# How to rotate child objects in 3D

• 03-30-2008
Arianiv
How to rotate child objects in 3D
Hi,
I was wondering if anyone had a good strategy for rotating child objects in 3D independently of a parent object.

For example, a car with wheels that can turn on their own axis, at the same time as following the rotation of the car itself as it goes around a turn.

I have gotten this to work to some extent by having child 3D objects inherit a parent axis if they are doing a non-self rotation (i.e. around some other center of mass).

Each 3D object has a "bind" point for its own rotation (could be the center or a hinge) – as well as a "origin" point. When I rotate any object, all child objects are instructed to rotate around an "origin" that is the same as the parent's "bind" point. In addition, child objects are handed the parent axis (since they may have already been rotated in their own frame).

So it works, but all hell breaks loose if I twist about the parent body in too many directions. I thought it was gimbal lock, and I ripped out the 3D matrix I was using and replaced with a 4D matrix and quaternions - same problem, almost exactly. I think Quaternions smoothed out some of the main-body rotation.

I'm wondering - what information do these child objects need in order to do the same relative motions in all frames?

any suggestions?
• 03-30-2008
VirtualAce
You can either create a mesh hierarchy and render the hierarchy or render the objects using different transforms.

To render the wheels you would do use the inverse world matrix of the object and then a transform to both rotate the wheels and then translate the wheels to their correct location. The inverse world essentially will 'un-do' the world transform on the object. This means translations/rotations are now relative to the center of the object.

Bob and others would be more adept at getting this working but I think I'm on the right track.
• 03-30-2008
Drac
Yeah, Bubba's pretty much got it. DirectX has a MatrixStack class made especially for this, even if you aren't using DX I would check out the documentation for that. It doesn't really tell you about the inverse part of it. Pretty much to get the matrix you want you're going to have to take the inverse of whatever matrix is at the top of the stack. You should probably understand how it all works so reading up on matrix's in general should help.
• 03-31-2008
Arianiv
inverse matrix
Thanks guys - would not have thought of using the inverse.

Btw, I'm actually using Actionscript 3, not C, but the core code is basically the same for these items, just that I had to write all of it from scratch :)

However, I am failing to understand when I would want to perform and undo a transform using the inverse.

When I do rotations I have a floating origin point and an arbitrary axis. For simplicity the axis is either going to be the X,Y,or Z axis of a given coordinate system. Those are easy to define axes.

The origin point is basically where the X,Y,Z converge. So, the origin is like the center of the earth, and the moon is rotating around the earth's Y axis using that origin as a reference point.

Now when I move the earth - anywhere, or rotate it any way - I basically inform the moon "here is your new parent origin, new parent Y axis".

So in this scenario where would the inverse matrix apply? I am already doing a translate/rotate/translate-back procedure, in order to use the arbitrary origin. So I think this has the same effect as using the inverse...

I guess my gut is telling me that having each object store a 3-vector frame of reference (X,Y,Z) might be overcomplicating things. But I'm not sure... basically my object3D class stores a X = (1,0,0), Y=(0,1,0), Z=(0,0,1) set of basis vectors.

When I tell the object "rotate around Y 15&#176;" - I also make sure to update the X,Y,Z axis-vectors as well via a matrix rotation. Basically this makes it so an object always has a "front", "back" etc, which is useful when I write higher level animation code, and it lets me write scripted animations using an assumed orientation.

Also child objects can perform either self-rotations, or parent-rotations.

Does my approach have an obvious mathematical flaw? Because basically, through drawing test axis vectors and debugging, I am seeing that my otherwise-perfect rotational matrices are failing to adjust the X,Y,Z axis unit vectors correctly if I perform rotations around 2 or more axes. I seem to get the same exact problem using vectors or quaternions.

Turning the character to face left (-90 degree rotation around Y), for example, properly updates my character's "Z" axis to "-1,0,0", so the basic concept works. I was wondering if for some reason I need to use quaternions for these axes.. or if I am just missing something obvious.

THANKS
• 03-31-2008
VirtualAce
Quote:

Does my approach have an obvious mathematical flaw?
Yeah. Gimbal lock.
• 04-01-2008
Arianiv
Haha - yeah - but why?

Aren't quaternions supposed to help me get rid of Gimbal lock? I am using a 4D matrix and quaternion representation.

Do I just need to keep the object coordinate system intact on all objects? Thats fine if so, it just makes for a little less clean code if I there's no good way to store an orientation offset. It is a nice stateful quanta to have.. but even using quaternions it would just be 3 quaternions with a W that got updated.

In essence, using 3 values to store the state of a rotation, which is no different than using 3 degree offsets, which is like a 3d-vector which gets gimbal lock. Is that the problem..?

Ideally I wanted to use that type of model to build a "spine".. but maybe there is another way to do it.
• 04-01-2008
Arianiv
I found a useful thread on the topic

"Quaternions and skeletal animation"

looks like at least the origin/binding portion I had right. Seems like plenty of others have run into these issues. After some fiddling my root quaternion rotations are more correct, sub rotations are completely broken :) And oh, now a pivot around the Y axis induces a 180 flip every other frame. Awesome!
• 04-02-2008
VirtualAce
You said you were going to use quaternions not that you were. With quaternions you won't have gimbal lock.
• 04-02-2008
DavidP
All you need to do is translate the wheel to the origin, rotate it about the origin, and then translate it back to its original position. Done. :)
• 04-02-2008
VirtualAce
Quote:

...All you need to do is translate the wheel to the origin,
Which is the inverse world matrix of the object.

Quote:

... and then translate it back to its original position.
Which then places it back into world space.
• 04-02-2008
Arianiv
Quote:

Originally Posted by DavidP
All you need to do is translate the wheel to the origin, rotate it about the origin, and then translate it back to its original position. Done. :)

Yeah, this is exactly what I have been doing since my first version, and works perfectly. The issues have mainly been about frames of reference.

For this translation-rotation-translation, I have not been using the inverse world matrix, just a simple XYZ vertex translation, run the vertices through the object's rotation matrix and translate back.

The best example I have found so far does, like Bubba mentioned, incorporate a multiplication by the inverse world matrix to the current rotation that is used to set up the matrix. Instead of storing a given set of axis vectors, it appears the solution is storing a total & local quaternion, and making sure child objects take into account the parent quaternion. Its still a bit of doing to work out the order of things, but I'm getting there. I will be happy when I can focus on animating and rendering with this part complete!
• 04-03-2008
BobMcGee123
You really need to post code. Be careful when multiplying quaternions, you cannot reverse the order of multiplication and get the same results.