Bone hierarchies

Started by
8 comments, last by jtech 22 years, 4 months ago
How do you rotate a bone hierarchy based on its AABB center, and not by its root bone, which can be anywhere?
Advertisement
I would do it just as you would translate the model to another point in space, by translating the model so that the AABB center is at the origin, performing the rotations, then translating back to the original position.

Z.
______________"Evil is Loud"
Yes, that works for models with vertices, but I''m talking about
a bone hierarchy, where each bone has a position
and a rotation relative to its parent. I want to rotate the
entire hierarchy by 90 degrees, and simply swapping two
vector components for position and rotation does not work on
hierarchies.
You would have to calculate the center of the heirarchy by first finding the absolute positions of the bones (give the root bone an arbitrary position, then find the other positions using that), then finding the center point of all of the bone positions. Once you find that, do a I said in the previous post, translate to the origin, rotate, and translate back, then Using the difference of positions from the original root pos to the rotated position, re calculate the relative positions of the child bones.

Z.
______________"Evil is Loud"
But if I do that, then I lose all rotation information.

I don''t it is possible to transform a bone''s relative position
absolutely, then transform it back relatively without losing
its rotation.

At least I think so in thought.
The root bone is just a matrix that you have built from a compound rotation and translation.

You probably have your bone origin at the zero axis or translated up to be the hip or something.

To do what you are talking about, all you need to do is make a temp matrix that is a parent to your root. Use to translate the object so that the object is centered at the point you want to rotate. Then rotate it as you want to and then translate it back. That gives you what you want. But you have this extra parent matrix. So just multiply it by the original root bone matrix and that becomes the new root matrix. Voila...

I understand what you are saying, but I still can''t get it to work.

My root bone has a position and a rotation. The rotation is stored
as a rotation vector (rx,ry,rz). What I tried doing is creating a
rotation matrix from my rotation vector, multiply that with a 90
degree rotation matrix, and then get my rotation vector back using
a MatrixToEulerAngles function. It seems to work when the root
bone rotation is all zero, but when it has some rotation, it ends
up wrong.

Is it possible that I''m experiencing some kind of gimbal lock if
some of the rotation components of the root bone are 90 degrees
already and I''m trying to rotate the entire skeleton by 90 degrees?
The problem with MatrixToEuler functions is they don''t really work well. That may be the problem. For instance, what you are calling gimbal lock is the singularity that comes from using the Euler angles to create a matrix. For your limited case, however, it should work alright. You need to be certain that your Matrix->Euler routine returns the same order of rotations as you use to built the matrix. That is if you are transforming in XYZ order, your routine must also return XYZ order. I have often seen people use routines that return HPB order (YXZ) and it breaks things. For your case if you rotate it very much you could end up with Euler angles very different from what you started with but it should still be valid for the orientation you need. (IE 20,60,45 + 60,0,0 != 80,60,45 usually).

Assuming that is correct, what you want to do is build up the magic matrix that gets the character where you want it. Then convert it to Euler in the right order and it should be fine.

I find it usually helps to do the math out either on paper, in the program, or mathCad. Then make sure it is actually doing what I think it is. So take your Eulers and covert to a matrix. Then take the matrix you wish to rotate and translate it by and multiply them together. Then extract the Euler rotations and the translations and see if it works. I compare the program output with MathCad. I mean it''s math so we know that part works, it just is making sure your steps are correct and your program is doing it the right way.

-Jeff
I forgot to say that I always check the routines first to make sure they are correct. For example for your Matrix->Euler, pass in a bunch of test values to verify. Euler->Matrix->Euler. The Eulers should be the same since there are no compound rotations. If not, you have a bug in these routines.

I found my rotation bug. I was post-multiplying the 90 degree
rotation instead of pre-multiplying it with the root bone
rotation. I still think my first choice was correct, but
it''s working, and that''s good enough for me.

BTW, I''m using the EulerMatrix functions from Graphic Gems IV.
I''ve gotten good results from it so far.

Thanks for the help.

This topic is closed to new replies.

Advertisement