Sign in to follow this  
Quaid Tseng

Problems about GetBoneOffsetMatrix()

Recommended Posts

What does boneoffset mean? I had read Mr.Adams' Adv Anim in dx but not very clear. In the book it says : boneoffset is to orient the vertices around the mesh's origin. So I think boneoffset is just "the inverse of combined TransMat of the frame" Below are my codes:
for (DWORD i = 0; i < pMesh->pSkinInfo->GetNumBones(); i++)
{
    const char *BoneName = pMesh->pSkinInfo->GetBoneName(i);			
    D3DXFRAME_EX *pFrame = RootFrame->FindFrame(BoneName);
    if(pFrame)
    {
        pMesh->ppFrameMatrices[i] = &pFrame->matCombined;
    }
    else pMesh->ppFrameMatrices[i] = NULL;
}

RootFrame->updateHierrarchy();

for (i = 0; i < pMesh->pSkinInfo->GetNumBones(); i++)
{
D3DXMATRIX boneoffset;
D3DXMATRIX matbone = *pMesh->ppFrameMatrices[i];
D3DXMatrixInverse(&boneoffset, NULL, &matbone);
pBoneOffsetMatrix[i] = boneoffset;
}

But this code failed , using D3DXMatrixInverse(&boneoffset, NULL, &matbone) to replace the API *pMesh->pSkinInfo->GetOffsetMatrix() will get a wrong result. So I must use GetOffsetMatrix() to successfully load Tiny.x But GetOffsetMatrix()/UpdateSkinnedMesh() failed when I loading the .x exported from Maya. What I hope to know is , how can GetOffsetMatrix() retrieve the offset in SkinInfo? Or how can I hand-calculate the offset from a .x file? Any ideas? Thank you!

Share this post


Link to post
Share on other sites
Yup, I had the exact same problem with Tiny_4anim.x. I found many things in this .x file that challanged my whole design for loading and creating skinned meshes. For one thing, I found that the offset matrices in that file are not necessarily the inverse of the too-root (combination) matrix. So, I gave up trying to compute the offset myself from a loaded .x file, and just use the pSkinInfo->GetOffsetMatrix to put them into another field in my custom D3DXFRAME structure. Trying to compute the offset proved futile, since the offset matrices (stored with the skin data in the .x file) and the TransformatMatrix (stored with the frame data) are not just simple translation matrices, but are some combination of scale, rotate, and transformation, though not in that order. Using the D3DXMatrixDecompose function proved futile as well.

I also found that there are 48 bones, and only 35 of them influence vertices directly. But the others are part of the hierarchy and are important for computing the to-root matrices.

I draw a small sphere for each bone using the inverse of the offset matrix as the world transform for each bone, when I am rendering Tiny without the skinning. When rendering Tiny with the bone influences, I just use the to-root matrix to position the spheres.

But, the offset matrix is supposed to transform the vertices that are connected to that bone to the origin, and the TransformationMatrix is used to scale, rotate, and translate the bone into its current pose. You will also notice that whoever created Tiny, did not just skin the mesh in its default pose. The frame hierarchy repositions and rotates the mesh from its default pose.

Whe I build and skin a mesh myself, the offset and initial TransformationMatrix matrices have only a translation component and are just the inverse of each other.


If you cannot use the GetOffsetMatrix for .x files created in Maya, then either you are doing something wrong in your AllocateHierarchy functions, or the .x file is not being created with the skinning info. What happens when you try to do the ConvertToIndexBlendedMesh?

[Edited by - DXnut on March 11, 2006 11:21:12 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by DXnut
If you cannot use the GetOffsetMatrix for .x files created in Maya, then either you are doing something wrong in your AllocateHierarchy functions, or the .x file is not being created with the skinning info. What happens when you try to do the ConvertToIndexBlendedMesh?


Now I print out the boneoffset matrices, the matrices obtained from GetBoneOffsetMatrix() and inverse of matCombined
do not match exactly, but very very close..(with difference smaller than 0.001)
So to inverse the TranMatCombined as offset is correct too.

My errors occurred at UpdateSkinnedMesh, not due to boneoffset.
I guess it's the problem of SkinInfo's FVF.

My .x from Maya has DeclData:

DeclData {
2;
2;0;6;0;,
2;0;7;0;;
17856;
0,
0,
.
.
.
total 17856 0's

It says there's 2 VertexElement {type,Method,Usage,UsageIndex}:

2;0;6;0;,
2;0;7;0;;

Really strange, 2 stands for three Floats, 0 for default
6 for tangent? 7 for Binormal??

I have 2976 vertices, that is, each vertex has 17856/2976=6
zeros, they are all zero!!

Perhaps, .x exported from Maya does not fill the vertexelement
and cause UpdateSkinnedMesh malfuction.

But I am not familiar with vertex structure....

I am going to try to use DrawIndexedPrimitives to draw them all myself.






Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this