Skeletal Animation With Attachments (And Clothing)

Started by
21 comments, last by fuchiefck 18 years, 10 months ago
Quote:Original post by MeshMan
I'm wondering how you put this all into a OOP kind of system? I've never fully understood how the render path looks. Like say you have a "class MeshNode" which essentialy is your mesh which contains - its local transform? If I also store a list of attatched MeshNode's, does it go something like:

I just use a tree list. The root node is at the top, and each node sends it's final result down to all of it's children.

If you're referring to weapons, I don't have them as part of the skeleton. Each weapon controls itself, rather than be part of the hierarchy. Characters would just have a simple list of attached objects. Scroll through the list to update and/or render, and let each object take care of itself. All the object really needs is a link to the bone matrix that it's attached to.

Quote:I think I get the clothing thing and now I think my lack of experience with bone animations might be the problem. Originally I thought it might be like 2d, where you had to animate every article of clothing. But with bone animations. All you need is a single skeleton that has all the motions. And then have the envelopes setup nicely so that no matter what mesh legs you use, or what mesh torso, or arms, they will always fit on the bones, inside the envelopes and animate nicely.

Skeletons are very important. If it's possible to use the same skeleton for all of the humanoid models in your game, go for it. I couldn't get away with it; my women looked like freaks with male shoulders. So I have gender specific skeletons. That means I can recycle animations between any gender-matching characters. Remember that you can scale models, so it's not very hard to make an ogre using the same skeleton you use to make an elf, with a bit of tweaking. Providing accurate melee-type contact between different scaled characters may bite you, though.

Quote:I have played with envelopes and animating bones in 3d Max. I didn't know that you could load a skeleton and then swap different meshes into the envelopes though. As I said this may have to do with my inexperience with skeletal models, but maybe you could give me some pseudo pointers as to how that's done?

