• 15
• 15
• 11
• 9
• 10

# Update Quaternion Slowly

This topic is 1938 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Okay, guys I know I'm asking alot of questions, but I have alot alot of work to do to finish the 3D Game Engine I'm working on.

I have a RigidBody, I can rotate it by supplying a new Quaternion value, but here is the problem:

I want to rotate it SLOWLY, something like the following:
 // We might need to call this method 500 times from rendering to make the RigidBody rotation is equal to FinalQuaternion void RotateSlowly(btQuaternion FinalQuaternion) { btMatrix3x3 orn = body->getWorldTransform().getBasis(); // Code here to change 'orn' according to FinalQuaternion to keep rotating with certain speed until orn rotation is EQUAL to FinalQuaternion body->getWorldTransform().setBasis(orn); } 

How can I do that?

##### Share on other sites
You can compute the quaternion that would turn orn into FinalQuaternion, with a division. If you want to limit the angle, you force the real part of the quaternion to be at least cos(max_angle/2) and rescale the imaginary part of the quaternion to make it unit-length. I posted some code to do that here.

##### Share on other sites
@Álvaro: I'm not sure exactly how to implement that to use it with Bullet, I thought about converting the quaternion to euler and supplying the updated value to setYPR but I don't know how should I do it with frame independent, same like the following example:
x += speed * elapsedTime; // Frame independent

##### Share on other sites
What part of what I describe don't you understand? The code I provided uses Boost quaternions, but if you understand what it does, you should be able to write the code to work with any quaternion implementation.

##### Share on other sites
Some parts I don't understand like:
q.real();
q.unreal();

I'm dealing with btQuaternion which doesn't have those methods, I would prefer using Euler but having a little problem with as I mentioned above.

##### Share on other sites
q.real() returns the real part of q (duh ;) ). So if q = w + xi + yj + zk, q.real() returns w.
q.unreal() returns a quaternion where the real part has been zeroed out. So if q = w + xi + yj + zk, q.unreal() returns 0 + xi + yj + zk.

In any case, the procedure is this:

• Start with q = w + xi + yj + zk
• If w is negative, flip the sign of all four components
• if w is less than cos(alpha/2), set w to cos(alpha/2) and rescale the vector (x,y,z) so that w^2 + x^2 + y^2 + z^2 = 1.

The last part is the trickiest. You have to multiply x, y and z by a constant factor that is computed as sqrt((1-w^2)/(x^2+y^2+z^2)).

Is that clear?

##### Share on other sites
@Álvaro: I found out that I can do that easily by using quaternion slerp to animate the rotation, how can I know that the rotation is completed when using btQuaternion::slerp?

##### Share on other sites

@Álvaro: I found out that I can do that easily by using quaternion slerp to animate the rotation, how can I know that the rotation is completed when using btQuaternion::slerp?

Well, the rotation is completed when you pass a 1 to slerp. How exactly are you calling it?

##### Share on other sites
I want to know when the rotation animation is completed, here is what I'm doing:
 // This method should return true when the rotation is completed, otherwise, return false bool lookAt(float x, float y, float z, float elapsedTime) { btQuaternion FinalQuat = GetLookAtRotation(x, y, z); btQuaternion currentQuat; orn.getRotation(currentQuat); float speed = 0.001f; // Instead of just setting FinalQuat to the rigidbody, I want to animate it btQuaternion newQuat = currentQuat.slerp(FinalQuat, elapsedTime * speed); if (???) // If slerp() have done animating the rotation { return true; // Animation completed } else { return false; } }  Edited by Medo3337