【问题标题】:Translate model over time like actor?像演员一样随着时间的推移翻译模型?
【发布时间】:2015-03-03 08:31:00
【问题描述】:

我最近开始学习 LibGDX,并且喜欢 Actor 系统在移动/淡入淡出/旋转方面的简单性。很简单!但是,进入 3d 时,我想知道是否有类似的实现方式。

我见过有人说“instance.transform(x,y,z)”,但它会立即应用并显示在下一次渲染中。我想知道是否可以使用一些内置框架 ala "model.addAction(moveTo(x,y,z), duration(0.4f));" 插入该转换我知道 Model 不会像 scene2d 中的大多数元素那样从 Actor 继承。当谈到所述模型的骨骼动画和导入动画时,我了解当前的动画框架,但我正在寻找一种解决方案来在我的游戏世界中移动我的模型,而不必在渲染中执行大量相关逻辑.

有没有一种方法可以在模型上使用 Action 框架,而不是使用自定义插值实现来弄乱我的渲染循环?只是平移、旋转等。(如果没有,我可能会在模型对象上实现动作、池等。)

谢谢!

【问题讨论】:

    标签: animation 3d libgdx


    【解决方案1】:

    一个快速而肮脏的技巧是在侧面使用scene2d的动作系统。创建一个没有演员的舞台。您可以将您的动作直接发送到舞台并每帧调用一次stage.update(delta); 来处理您的所有动作。你不需要绘制舞台来做到这一点。 (不过,在未来,您可能还是想要一个展示 2D UI 内容的舞台。)

    您需要创建自己的操作。由于舞台不适合 3D,因此没有理由尝试使用 Actor。您的 Actions 可以直接应用于舞台进行处理,并且设计为不针对任何 Actor。

    这是一个示例(未经测试)。由于您主要关心的是随着时间的推移混合内容,因此您可能会从 TemporalAction 扩展大部分 Action。

    public class MoveVector3ToAction extends TemporalAction {
    
        private Vector3 target;
        private float startX, startY, startZ, endX, endY, endZ;
    
        protected void begin(){
            startX = target.x;
            startY = target.y;
            startZ = target.z;
        }
    
        protected void update (float percent) {
            target.set(startX + (endX - startX) * percent, startY + (endY - startY) * percent, startZ + (endZ - startZ) * percent);
        }
    
        public void reset(){
            super.reset();
            target = null; //must clear reference for pooling purposes
        }
    
        public void setTarget(Vector3 target){
            this.target = target;
        }
    
        public void setPosition(float x, float y, float z){
            endX = x;
            endY = y;
            endZ = z;
        }
    }
    

    您可以创建一个类似于 Actions 类的便利类,以便轻松设置使用自动池生成您的操作:

    public class MyActions {
    
        public static MoveVector3ToAction moveVector3To (Vector3 target, float x, float y, float z, float duration){
            return moveVector3To(target, x, y, z, duration, null);
        }
    
        public static MoveVector3ToAction moveVector3To (Vector3 target, float x, float y, float z, float duration, Interpolation interpolation){
            MoveVector3ToAction action = Actions.action(MoveVector3ToAction.class);
            action.setTarget(target);
            action.setPosition(x, y, z);
            action.setDuration(duration);
            action.setInterpolation(interpolation);
            return action;
        }
    
    }
    

    示例用法。 ModelInstance 移动起来有点棘手,因为您必须使用它们的 Matrix4 变换来完成它,但是您不能安全地返回位置或旋转或缩放变换。所以你需要保留一个单独的 Vector3 位置和四元数旋转,并在每一帧上应用它们来更新实例的变换。

    //Static import MyActions to avoid needing to type "MyActions" over and over.
    import static com.mydomain.mygame.MyActions.*;
    
    //To move some ModelInstance
    stage.addAction(moveVector3To(myInstancePosition, 10, 10, 10, 1f, Interpolation.pow2));
    
    //In render():
    stage.update(delta);
    myInstance.transform.set(myInstancePosition, myInstanceRotation);
    

    【讨论】:

    • 会试一试并报告。谢谢!
    • 我已经能够通过扩展 TemporalAction 来实现我所需要的。谢谢!当我编写更多函数时,我会在我的 Action3d 类中发布一个小的 Github。也许它会帮助其他人。我想让你看看它并告诉我你是否认为如此厚颜无耻地操纵矩阵存在下游问题(或者如果使用更复杂的形状——我只是在使用一个立方体)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 2011-10-15
    • 1970-01-01
    相关资源
    最近更新 更多