3D libgdx rotation

2019-08-09 17:16发布

I think this question is not a duplicate, or if it is, I couldn't understand how to make this work.

(sorry for my great drawing capabilities...) Rotation Schema

I have a ball, radius 0.5 (so, perimeter is 3.1415926). In each frame, I have it in oldPosition and I want to place it in position, so, move in the blue arrow direction, represented by the v vector in the drawing. This is easy.

The trick is that I want the ball to be rotated in the target position. The rotation axis should be perpendicular to the direction (green dashed line), and rotation should be performed in relation to the object center (rotation will be 2x the length of the translation).

My libgdx code at the moment looks like:

// During object initialization I have a Matrix4 with identify
Matrix4 rotation = new Matrix4();


// Now, this code during render()
Vector3 movement = position.sub(oldPosition);
float length = movement.len();

// drawing this on paper, it seems a correct way to compute orthogonal vector
rotation.rotateRad(new Vector3(-movement.z, 0f, movement.x), 2*length);

iSphere.transform = rotation.cpy().trn(position);

So, basically, I start with the identify Matrix4. In each frame I apply a rotation to it, apply that rotation in the sphere, and translate it.

This seems to work at first (?), but after a lot of rotations, ball starts rotating in the wrong direction.

I tried an implementation with Quaternions but did not have luck as well. It should be something simple that I am forgetting.

1条回答
Juvenile、少年°
2楼-- · 2019-08-09 17:45

Like @Springrbua said you could take the cross product to get the axis to rotate around. For example (untested code):

public void update(float delta) {
    velocity.add(tmpV.set(acceleration).scl(delta));
    position.add(tmpV.set(velocity).scl(delta));
    final float speed = velocity.len();
    final float angle = speed*delta*MathUtils.radiansToDegrees;
    Vector3 axis = tmpV.set(velocity).scl(-1f/speed).crs(Vector3.Y);
    tmpQ.set(axis, angle);
    rotation.mulLeft(tmpQ);
    transform.set(position, rotation);
}

Here's the full source of a working example: https://gist.github.com/xoppa/3b841fb52f46e8cdec24

查看更多
登录 后发表回答