Rendering Biped Bones with DirectX 9

Abd4b56ff96074042dda5243e99a5d14
0
Anddos 103 Sep 23, 2012 at 17:51

I have an animated model up on screen thats in .X format, what i want todo is render the bones, there is 35 of them

Here is a list

Bip01_R_UpperArm 0
Bip01_Spine3 1
Bip01_Neck 2
Bip01_Spine2 3
Bip01_Spine1 4
Bip01_R_Clavicle 5
Bip01_Spine 6
Bip01_L_UpperArm 7
Bip01_L_Clavicle 8
Bip01_Pelvis 9
Bip01_R_Thigh 10
Bip01_L_Thigh 11
Bip01_R_Calf 12
Bip01_R_Foot 13
Bip01_R_Toe0 14
Bip01_L_Calf 15
Bip01_L_Foot 16
Bip01_L_Toe0 17
Bip01_L_Forearm 18
Bip01_L_Hand 19
Bip01_L_Finger1 20
Bip01_L_Finger11 21
Bip01_L_Finger0 22
Bip01_L_Finger01 23
Bip01_L_Finger02 24
Bip01_L_Finger12 25
Bip01_R_Forearm 26
Bip01_R_Hand 27
Bip01_R_Finger1 28
Bip01_R_Finger11 29
Bip01_R_Finger0 30
Bip01_R_Finger01 31
Bip01_R_Finger02 32
Bip01_R_Finger12 33
Bip01_Head 34

heres how the update function gets the bone matrix

// set FinalMatrices to that frame’s offset matrix
FinalMatrices = *pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i);

// multiply that by the animated frame matrix
FinalMatrices *= *pMeshContainer->ppFrameMatrices;

now do i need to convert the FinalMatrix array to D3DXVECTORS?

6 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Sep 23, 2012 at 18:48

A matrix represents a coordinate system, so usually to draw a matrix I draw the axes - XYZ in red, green, and blue respectively. The X axis is the first row of the matrix, the Y axis is the second row, etc. (using a row-vector convention). The origin is the last row.

For viewing skeletons it’s also common to draw a line connecting the origins of each bone and its parent bone, which lets you visually see the hierarchy of bones.

Abd4b56ff96074042dda5243e99a5d14
0
Anddos 103 Sep 23, 2012 at 19:45

I dont plan to draw lines, but points, so if i scale and rotate the mesh , i will need to transform the bones matrix by that matrix?

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Sep 24, 2012 at 17:36

It depends. There are two matrices commonly associated with a bone. One is the bone-to-parent matrix that transforms from the bone’s local space to its parent bone’s local space. That matrix does not need to be altered if the whole mesh is transformed. Only the root bone needs to be transformed, then all the others will inherit the transform from it. On the other hand, at some point in the rendering you probably calculate a bone-to-world matrix for each bone, that has all the parent matrices baked in all the way up to the root. At that point to transform the mesh you would need to transform all the bones, since the inheritance has already been calculated.

6837d514b487de395be51432d9cdd078
0
TheNut 179 Sep 24, 2012 at 18:17

I believe the X file format stores absolute bone transformations, not relative. So the matrix you read in from the file already takes into account its parent matrix. If all you want to do is render the joints as points (note on technicality, rendering bones requires you render lines, not points; a bone is a connection of two joints), then just render a point at the bone’s offset position. This will render the point in pose space. You can transform that into world space if you want. Rotation is irrelevant and scale is probably irrelevant too, unless you really want to scale the point to proportion.

Abd4b56ff96074042dda5243e99a5d14
0
Anddos 103 Sep 30, 2012 at 02:56

[qoute]
Then just render a point at the bone’s offset position. This will render the point in pose space. You can transform that into world space if you want.
[/qoute]

ok i got the idea now

Abd4b56ff96074042dda5243e99a5d14
0
Anddos 103 Nov 18, 2012 at 10:08

this is what my update function looks like

void update_mesh_containers(CUSTOM_FRAME* pFrame)
{
// cast the pFrame’s mesh container pointer to a CUSTOM_MESHCONTAINER*
CUSTOM_MESHCONTAINER* pMeshContainer = (CUSTOM_MESHCONTAINER*)pFrame->pMeshContainer;
if(pMeshContainer && pMeshContainer->pSkinInfo)
{
NumFrames = pMeshContainer->pSkinInfo->GetNumBones(); // find how many frames
// for each frame in the mesh container…
for(UINT i = 0; i < NumFrames; i++)
{
//MessageBox(NULL,pMeshContainer->pSkinInfo->GetBoneName(i),”Bone names”,0);

// set FinalMatrices to that frame’s offset matrix
FinalMatrices= *pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i);
FinalMatrices*= *pMeshContainer->ppFrameMatrices;**
writeBonesTxt(pFrame,i);
}
void* pSrc = NULL; // a void pointer for the original mesh
void* pDst = NULL; // a void pointer for the modified mesh
// lock the two meshes
pMeshContainer->MeshData.pMesh->LockVertexBuffer(NULL, &pSrc);
pMeshContainer->pFinalMesh->LockVertexBuffer(NULL, &pDst);
 
// store the animated mesh into FinalMesh
pMeshContainer->pSkinInfo->UpdateSkinnedMesh(FinalMatrices, NULL, pSrc, pDst);
// unlock the two meshes
pMeshContainer->pFinalMesh->UnlockVertexBuffer();
pMeshContainer->MeshData.pMesh->UnlockVertexBuffer();
}
// run for all siblings
if(pFrame->pFrameSibling)

update_mesh_containers((CUSTOM_FRAME*)pFrame->pFrameSibling);
// run for the first child (which will then run all other children)
if(pFrame->pFrameFirstChild)

update_mesh_containers((CUSTOM_FRAME*)pFrame->pFrameFirstChild);
}

so i just multiply *pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i); with the translation matrix right?