1
votes

I have a Three.js web application with a single model. I use the mouse to rotate the model. This is done by recording the amount of X/Y movement over time between mouse down and mouse up events and using the delta X/Y values to rotate the model around the desired axis, (X Y or Z). I do not change the camera perspective or orientation.

For mouse Y movement, I rotate the model around the X axis, rotating in the YZ plane. When the model is in it's original state with a quaternion value of (0, 0, 0 1), this works great since I want the top of the model to rotate away from the camera (me) when I move the mouse up and towards the camera when I move the mouse down.

However, I of course lose this movement perspective after the model is rotated. For example, if I rotate the model a full 180 degrees around the Y-axis (flip it horizontally), the perceived motion inverts. Moving the mouse up moves the model towards the camera and moving it down moves the model away from the camera.

My question is, how can I adjust the rotation operations to maintain the desired perceived movement, regardless of the change in the model's quaternion value due to movement? That is, what steps/operations do I need to take to compensate for the model's current orientation given its current quaternion, so I get the same perceived movement of the model when moving the mouse?

I use the code below to rotate the model, where object is the model, axis is the desired axis (pure X, Y, or Z), and radians is the desired angle of rotation:

function rotateAroundObjectAxis(object, axis, radians)
{
    var rotObjectMatrix = new THREE.Matrix4();
    rotObjectMatrix.makeRotationAxis(axis.normalize(), radians);

    object.matrix.multiply(rotObjectMatrix);

    object.rotation.setFromRotationMatrix(object.matrix);
}
1

1 Answers

2
votes

You want the rotation from the point of view of the rotated object so you need to left-multiply the rotation.

So if the final MVP matrix is from perspective*view*model then you need to insert the rotation between the model and view matrices.

function rotateAroundObjectAxis(object, axis, radians)
{
    var rotObjectMatrix = new THREE.Matrix4();
    rotObjectMatrix.makeRotationAxis(axis.normalize(), radians);

    rotObjectMatrix.multiply(object.matrix);

    object.matrix = rotObjectMatrix;

    object.rotation.setFromRotationMatrix(object.matrix);
}