How to parse skinned meshes?

Started by
4 comments, last by Shenjoku 17 years, 2 months ago
Hi, I'm currently working on making a small 3D game and I'm kinda stuck on how to parse a skinned mesh into the game for use. I've tried looking over the SDK tutorial but honestly I don't count that as a tutorial at all because just looking at code doesn't really teach me anything if I don't know what you need to do exactly. I am using visual studio 2005 with the latest directX SDK (december 2006) just as an fyi, and if anyone has any idea where I can find a more in depth tutorial or some such thing I would greatly appreciate it :) thank you
Advertisement
Parsing a skinned mesh is no easy task as you've seen. There are two ways to do it if you use an X file. You can use the built-in D3DX routines that load the mesh and create an animation controller for you. Or you can create your own X file parser and animation controller as described by Jim Adams in his book "Advanced Animation in DirectX 9". Get the latest version of the book if you really want to learn this, because I don't think the original animations worked properly due to a sign error in the quaternions somewhere (can't swear on that though).

My approach is to take a middle ground between the two. I like the X file parser because forces me to create a class and routines that will let the parser add frames and meshes from the X file. These same routines can then be adapted to allow frames and meshes to be added from other model formats. Another advantage of parsing the file is that you can store and retrieve any kind of data you can think of in the X format, if the X format is good for you. I don't think any level of encryption or security exists there.

The tutorial with DirectX doesn't create a parser class. It lets you create customized structures and overload functions to load and destroy frames and meshes, and it does all of the parsing of the file internally. The key difference between its parser and the one in the Advanced Animation book is that the D3DXLoadSkinnedMeshFromXFile (or whatever the function is called) creates a root frame by default, so a root frame always exists. The X file itself may just contain a mesh without any frame data, but the D3DX parser will place that mesh in a default root frame. The Advanced Animation treats the frames and meshes separately I believe.

As for the actual task of parsing the file...you need to read in the frame heirarchy, mesh data, and skin info from the X file. If the skin info is valid (indicated by being non-null with the Microsoft D3DXLoadSkinned... approach or indicated by containing 0 bones with the parser method), then you go through and map each bone to its corresponding matrix and store those matrix pointers in the mesh container for easy access later.

To draw the mesh (assume no animation at the moment), you start at the root and multiply each sub-frame matrix by its parent. The root's matrix will just be the position/scale/rotation you want the entire mesh to be in the world. The arm's matrix is multiplied by the body matrix to create the arm's combined matrix. That matrix is then multiplied by the hand matrix to create its combined matrix, etc. You can render two different ways. The D3DXLoadSkinned... example has a scheme to render with hardware matrix blending or software. The Advanced Animation method just uses software (the version I have anyway). The tutorial uses hardware for the number of bone blends that are allowed, then uses software for the rest. It also allows you to change the type from indexed, non-indexed, vertex shader indexed/non-indexed, and software. I suggest stripping the tutorial down to just non-indexed hardware skinning if you want to learn it a little better, gets a lot of the code out of the way. Then learn the other methods.

To render animation, before updating the matrices as described above, you would go through each animation that is active, determine what effect that animation has on which bones, and then apply the transformation to the bones (frames) in the heirarchy.

I would be surprised if there wasn't some sort of tutorial here on Gamedev.net that described the code or does a better job explaining than I did.

Good luck,
Chris
Chris ByersMicrosoft DirectX MVP - 2005
ok so I'm doing what you suggested and trying to break apart the skinned mesh example and add it to my graphics core for my game but I'm having library linker problems that I've had before and I don't know how to fix them...
SkinMesh.obj : error LNK2001: unresolved external symbol __check_commonlanguageruntime_version
SkinMesh.obj : error LNK2001: unresolved external symbol "public: long __thiscall CMyD3DApplication::GenerateSkinnedMesh(struct D3DXMESHCONTAINER_DERIVED *)" (?GenerateSkinnedMesh@CMyD3DApplication@@$$FQAEJPAUD3DXMESHCONTAINER_DERIVED@@@Z)
SkinMesh.obj : error LNK2001: unresolved external symbol "long __stdcall D3DXCreateTextureFromFileA(struct IDirect3DDevice9 *,char const *,struct IDirect3DTexture9 * *)" (?D3DXCreateTextureFromFileA@@$$J212YGJPAUIDirect3DDevice9@@PBDPAPAUIDirect3DTexture9@@@Z)
SkinMesh.obj : error LNK2001: unresolved external symbol "long __cdecl DXUtil_FindMediaFileCb(char *,int,char *)" (?DXUtil_FindMediaFileCb@@$$FYAJPADH0@Z)
SkinMesh.obj : error LNK2001: unresolved external symbol "long __stdcall D3DXComputeNormals(struct ID3DXBaseMesh *,unsigned long const *)" (?D3DXComputeNormals@@$$J18YGJPAUID3DXBaseMesh@@PBK@Z)
LIBCMTD.lib(crt0.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup

my guess is I'm missing some kind of library file or maybe I'm linking t the wrong one but I honestly have no idea...I've never had this many problems with linker errors before.

EDIT: nevermind I got all that resolved :) current error I need to fix=figure out where D3DXMatrixLookAtLH function is declared. like what header file if anyone knows.

[Edited by - Shenjoku on January 26, 2007 2:18:06 PM]
Sorry to double post but I ddin't want to make a second topic.
Can someone please tell me what header file is needed to use the D3DXMatrixLookAtLH() function? I can't find it and I keep getting this error:
LINK : error LNK2020: unresolved token (0A00005B) D3DXMatrixLookAtLH

Even when I comment out the line that I was using for the function it still gives me the error which is confusing the hell out of me.
Try including these libs:
d3dxof.lib
d3dx9.lib
dxguid.lib
d3d9.lib
yay thank you :) your help finally got me on the way to getting it all fixed. It's working perfectly now :) I jsut need to integrate it into my graphics core and all will be fine. A big thanks to everyone that helped. Couldn't have done it without yah.

This topic is closed to new replies.

Advertisement