Question

I am trying to achieve the same rotational effect like Maya in my project. I have some knowledge on quaternions and the trackball example.

Unfortunately I am still unable to wrap my head around the concept of using the quaternions to get the desired effect.

Basically I am still getting the same issue I had before with the 3d trackball. After flipping the object upside down, and then trying to rotate to the right, the object will rotate to the left. Well actually its my camera rotating around the focus point in the opposite direction.

The problem is that I am using the screen coordinates & trackball to get the old / new vectors and getting the angle of rotation from those two vectors. I will always get the wrong axis of rotation this way.

How should I go about solving this issue?

Was it helpful?

Solution

I don't know Maya so I can only guess that its rotation is like this: if you rotate left-right, it feels natural. Then if you rotate the object up-down 180 degrees, then rotate left-right again, it still feels natural.

If you are familiar with the concept of using a matrix to do transformations (like rotate, scale and translate), well a quaternion is just the same concept but it only allows rotations, so you might want to use it to constrain your transforms to just rotations. In practice, you can use either a matrix or a quaternion to do the same thing.

What you need to do is remember the current quaternion state for the object, then when the next frame of rotation occurs, multiply the new rotation with the old quaternion (in that order) to give you the next frame's quaternion. That will ensure that no matter what orientation the object is in, the next frame's rotation will be applied from the viewer's viewpoint. This is as opposed to some naive rotation where you just say "user is scrolling up/down, therefore alter the object's X-axis rotation", which causes that flipping.

Remember, like matrices, quaternions need to be multiplied in reverse order that the actions are actually applied, which is why I said to multiply the new operation by the existing quaternion.

To finish with an example. Let's say the user is going to perform 2 actions:

  • On frame 1, the user rotates the object 180 degrees about the X axis (up/down rotation).
  • On frame 2, the user rotates the object 90 degrees about the Y axis (left/right rotation).

Lets say the object has a quaternion Q. Every frame, you will reset the object to its default coordinates and apply the quaternion Q to rotate it. Now you might initialise it with the identity quaternion, but let's just say the initial quaternion is called Q0.

  • On frame 1, create a new quaternion R1 which is a "rotate 180 degrees about the X axis" quaternion (you can find some maths to compute such a quaternion). Pre-multiply the new operation by the existing quaternion: Q1 = R1 * Q0.
  • On frame 2, create a new quaternion R2 which is a "rotate 90 degrees about the Y axis" quaternion. Pre-multiply the new operation by the existing quaternion: Q2 = R2 * Q1.

On frame 1 you will use Q1 to display the object, and on frame 2 you will use Q2. You can simply keep applying any subsequent user actions to the quaternion and it will always be rotated in the viewer's frame of reference.

OTHER TIPS

I think you have problems with changing coordinate system.

Suppose, you want to rotate object in X Axis, then in Y Axis, and then move it and scale. So, you should multiply your transformation maxtrix (at the beginning it equals to itentity matrix) to the rotation matrix (firstly to X, then to Y), then to translation matrix and at the end to scaling matrix. So, when your current matrix multiplies to the resulting matrix, your coordinate systems changes.

To avoid this problem you can use 2 methods:

1) to accumulate your resultig matrix as product of all previous matrices.

2) to use stack, where in the top will be the matrix, which equals to product of all matrices in the bottom of this matrix (in the stack).

P.S. I'm not sure, that it helps you. I never used quaternions in my projects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top