RE: [Algorithms] Quaternion animation strategy
Brought to you by:
vexxed72
From: Robert D. <bli...@go...> - 2006-03-29 09:57:00
|
Not sure how you came to that conclusion, we stored less data this way as we didn't have to store any hierarchy data. Regards Robert _____ From: gda...@li... [mailto:gda...@li...] On Behalf Of Mark Wayland Sent: 29 March 2006 10:50 To: gda...@li... Subject: Re: [Algorithms] Quaternion animation strategy A good idea considering that any errors in interpolation of the parent bone(s) would not be propagated down the hierarchy, but means storing a bit more data... I guess nothing's free? ;-) Cheers, Mark ----- Original Message ----- From: Robert <mailto:bli...@go...> Dibley To: gda...@li... Sent: Friday, March 24, 2006 6:59 PM Subject: RE: [Algorithms] Quaternion animation strategy Just to suggest an alternative idea . since you have to store the quaternion and offset for each bone anyway, I once worked on a game where we changed our animation system to store all these values relative to the base pose. This has the advantage that you don't have to keep loading up different parent bones to apply to your next child when propagating. Oh, and you don't need to know the parent relationship. However it does have the disadvantage that you really have to use the animation as an absolute . trying to mess with bit of it when you don't have the parent-relative values can be tricky in some cases. So, it worked well for us, but YMMV. Regards Robert _____ From: gda...@li... [mailto:gda...@li...] On Behalf Of Matt J Sent: 23 March 2006 23:54 To: gda...@li... Subject: Re: [Algorithms] Quaternion animation strategy Hi James, I'll take another look at the export format, MDX, the guys who wrote these (unofficial) docs aren't mathematicians, but thanks to your clear response I think I can figure out for sure how it is done. Thanks a lot for the response. It was very helpful, it seems that you still use matrices for the final form and still use the concept of local transformations (i.e., in OpenGL you can think of a group of successive affine transformations as occuring on a local coordinate axis frame that "moves" around per joint, which is useful in this sense) and you use quaternions just as a means of storage and interpolation between different frames. One final question, I understand simply storing all the bones in the array, but in order to render a bone, it has to be aware of its parent bone's relative effect on the transformation, correct? It would seem you would still want to use the concept of a tree structure but your just storing the bones in an array and say, using an index/handle instead of a pointer to reference it? Or, is there another technique you use, say, like, propogating affine transformations made from one bone to the children of that bone? Thanks for the tips! Matthew > 1. Are the quaternions stored as the joints of the bones, or are they > used simply to interpolate two rotation matrices? In other words, is it > perfectly acceptable or usually practiced to store the quaternions > directly in the tree-based bone data structure? We store a position vector and orientation quaternion for each bone in the skeleton. We build transform matrices from these as a final step once we go to skin the associated mesh. You may also find it advantageous to not store the bones in a strict tree structure; we simply keep an array of bones, where each bone may or may not be parented to another bone. This allows for more flexibility in rig construction and doesn't require a single "root" bone, and as a bonus has better cache performance. You would still have to traverse it as a tree structure, correct? Even if your rendering a bone, the rotation has to be in the context of the parent bones. > 2. How are these quaternions calculated? Do you find the cross product > of the vector formed by the two bones, and then build > it based on that vector and the angle of rotation?, using the form q = < > cos (theta / 2) , A sin(theta / 2) > where A is the axis of rotation. Your conversion from axis/angle to quaternion is correct but I'm not sure why you need to calculate the quaternion. We export the orientation as a quaternion directly from our art package. Right. This makes sense, the package would have a series of quaternions, and you just interpolate between them. I'll double check, I believe this is the format that MDX uses, although the (unofficial) docs aren't clear about this. > 3. So, suppose we are in model space, and every joint is a new rotation > based off of the previous joint. Is point P found by q_bone1 * q_bone2 * > P * q_bone1_conjugate * q_bone2_congjugate? Is that the equivalent of > applying two rotation matrices? It would seem like we do not worry about > using the concept of a local matrix anymore, but instead directly > transform the model points using quaternions and render them in model > space. Is this correct? If this is correct, it would seem we would also > need to keep track of the translations between bones. That seems simple > enough, it would seem before performing the quaternion rotation, you > would shift it so the bone starts at the origin of model space, do the > rotation, and shift it back. I think you are overcomplicating things. To skin the mesh we calculate transform matrices for all the bones in the skeleton (using the position and orientation) and use the standard skinning method (bone offset method I think it's called). Each vertex is transformed by the appropriately weighted skinning transform, which is the bone inverse reference transform (the bone's transform in the reference/bind pose exported from the art package) multiplied by the current bone transform. You can directly transfom a point by a quaternion but doing any more than one point will be slower than just converting the quaternion to a rotation matrix and transforming by the matrix. |