Page 1 of 1

Sharing animation

Posted: Fri Apr 09, 2004 1:41 pm
by labigne
Hi all

I was just wondering if it's possible to share animations between 2 entities having the same kind of skeleton ?

Thanks for your replys

Posted: Fri Apr 09, 2004 3:01 pm
by sinbad
You can share the same skeleton between multiple meshes, and hence the animations which are attached to the skeleton can be shared between several meshes. And of course, entities share meshes with each other so yes, entoties share skeletons and animations.

However, at present you can't share an animation between several skeletons. This is because they are quite tightly coupled, in that the animation tracks refer specifically to the bones in the skeleton. It wouldn't be impossible to separate them, but I think it's fairly difficult to ensure your content matches up again all the time so I kept them together.

Posted: Fri Mar 11, 2005 8:11 am
by Injector
That is a feature i am in desperate need of. The bone setup (names, hierarchy) of all our models is the same (because we want every character to be able to play all available animations), only the binding pose is different for each character.
What we have done so far is just copying and pasting the <animations> section to the different skeleton files (so it is exactly the same for every character), but now we have got a problem with memory consumption.

Would it be possible (maybe even for me) to easily add methods like, say addAnimation(Animation*) to the Skeleton[Instance] class without (or minor) sideeffects (like taking care who is responsible for deleting the animations)? There would be a single .skeleton file holding all the animations, and several .skeleton files only defining the binding pose of a certain character.

It would be great to receive an answer.

Injector

Posted: Fri Mar 11, 2005 12:55 pm
by kikito
Injector wrote:The bone setup (names, hierarchy) of all our models is the same (because we want every character to be able to play all available animations), only the binding pose is different for each character.
Can't you have only one scheleton with all the available animations on it? As Sinbad said, the scheleton itself can be shared between meshes. I think the memory footprint of this could be even smaller than having all those Animation objects separated.

Just my two cents :)

Posted: Fri Mar 11, 2005 12:58 pm
by marco.c
I'm sorry I can' properly give an answer to your question, but I'm having the same problem as you. We might put together our efforts to find a solution.
I found out a way to load an animation from a file.
Have you ever heard the .bvh file format?
It contains motion capture data, so animations. It's easily parseable.
The bvh file can be shared, and you load it at runtime. Once you have loaded it, with a few wise lines of code you get the Animation object.

I think it partially matches with your goal. I'm looking for the wierd addAnimation method too. If I discover something, I'll tell you. Ok?

Good luck.
M

Posted: Fri Mar 11, 2005 1:21 pm
by Injector
Can't you have only one scheleton with all the available animations on it?
No, I can't because the binding poses of the characters (which are part of the skeleton) are deliberately distinct (they might just be scaled to reflect different character sizes and/or the translate offsets might be different). The scale is not a problem within an animation though, as there are only rotations anyway (mostly).

Posted: Fri Mar 11, 2005 4:47 pm
by marco.c
GOT IT!
Although there's no addAnimation method, you can always create it.
Given a Skeleton object, let say skel, you can invoke

Code: Select all

Animation *anim = skel->createAnimation("AnimName",length);
Then, you can apply the same animation to another Skeleton. Have a look at

Code: Select all

void apply(Skeleton *skeleton, Real timePos, Real weight=1.0, bool accumulate=false)
anim->apply(skel2,......);
Let me know if it helps.
M.

Posted: Fri Mar 11, 2005 4:52 pm
by marco.c
I forgot. You obviously have to create the Animation yourself.
That means, creating an AnimationTrack for each bone, and as many KeyFrame for each track as the frames in your Animation.
I've written a chunk of code which does this work. If you want I can tell you more.

Good luck,
M

Posted: Fri Mar 11, 2005 5:00 pm
by Injector
Yeah, I could create animations manually, but I do not want that as that would impose the memory consumption problem I am trying to avoid.

Posted: Fri Mar 11, 2005 5:13 pm
by marco.c
I see your point, but I don't think you have many more chances.
The Animation handler that you get is just a pointer to the inner data structure in your skeleton. It just takes as much memory as a pointer does, then it's the same way OgreXMLConverter works.

When you load a resource in a Entity, it already contains the Animation objects. I don't actually know how the apply() method deals with the memory. :?
Otherwise, the only way I see is:

Code: Select all

void Entity::shareSkeletonInstanceWith (Entity *entity)
but I've never tried it, and I don't actually know how it works.
Remember, there might be some differences betweem a Skeleton and a SkeletonInstance.
Good luck.

M

Posted: Fri Mar 11, 2005 6:37 pm
by kikito
I see that your main problem here is the way animation tracks are handled in the SkeletonSerializer.

You see, as they are, animation tracks allways are created allways with a hard reference to a bone. But note that internally, Animation and AnimationTrack has a reference use Nodes, not Bones. You could try to rely on this, and do something like creating:
- "OgreBoneHandler" class (subclass of Node): Node with a "bone handler"; a string or number, used to find a bone on a skeleton. Maybe a pointer to that bone for the shake of speed.
- "OgreIndirectAnimation" class (subclass of OgreAnimation?) so you can apply them indirecly to a skeleton. A pointer to a OgreSkeleton (OgreSkeletonInstance?) on it.
- "OgreIndirectSkeletonSerializer" OgreSkeletonSerializer able to read Indirect animations (You'll need to change the readAnimation function and maybe that's all)

Using numbers on bone handlers could be slightly faster than using strings, but you'd need more changes for that (like another class called "OgreSkelletonSetup" for matching bone names with numbers, "OgreSkelletonWithSetup" pointing to it and more changes on OgreIndirectSkeletonSerializer to keep track of all that... :P)

I won't be able to read this forum untill monday, so good luck and see ya!!

Regards!