Store a complete bone-mesh hierarchy?

Started by
2 comments, last by haegarr 14 years ago
I'm in the middle of creating my model and mesh classes, where a single model has multiple meshes as well as a set of transforms which serve as the bones for the model. My current problem is that where each mesh stores a reference to it's parent transform (bone), that's the only reference that it stores and I don't have a record of the bone hierarchy, so as soon as we have a transform with a child transform, everything breaks down because I can't concatenate the transforms to get a final one for some meshes. I've also been thinking about when I get around to animation, I'll probably want to store an animation as a single file where I just reference each bone that is animated with a name so I can just apply a single animation or animation set to different models, and it will just work as long as the model has the correct bones. Maybe it would just be easier to store the bone hierarchy with each bone as a transform (relative to it's parent), the name of the bone, and the name (or index if they're in an array) of the bone's parent. Thoughts? Is there a better way to do something like this? Am I making this too complicated (as I often do)?
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
Advertisement
Perhaps you should go over the concepts of a scene graph. That is basically what you wanna make, within the context of your model.
Names are a good way to associate data orthogonally. So you're on the right track.

But they can also be quite slow at runtime. Fortunately there's a good way around that. Create methods and structures to "bind" data together. I.e. the list of bone names for each mesh (there will be multiple for non rigid meshes) becomes a list of indices or pointers after binding.

You do the binding only once, when you instantiate the model with a set of meshes, thus marrying orthogonality at creation time with speed at run time.

Some goes for animations btw.
A skeleton is more than just parenting. Depending on supported animation features (keywords blending, layering) you need to store a total weight, too. And you may need to check whether the weight is still zero after all animations are processed, falling back to the rest post if so (hence you also need access to the rest pose transformations as well). Moreover, you don't want to drive the parenting further than the skeleton root is, while parenting in the sense of a scene graph goes up to the scene's root. (I explicitely warn to think of the scene graph as a panacea.)

However, Endar, I personally use a similar concept of binding animations to skeletons. First of all, both animations (i.e. the value tracks, for example key-frame interpolation curves) as well as skeletons (i.e. their structure and rest pose) are resources, especially prototypes in this case. Both kinds are totally unaware of the other.

Using a skeleton means to create a skeleton instance in the scene (perhaps scene graph) with a bone instance for each bone prototype. The bone prototype store the parent reference, the local rest pose parameters, perhaps motion limitations, and an identifier. The bone instance store a reference to ist prototype and the current local transformation and its global transformation.

Using an animation is similar: The prototype consists of a sequence of tracks, each one parametrized with a name. When an animation becomes instanciated in the scene (the timeline in this case, to be exact), a track instance for each track prototype is created. The instance refers to its prototype, but also to the target. The target is looked up on instanciation from the specified skeleton instance by using the track's name (I also use a type specifier and semantic and symmetry tag, but that doesn't mean anything to the principle). If the skeleton instance can resolve the look-up, it returns a pointer to the bone instance's transformation, what is then bound by the animation instance to work further on. If, on the other hand, the look-up fails, then the track cannot be bound and is not instanciated at all.


EDIT: Huh, Rattenhirn has mentioned something like that during I was still writing ;)

This topic is closed to new replies.

Advertisement