Archived

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

skeletal animation sort of working

This topic is 5084 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

well, i have the weights and indices for each vertex being sent to my shader and it all seems to work fine. I have a few issues with getting the matrices right though. What i have for my bones is a position, and angle/rotation the problem is combining these into a matrix, and then combining it with the parent matrix. should it go like for the bones matrix: boneMatrix = translate matrix * rotation matrix boneMatrix = boneMatrix * parent matrix and my position for my bones should be relative to the parent? what if i just used a distance? how would i create a translation from that?

Share this post


Link to post
Share on other sites
Actually I think you want to do rotation on the left. Translation will most likely always be the last thing you do.

So,

boneMatrix = rotation_matrix * translate_matrix;
boneMatrix = boneMatrix * parent_matrix;

If you are using code from the Advanced animations book, you may have to invert the quaternion rotation when importing it from the x file. If not, forget I said anything. Otherwise refer to the thread "Problems with Advanced Animation Book" or something like that. Search for D3DXQuaternionInverse.

Chris

Share this post


Link to post
Share on other sites
hrmm im actually not using quaterions.... but maybe i should as nothing i do seems to be working :-/

should the very first bone''s parent be an identity matrix?

the way i have done my shader is to have the shader find the average from the local matrix array, then that is multiplied with the worldViewPorjection matrix, so i dont know if i have to do anything special there?

if i must use quaterions, any tutorials as to what they are how to use them etc?

thanks

Share this post


Link to post
Share on other sites
Don''t use quaternions for this. They are simply an alternative to multiple-axis rotations.

I''m not sure what you mean by taking the average of the local matrix array. Perhaps some code would help, if you can provide it.

Are you loading the mesh from an X-file? Are you updating hierarchies, re-structuring mesh data, etc?

Chris

*Life is like the rock in a sling-shot. Pick a good target, take good aim, and get there as soon as possible!*

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
no xfile stuffs, i use my own file formats and model formats, and use a shader to do the work.

i managed to get it to sort of work, but rotating a bone causes its vertices to be rotated around the model axis, not the origin of the bone, i tried to do a transform to get them to rotate around the bone, but this does truley weird things.

[cpp]
void Model::UpdateSkeleton()
{
//go through and update all bones
int i = 0;
for( int i = 0; i < boneKeys.size(); i++ )
{
D3DXMATRIXA16 parent;
D3DXMATRIXA16 matRotation;
D3DXMATRIXA16 matTranslation;

Transform();
D3DXMATRIX viewProjection;
viewProjection = matWorld * ENGINE.GetRenderMgr()->GetCamera()->matView * ENGINE.GetRenderMgr()->GetCamera()->matProjection;
//D3DXMatrixTranspose( &viewProjection, &viewProjection] );
KeyFrame boneKey = boneKeys;
Bone boneBone = modelData->skeleton[i];


if( modelData->skeleton[i].parentId != -1 )
{
parent = boneArray[ modelData->skeleton[i].parentId ];
}
else
{
D3DXMatrixIdentity( &parent );
}

D3DXMatrixIdentity( &boneArray[i] );
//D3DXMatrixTranslation( &matTranslation, modelData->skeleton[i].position.x, modelData->skeleton[i].position.y, modelData->skeleton[i].position.z);
//D3DXMatrixTranslation( &matTranslation, 0, 0, 0);

D3DXMatrixRotationYawPitchRoll( &matRotation, boneKeys[i].rotation.x, boneKeys[i].rotation.y, boneKeys[i].rotation.z);


//D3DXMatrixRotationYawPitchRoll( &matRotation, 0, D3DXToRadian(90), 0);
//D3DXMatrixMultiply( &boneArray[i], &matRotation, &matTranslation );
D3DXMatrixMultiply( &boneArray[i], &boneArray[i], &matRotation );
//D3DXMatrixMultiply( &boneArray[i], &boneArray[i], &matWorld );
D3DXMatrixMultiply( &boneArray[i], &boneArray[i], &parent );
}

}
[/cpp]

thats the code to transform my bones, i do a rotation, and then multiply it with the bones parent. Doing any translation other than 0,0,0 causes weird results.

Share this post


Link to post
Share on other sites
Hi, supagu!
From what I observed, I think you''re not very sure of how to obtain the position of the child bone with respect to the parent bone. In my opinion, this is how you do it.
1. Get the position of the child bone. Let it be vChild.
2. Get the position of the parent bone. Let it be vParent.
3. Get the translation vector. Let it be vTranslate, and so
we have vTranslate = vChild - vParent.
4. Get the translation matrix using vTranslate. Eg. D3DXMatrixTranslation( &matTranslate, vTranslate.x, vTranslate.y, vTranslate.z ). Use this matrix as the child translation matrix.
5. Then, multiply them like what Supernat02 has explained to you.
Hope this helps!

Share this post


Link to post
Share on other sites
problem is, when i apply any transformation to my bone matrices, i get weird results?!

is there any one that has skinning working with thier own transforms? sure would like to get thier icq and have a chat.

Share this post


Link to post
Share on other sites
How is your model stored?

If you have one bone per vertex, you can store the vertices in "bone space". Your bone transformation will put it back into model space.

Another method is the have the vertices in model space all the time. This also allows multi-bone influences per vertex.

Now, this step is neglected in almost everything that talks about bones. Your mesh has a certain pose when exported. Record the translation and orientation of each bone in addition to vertex position when it is exported. This is your reference pose. Calculate your bone transform hierarchy for the reference pose. Find and store the inverse of each of these matrices. This is done once, on initialization.

Now, for the actual bone pose (every time you have a new keyframe), calculate the bone transform hierarchy. Multiply each matrix by it''s inversee reference pose matrix. Transpose these, store them in constant registers, and you should be good to go.

I don''t remember off hand which order you should translate or rotate, but it takes seconds to try it the opposite way.

Share this post


Link to post
Share on other sites