Android. LibGDX. How to move and orient 3D-object

2019-09-11 01:35发布

I'm using LibGDX for my Android app. I need to move and orient 3D object(ModelInstance) along a spline.In my case it's CatmullRomSpline. I got the movement working but having problem with orienting the ModelInstance along the spline.

My Code:

public void update() {
    float t = SPEED * Gdx.graphics.getDeltaTime();
    elapsedTime = elapsedTime + SPEED *  Gdx.graphics.getDeltaTime();       

    //Movement
    catmull.valueAt(value, elapsedTime);
    myObject3d.transform.setTranslation(value);

    //Rotation
    derivative = catmull.derivativeAt(derivative, t);
    derivative = derivative.nor();

    //Tried to bring object into default position before rotating
    //Vector.X - is the default direction of my Object - facing right
    //myObject3d.transform.rotate(Vector3.X, Vector3.X);

    myObject3d.transform.rotate(derivative, Vector3.X);             
}

1条回答
劫难
2楼-- · 2019-09-11 02:12

The Matrix4#rotate method has two arguments, base and target. In your case the base vector should be Vector3.X, while the target is derivative. You need to swap the arguments for this. Also, the Matrix4#rotate method post-multiplies the rotation on top the existing rotation. Or in other words: this will accumulate the absolute rotation on every call. You probably want to use the Matrix4#setToRotation method instead, which resets the rotation on every call (clears the matrix).

myObject3d.transform.setToRotation(Vector3.X, derivative);
myObject3d.transform.setTranslation(value);

While this probably will work in most cases, you might get unexpected results depending on the path. Like said, there are infinite possible rotations that will result in this direction. Therefor it's better to use two additional vectors to specify the up (Y) and right (Z) vector.

right.set(Vector3.Y).crs(derivative).nor();
up.set(right).crs(derivative).nor();
myObject3d.transform.set(derivative, up, right, position).rotate(Vector3.X, 180);

Here the cross product is used to calculate the right and up vectors, where it is assumed that Vector3.Y is usually close to the up vector. Then the Matrix4#set method is used to set the matrix to reflect these values. The first argument specifies the "new" X-axis, the second the "new" Y-axis, the third the "new" Z-axis and the last argument specifies the translation (location).

Here's a working example: https://gist.github.com/xoppa/7558c0c75e9534795e9f

Although unrelated, keep in mind that path.valueAt method uses 0 <= t <= 1. Or in other words, t (elapsedTime in your code) should not be below 0 or above 1.

查看更多
登录 后发表回答