Jump to content


Rendering Biped Bones with DirectX 9


6 replies to this topic

#1 Anddos

    Valued Member

  • Members
  • PipPipPip
  • 177 posts

Posted 23 September 2012 - 05:51 PM

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[i] = *pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i);

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

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

#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 5305 posts
  • LocationBellevue, WA

Posted 23 September 2012 - 06:48 PM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

#3 Anddos

    Valued Member

  • Members
  • PipPipPip
  • 177 posts

Posted 23 September 2012 - 07:45 PM

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?

#4 Reedbeta

    DevMaster Staff

  • Administrators
  • 5305 posts
  • LocationBellevue, WA

Posted 24 September 2012 - 05:36 PM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

#5 TheNut

    Senior Member

  • Moderators
  • 1697 posts
  • LocationThornhill, ON

Posted 24 September 2012 - 06:17 PM

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.
http://www.nutty.ca - Being a nut has its advantages.

#6 Anddos

    Valued Member

  • Members
  • PipPipPip
  • 177 posts

Posted 30 September 2012 - 02:56 AM

[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

#7 Anddos

    Valued Member

  • Members
  • PipPipPip
  • 177 posts

Posted 18 November 2012 - 10:08 AM

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[i] = *pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i);
FinalMatrices[i] *= *pMeshContainer->ppFrameMatrices[i];
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?





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users