Jump to content
  • Advertisement
Sign in to follow this  
Jiia

Transformation Matrix

This topic is 5026 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 think all of the SkinMesh experts have accended to some other plane of existence. I'm gonna keep this question very simple, in hopes of getting at least one reply. You know the TID_D3DRMFrameTransformMatrix type templates that always follow a TID_D3DRMFrame in the X-File format? What the hell are these for? If I read in the transform matrix following each bone in the X-File, what happens if I apply those matrices to my bones and render it? Will the model be in it's pose that existed in the X File? If not, what do I need to do to these matrices to make them put the model in it's default pose? Please ignore the rest of this if you can answer that question. All of my animation matrices are screwed up. In your standard walk-animation, the model's thighs are bent so that the feet are kicking it in the head. The transform matrices included after each bone give me the same results when applied DIRECTLY to the mesh hierarchy. Please tell me if I'm doing something wrong here.
#1- Set all bone states (I set these DIRECTLY from the file)
#2- For each bone in hierarchy..
     #2a- Set Final-Matrix of this bone to Offset-Matrix
     #2b- Multiply that with the state of the bone (from #1)
     #2c- Multiply that with the Inverse-Offset-Matrix (inversed #2a)
     #2d- Multiply that with our parent's Final Matrix (see #2e)
     #2e- Pass our Final Matrix to each child bone
#3- Throw Final Matrices into the shader and render
Here is the hierarchy part in real code..
VOID CBone::ComputeHierarchy(MATRIX *States, MATRIX *Finals, MATRIX &Derive) // Cycles the states through the heirarchy
{
    Finals[Index] = Offset * States[Index] * InverseOffset * Derive;

    // Compute Children
    CBone *b = FirstChildBone;
    while(b)
    {
        b->ComputeHierarchy(States,Finals,Finals[Index]);
        b = b->Next;
    }
}


See any problems with this? Because it doesn't work. The only problem I can see is the matrices in animations of the X file. Any help is appreciated. [disturbed] [Edited by - Jiia on September 13, 2004 6:44:59 PM]

Share this post


Link to post
Share on other sites
Advertisement
I cannot see how you exit the while loop; once in, the recursion will never exit because the b is always initialized with FirstChildBone so if b!=NULL it will never exit.

Share this post


Link to post
Share on other sites
FirstChildBone is the first node in a linked list of child bones for each bone. But I know my problem is not within the hierarchy. I can simply pass identity matrices through the hierarchy until I reach the left thigh, compute it, and it's still kicking the head.

EDIT: See what the animated model looks like here.

Share this post


Link to post
Share on other sites
the frame transform matrices have the local object coordinates. Typically the root node is an identity matrix and the children indicate offsets to their parent. I think you do process the frame info in your bones states as you said. So the problem I believe is with the matrix transforms before rendering somewhere. Can you post the code of the matrix operations you do from the .x file frames before rendering? I am not clear which one is the offset-matrix, parent final matrix etc and also the matrix order in the multiply operations.

Share this post


Link to post
Share on other sites
Well, there is no code. I'm trying to use the matrices from the animation keys directly. I set those as the state. Then I pass it through the hierarchy, which applies the offsets and such. If there is any code that would modify the animation matrix keys before ever using them, then that is what I NEED, badly.

The CBone::Offset matrix is what I got from ID3DXSkinInfo::GetBoneOffsetMatrix(). The CBone::InverseOffset matrix is just the inverted version of the CBone::Offset matrix.

The matrix multiplies go from left to right. Like this:

Finals[Index] = Offset;
Finals[Index] *= States[Index];
Finals[Index] *= InverseOffset;
Finals[Index] *= Derive;



The parent final matrix is exactly what is computed above. It is passed to each child as "Derive" parameter.

Also note that I am not using the AnimationController provided with D3DX. I'm assuming it is doing exactly what I need to do, which is probably why very few people know the answer to this.

With my current code, if I set each bone state to identity, I get a perfect default pose. If I rotate a bone's state manually, it does exactly what it should. If I rotate the shoulder, the forearm and hand behave perfectly. If I set any bone state to a matrix from an animation key, it goes whacky. The animation keys are plain screwed up. I'm assuming there must be a way to modify them to make them relative to the identity matrix. In other words. States[LeftThighIndex] = Animation.Keys[0]; makes the left leg kick the head, when it should be barely rotated, as in the animation while in the modeler. It's not just with my mesh, though. Tiny does the same thing.

Share this post


Link to post
Share on other sites
Ok I see. I was looking the skinnedmesh demo in the SDK (uses the animation controller as you said to derive the paths) but the updateframematrices function in it takes into account frame siblings not just the children in a separate operation so the parent matrix is multiplied with the current for each sibling.

Also you do an inverse on the offset while you already multiplied the offset itself (before states why?).

Share this post


Link to post
Share on other sites
I'm not sure what you mean about siblings. The sibling of the left shoulder would be the right shoulder. Why would the left shoulder have any affect on the right, or vice versa?

Each child bone computes all of it's children. That means the hip computes both the left thigh, and the right thigh. The entire left leg would be computed, then the entire right leg. If I computed siblings as you mention, it would mean the left and right thigh are computed, then the left and right shins. So in a different order. But the result should be the same, right? The parent of each bone remains the same, and the bone's only use their parent as a guid to modify their own orientation. Let me know if I'm missing out on something.

Quote:
Also you do an inverse on the offset while you already multiplied the offset itself (before states why?).

The "Offset" matrix that I get from ID3DXSkinInfo::GetBoneOffsetMatrix() tells each bone how to move itself so that it's rotational origin is 0,0,0 in 3D space. So the Offset matrix for the hand moves the wrist joint to the 0,0,0 point. The state of each bone is supposed to (as far as I know) tell the bone how to rotate. If I tried to rotate a bone before moving it to the center point, it would rotate around the model's origin rather than it's own origin.

So Final = Offset * State would move the bone to the origin, then rotate it, but then it remains at the origin. If I render after this, the hand would appear stretched from the forearm to the center point of the model. It would be rotated correctly, however. The InverseOffset matrix moves the hand's wrist back to where it was before. So it is put back onto the forearm. So ToCenterPoint,Rotate,BackToLocation. I guess the Animation Controller also takes care of these things?

Again, let me know if I'm totolly blotching something.

Share this post


Link to post
Share on other sites
I may not be too helpful here, as I am using DX8 and created my own skeleton and skinned mesh objects.
But in my experience, the offset matrices should not be taken into account until you are building your mesh object (ie. applying the transformations).
All of the bone (or frame as .x files call them) matrix transformations are in BONE-local space. From what I have played with, I have discovered that the offset matrices seem to apply these bone matrices into MODEL space.
So when animating :
1) Set your bones with the .x file BONE local transformation matrices.
2) Traverse your skeleton hierachy, multiplying children by the parent matrices.
3) Extract these multiplied-through matrices in the order which they came in the .x file (the bone name buffer from D3DXLoadSkinMeshFromXof) to build up your final array of matrices to apply to the skinned mesh.
I use something like :

D3DXMatrixMultiply(&(amtxBones[dwCurBone]), // output
mtxOff, // offset matrix
mtxCur); // multiplied through bone matrix


and plug that into

smSkin->UpdateSkinnedMesh(amtxBones, NULL, mshPose);


Hope this helps you out - even if it is based on DX8.
Steele.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!