Jump to content
  • Advertisement
Sign in to follow this  
darkzim

Ragdolls with .x mesh

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

Currently, I have loaded my .x files manually with the hierarchy and can play animations. Now I want to use ragdoll physics with the characters that I have (.x files), and I already have a 3rd party physics library implace in my code (Tokamak). What I want to know is how I go about mixing Tokamak and the .x file. I was thinking about positioning invisible Tokamak primitves on my model for collision detection... But then how do I modify the .x model? Should I modify the individual frames' transformation matricies directly? If anyone could point me in the right direction that would be great [lol] .

Share this post


Link to post
Share on other sites
Advertisement
You've got the right idea. Rotate (generally you only rotate the bones) the transformation matrix. To get an idea of how that works, dig deeper into what the animator is really doing. Did you use the AnimationController or use someone else's that has source code?

Share this post


Link to post
Share on other sites
You change the bone's (D3DXFRAME) TransformationMatrix.

It's a good idea to create your own frame class (probably derived from D3DXFRAME):


// extended frame class
class Frame : public D3DXFRAME
{
public:
Matrix4D matCombined;
Matrix4D matOriginal;

Frame (); // constructor
~Frame (); // destructor

Frame* Find ( char const* name ); //find frame by name
void Reset (); // reset transformations to default values
void Update ( Matrix4D const* matTransformation = NULL ); // update hierarchy
int Count (); // count frames in a tree
};

// constructor
Frame::Frame ()
{
Name = NULL;
pMeshContainer = NULL;
pFrameSibling = pFrameFirstChild = NULL;
matCombined = Matrix4D::GetIdentity ();
matOriginal = Matrix4D::GetIdentity ();
TransformationMatrix = * (D3DXMATRIX*) Matrix4D::GetIdentity ();
}
// destructor
Frame::~Frame ()
{
delete[] Name;
delete pFrameSibling;
delete pFrameFirstChild;
}

//find frame by name
Frame* Frame::Find ( char const* name )
{
Frame* pFrame;
Frame* pFramePtr;

// if name matches return this
if ( Name && name && !strcmp ( name, Name ) )
return this;

//iterate over siblings
if (( pFramePtr = (Frame*) pFrameSibling ))
{
if (( pFrame = pFramePtr->Find ( name ) ))
return pFrame;
}

//iterate over children
if (( pFramePtr = (Frame*) pFrameFirstChild ))
{
if (( pFrame = pFramePtr->Find ( name ) ))
return pFrame;
}

// nothing found
return NULL;
}

// reset transformations to default values
void Frame::Reset ()
{
TransformationMatrix = * (D3DXMATRIX*) matOriginal;

Frame* pFrame;
//iterate over siblings
if (( pFrame = (Frame*) pFrameSibling ))
pFrame->Reset ();
//iterate over children
if (( pFrame = (Frame*) pFrameFirstChild ))
pFrame->Reset ();
}

// update hierarchy
void Frame::Update ( Matrix4D const* matTransformation )
{
Frame* pFrame;
Matrix4D identity;

// if no matrix, use identity. combine matrices
if ( !matTransformation )
{
identity = Matrix4D::GetIdentity ();
matTransformation = &identity;
matCombined = TransformationMatrix;
}
else
matCombined = TransformationMatrix * (*matTransformation);

//iterate over siblings
if (( pFrame = (Frame*) pFrameSibling ))
pFrame->Update ( matTransformation );
//iterate over children
if (( pFrame = (Frame*) pFrameFirstChild ))
pFrame->Update ( &matCombined );
}

// count frames in a tree
int Frame::Count ()
{
int num = 1;

Frame* pFrame;
//iterate over siblings
if (( pFrame = (Frame*) pFrameSibling ))
num += pFrame->Count ();
//iterate over children
if (( pFrame = (Frame*) pFrameFirstChild ))
num += pFrame->Count ();

return num;
}


, then set all the Frame::TransformationMatrix, then call Frame::Update.

Are you loading the file yourself (because D3DXLoadMeshFromX usually collapses hierarchy)?

Then after loading you will have to map bones to frames.
I did it by creating my own mesh container. Both frame hierarchy and mesh containers are contained in another class, responsible for loading them.

Mapping is probably like that:

// for all bones
for ( DWORD i = 0; i < pMesh->pSkinInfo->GetNumBones (); i++ )
{
// get bone name
char const* BoneName = pMesh->pSkinInfo->GetBoneName ( i );

// find corresponding frame
Frame* pFrame = FindFrame ( BoneName );

// set transformation
if ( pFrame )
ppFrameMatrices = &pFrame->matCombined;
else
ppFrameMatrices = NULL;
}



then create another mesh (copy of the first) and on update:

pRootFrame->Update ();
// update matrices
for ( DWORD i = 0; i < pSkinInfo->GetNumBones (); i++ )
{
// set inverse transformation
pBoneMatrices = *pSkinInfo->GetBoneOffsetMatrix ( i );
if ( ppFrameMatrices )
pBoneMatrices *= *ppFrameMatrices ;
}
// update the mesh
void* SrcPtr;
void* DestPtr;
pMesh->MeshData.pMesh->LockVertexBuffer ( D3DLOCK_READONLY, &SrcPtr );
pCopyMesh->LockVertexBuffer ( 0, &DestPtr );

if ( SrcPtr && DestPtr )
{
pMesh->pSkinInfo->UpdateSkinnedMesh ( (D3DXMATRIX*) pBoneMatrices, NULL, SrcPtr, DestPtr );
pMesh->MeshData.pMesh->UnlockVertexBuffer ();
pCopyMesh->UnlockVertexBuffer ();
}



... I'm sure if you didn't know this before you've lost me. I still hope you've got the idea.
There is also a book Advanced Animation with DirectX on this.

Share this post


Link to post
Share on other sites
But what would you do with conflicting physics and animation? Can you sort of input the animation to the physics engine?

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!