Archived

This topic is now archived and is closed to further replies.

max-space quaternions

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''ve written an animation system that uses quaternions exported from 3DSMax. The problem that I have is that since max''s space considers Z to be up, and my engine considers Y to be up, I effectively have two seperate types of quaternions running around in the engine: max-space quaternions and world-space quaternions. The two are seperate entities that can only be resolved when I convert them into matricies (max-space quats simply swap colums 1 & 2) -- which is fine for all my skinning code. However now that I''m doing some IK stuff, I need to be able to modify the rotations that are in max-space in my engine, which builds quats in world-space. Is there an easy way to convert from "world" quats to "max" quats? Hopefully that makes sense.

Share this post


Link to post
Share on other sites
You have 3 choices

1. Rotate the models in Max to they are oriented correctly for the engine. Z is "up" in Max only as the default -- there is no problem with Y being "up".
2. Rotate the models in the exporter.
3. Rotate the models after loading them into the engine but before using them.

Share this post


Link to post
Share on other sites
Hrm... I''m not sure if rotation is really what I''m after, I think it''s swizzling... I''ll give it a shot. I realized last night that I was going about this the hard way. The easy way ought to be to take a quat, convert it to eulers and then spit the swizzled eulers out as a quat again. So, to test the code out I just convert it to euler and then convert it back to a quat. What is odd is that it works for nearly all quats, but there are a few where the resulting quat is orthaganol to the source. Here''s the algorithm:

key.fRotation.mConvertToEuler (x, y, z);
qx.mCreateRotation (1, 0, 0, x);
qy.mCreateRotation (0, 1, 0, y);
qz.mCreateRotation (0, 0, 1, z);
testQuat = qz * qy * qx;

Seems simple enough, yea? Any idea why I would get a rotation that is orthoganol (I test for this by dotting the key.fRotation and testQuat and get 0)?

Share this post


Link to post
Share on other sites
Yea, that doesn''t work. All of my rotation data is relative to the parent, not in absolute world space, as such rotating the character really only implies rotating the root bone of the character by 90 degrees, which leaves me where I started for all bones in the heirarchy below the root.

Maybe I''m going about this the wrong way. The problem arises from trying to write some IK solvers to apply on my character. I''m attempting to implement a simple CCD system: given the vectors to the affector and to the target, I build an orthoganol axis of rotation, and am able to find the angle of rotation (acos). However, since I do this in world-space, y is up and when I multiply my bone''s rotation by this new quat bad stuff happens as I am multiplying a z-up quat with a y-up quat (hopefully that makes sense). I tried simply swizzling the axis of rotation as well, but that didn''t work...

Share this post


Link to post
Share on other sites
So here''s a simple little solver that I''m trying to write: something that rotates the characters head towards a point.

bone = skeleton->mGetBone ("Head01");
targetVector = *fFocusPoint - bone->fFinalWorldPosition;
boneVector.mSet (1, 0, 0);
bone->fParent->fOutput.mTransform (boneVector);
boneVector.mSet (boneVector.x, boneVector.z, boneVector.y);
targetVector.mNormalize ();
boneVector.mNormalize ();
orthoAxis = targetVector.mCrossProduct (boneVector);
orthoAxis.mNormalize ();
q.mCreateRotation (orthoAxis.x, orthoAxis.z, orthoAxis.y, acos (boneVector.mDotProduct (targetVector)));
bone->fBaseOutput = q;

some clarrification:
it is assumed that <1, 0, 0> is the vector along a bone, ie all bones point in that direction. fBaseOutput is a quat that represents the incremental rotation with respect to the parent bone. I have to swizzle the output of boneVector to get from z-up space to y-up space. In my code all quats are built under teh assumption that z is up, so the final step of transforming a point (or skin) by a bone is to swizzle the y/z coords.

The code above should, as far as I can tell, build a quat that rotates the bone we''re interested in such that it points toward the point of interest (fFocusPoint).

The code isn''t working, and my only guess is because I''m doing claculations in y-up space, where all the rotation code in the animation engine uses max''s quats which are z-up. As far As I can tell, I''ve got all my bases covered. The only thing that concerns me is if I can really create a proper quat by simply swizzling the axis of rotation as I''m doing it...

Share this post


Link to post
Share on other sites