The envolopes do not need to be exactly the same. I fitted a really thick hooded coat (like Jin's coat in Tekken 4) to a guy, and the coat's envolopes were huge. What I did was import the character mesh into the coat scene and gave it the same animations. As the time slider is moved around, they both animate together, and envolope/bending problems become obvious. So it's only the skeleton that is a must. You could start from scratch with new envolopes for each model, as long as you have a method to see the results.

Quote:Also, does anyone know where I could find a .x or a .max or .md3 that has bones and animations in it? Not up to paying for a model just for learning this technique.

There was a model, tiny.x, that comes with the Direct SDK. I think it still does.

Quote:I have Max, if worse comes to worse I can run though a tutorial to make my own. However I can never get the knee to tween right where the envelopes overlap, but that's clearly off topic. =)

I feel ya. I've been through it so many times, the pain is starting to subside, though. I personally hate the hip area more than the knees.
Advertisement
When it comes to loading the skeleton itself. Would that be in it's own .x? And then you would load the clothing meshes separately? If so, how do you attach the mesh to the skeleton. Is it a DirectX operation? Otherwise it sounds like it would be very complicated. lastly, you would have the torso and legs as separate meshes so you can change clothes, and the head separate for custom faces, and the arms separate so you can chop them off, then you would have tweening issues at those joints right? Unless you made the mesh continue past the joint for the arm and then had the break not at a joint. Did I just answer my own question?

So if you wanted to have changeable pants and allow both legs to be lopped off. You would have to build the legs, each as a separate mesh, build the hip area up to the top of the pants as a separate mesh. Then load all 3 when changing pants and apply them to the skeleton. I think that sounds right.

So could you give an example of how, through code, you apply meshes to a skeleton? I don't need actual source, I just don't even know where to look for that. For C# would it be in DirectX? or would you have to somehow write it yourself?

Lastly, do you have problems finding skeletal animations that will load properly other than tiny.x. I have heard it's near impossible.

Wow, I've learnt quite a bit already. I'm actually working on this right now. I'll keep you all up to date.

Thanks,
- GeekPlusPlus
- Newb Programmer: Geek++
Hi, I am currently working on a similar thing. I hope somebody can provide an explanation on the relationship between frames and mesh containers in a mesh hierarchy. I am quite confused, as different meshes are structured differently. As I step through my program when it's creating the frames and mesh containers, some meshes creates all the frames (bones) first and then create a single mesh container which "skins" the mesh, I think tiny.x does this. And other meshes I've encountered creates a frame, then creates a mesh container for that frame, and it does that for all the frames of the mesh.

I'm quite confused on the fact that if I want to create a mesh with swappable body parts, what kind of mesh format should i use... and how. thanks in advance...

and would somebody please have a look at my thread (below) and provide some responses if possible, thank you..!

http://www.gamedev.net/community/forums/topic.asp?topic_id=322974

-fuchiefck----------------------------------------------------------"Inside the world that you as a programmer or developer create, you are God" - Zerbst & Duvel
oh yeah I forgot,

GeekPlusPlus, I found this simple x file of a basic skeleton, with animations, which is quite nice, and thought it might be useful for you. not sure if you have it already but here it is:

http://www.toymaker.info/Games/html/x_file_animation.html

download the source code for this tutorial and u will find the x files. It comes in separate files for each animation set, but u can use Mesh Viewer in the SDK to combine the animation sets into a single file, like the tiny_4anim.x in the MultiAnimation sample of the SDK.

thx

-fuchiefck
-fuchiefck----------------------------------------------------------"Inside the world that you as a programmer or developer create, you are God" - Zerbst & Duvel
Quote:Original post by GeekPlusPlus
When it comes to loading the skeleton itself. Would that be in it's own .x? And then you would load the clothing meshes separately?

It just depends on how you prefer to do it. In my engine, I created an object called a "Race", which is basically just a skeleton class, with extra details like distance values and heights. Humanoid males have a race, and humanoid females use a different race. The race file is created externally using a small tool I made. It basically just rips the skeletal information (not animation, but bone offsets, hierarchy order and such) out of an x-file skinmesh and stores it by itself. All skin meshes from that point on are implimented as "suits". Characters equip suits to build their body just like they equip clothing or armor. All suits have a race type, and all compatible suits are of the same race.

There is never a reason to "attach" the skeleton to a mesh. The skeleton is only needed to animate. So the character object in your game would animate his skeleton, then pass the final array of animated bone matrices to all of his meshes. That array of matrices is all that's needed to render your skinmesh.

This is how I currently accomplish this. But it wasn't an easy task getting this far. I don't recommend diving in head first. You should probably try to experiment with a single animated mesh, at least until you get a good grasp of how it works.

Quote:lastly, you would have the torso and legs as separate meshes so you can change clothes, and the head separate for custom faces, and the arms separate so you can chop them off, then you would have tweening issues at those joints right? Unless you made the mesh continue past the joint for the arm and then had the break not at a joint. Did I just answer my own question?

Again, I made another tool. The tool loads in an x-file and allows me to select subsets to export as individual meshes. There are no tweening issues because all of the seem vertices have the exact same bone weights. You can see a snap of one of my characters here (don't poke fune, he's WIP [smile]). He's made up of about 16 seperate meshes, and there are never visible seams or cracks as he animates.

Quote:So if you wanted to have changeable pants and allow both legs to be lopped off. You would have to build the legs, each as a separate mesh, build the hip area up to the top of the pants as a separate mesh. Then load all 3 when changing pants and apply them to the skeleton. I think that sounds right.

Yes you could do it that way. But you might want to consider using subsets to seperate parts rather than seperate meshes.

Quote:Lastly, do you have problems finding skeletal animations that will load properly other than tiny.x. I have heard it's near impossible.

I use the exporter from www.Quest3D.com with a slightly old version of 3D Studio. Once again, I made a tool which extracts the animation from an x-file and stores it seperately. But I've never had any problems reading the exported files.
Hey Jiia,

Thanks for replying again.

Right now, I have successfully loaded a bone animated character into a hierarchy structure in C#. At the moment I have rendered different parts of the frame with it's mesh and skin. Next I will whip up a structure to recurse through the tree and show all the available meshes. Then, I can try altering them.

Things seem to be going quite well so far. Hopefully I don't go insane when I get to actual animations and switching.

At the moment I don't have anymore specific questions since your last post, but I'm sure I will soon.

And thanks to fuchiefck for the C++ source and the .x skeleton, they have helped a lot.

- GeekPlusPlus
- Newb Programmer: Geek++
Hello I'm back.

I have managed to load, display, and animate a few x files (some I even made and exported from 3d Max) with my C# skeletal demo program. It's fairly similar to the C++ so if you know that you can help with my next problem.

I'm trying to get swapable meshes working on my frame. The first thing I tried to do was take the MeshContainer of a simple mesh cylinder and set it to be the MeshContainer for the left thigh bone. When I did this nothing happened. Obviously my cylinder is missing some information needed to work with that frame. Could someone explain this to me?

Now, I'm assuming if I made a bunch of animations for a skeleton. then I added the mesh components to it so that they would be animated along with the bones, then if I save the mesh in a separate x file, then it would work when I set that mesh to be the mesh container for the frame? Since it was designed for that frame?

That might sound confusing, but the bottom line is if I have an animated skeleton, I'd like to be able to use different meshes on it without reanimating everything. And I might want to switch just the legs. (thighx2 calfx2). So what do I need to do to attach new mesh to my animated frame?

Thanks

- GeekPlusPlus
- Newb Programmer: Geek++
>take the MeshContainer of a simple mesh cylinder and set it to be the MeshContainer for >the left thigh bone.

You cannot swap the whole meshcontainer like you tried, what happens is, you will be replacing the position (transform matrix) of the original mesh container, along with other information that you might like to keep original... and the matrix of the new mesh may not be the same as the original one. When this happenes the cylinder may appear out of position, or just being rendered somewhere outside the screen. What u should do is: load a new mesh and get its pMesh pointer, and when you are rendering the part that you want to replace, just CloneMeshFVF the new mesh, so the pMesh pointer of the original left thigh bone will become the pMesh of the cylinder. Your code may become something like this:

if (pFrame->Name == "L_ThighBone")
{
pCylinderMesh->CloneMeshFVF(pCylinderMesh->GetOptions(), pCylinderMesh->GetFVF(), pDevice, &pMeshContainer->MeshData.pMesh);
}
//continue drawing the meshcontainer..

Teh above code will make a copy of the pCylinderMesh and place it in pMeshContainer->MeshData.pMesh, which was your original mesh.

>I'd like to be able to use different meshes on it without reanimating everything.
You won't have to reanimate anything if you just change the pMesh pointer, since your frame and meshcontainers remains original.

Other things you have to look for is the transform matrix of the Cylinder by itself, it may affect the position, and may not be placed in the right position. For more info please goto: http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.win32.programmer.directx.graphics

and look for a thread called "swapping meshes in a mesh hierarchy"... I've been getting quite a bit of help from there.

Hope I have helped...

-fuchiefck
-fuchiefck----------------------------------------------------------"Inside the world that you as a programmer or developer create, you are God" - Zerbst & Duvel
Thanks for replying.

I get what you're saying, I'm just having problems converting this part to C#. The C++ clone function takes a reference of the current mesh pointer so that you can attach the new mesh pointer to it. In C# there is no parameter, but the function returns the cloned mesh. However, the Mesh proporty on the MeshData is "not a variable" so I can't just set it

MeshContainer.MeshData.Mesh = newMesh.Clone(<flags>,<vert format>, _d3dDevice);

That's how I tried to do it, and it tells me that Mesh is not a variable, so I can't set it that way. There is no SetMesh or anything like that either. Does anyone know how to set the mesh pointer in C#?

- GeekPlusPlus
- Newb Programmer: Geek++
Hey, I figured out my mesh switching problem.

Instead of setting the mesh I set the MeshData

MeshContainer.MeshData = newMeshData

I'm going to have troubles if I want to load meshes with FromFile() though since I can't seem to copy a pure Mesh into the MeshContainer.

Anyway, then I setup the new textures and materials and it did switch. The problem is the new "leg" is about 20x smaller when attached to the skeleton than if I render it by itself. Now this means that somewhere along the skeleton's chain he has been scaled down. But _I_ have never applied a scale of any sort, or even changed the default starting position. Is it possible that the model has some inherit auto scale down?

I did think it was odd that he was only about 2 units tall...

- GeekPlusPlus
- Newb Programmer: Geek++

This topic is closed to new replies.

Advertisement