Hi Jan,

Jan Ciger wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Cedric,

Cedric Pinson wrote:
You are right, but it's not the job of osgAnimation to make this
assumption, osgAnimation
interpolate bewteen keyframes. The optimization of key is the
responsiblity of the exporter
instead. In the osg exporter i bake everything without optimization yet,
that's why it produces
a big amount of data. To work quickly i just exported all baked animation.
If you want you can just put one key for a channel or two with 40
seconds between them.
So it's not a blocker. But in the futur you could want to separate each
channel like PosX PosY PosZ
because sometimes it vary only on one value and you can save space like
espacialy if you have to bake
animation.

OK. My concern is not so much optimization (osgAnimation compressing the
keyframes), but the fact that the library can deal with sparse keyframes
for some bone and will correctly interpolate between them. If it can do
that, despite of the current naive exporter, then fine, but I didn't see
the timestamp/offset anywhere in the exported animation. How does it work?

So those 3 elements can be splitted in different file, and in animtk it
was like that before, the .osg is just a container of those three elements.

OK, that is what I suspected too.

There is no framerate, you specify your keyframes in seconds so more
your put keyframes
in a short range of time and better the resolution is.

Sorry, but that is *NOT* acceptable. That is related to the issue with
the keyframes above. You need to allow to either specify a duration of
the animation or a frame rate. You cannot rely on the density of the
keyframes to do this - that would require that every animation has keys
even for frames where nothing is moving, just to maintain the framerate.
That is extremely inefficient. Also, conversions from one framerate to
another would be extremely difficult, requiring resampling and
re-interpolation of possibly thousands of keys.

The way to go is to say:

duration 30
time 0 bone 1 x y z qx qy qz qw
time 15 bone 1 x y z qx qy qz qw
time 17 bone 1 x y z qx qy qz qw
time 0 bone 1 x y z qx qy qz qw
time 15 bone 1 x y z qx qy qz qw
time 17 bone 1 x y z qx qy qz qw


is valid today but will play 17 seconds because duration is last key time - 
first key
I can add a method animation->setDuration(30); then it will be what you want. 
And if you
want it in the osg file there is no problem to add it too.



With just three keys I have fully specified the animation, without any
implicit assumption about the duration or framerate. Moreover, there is
no need to maintain a long stream of interpolated keyframes anywhere -
the animation engine still needs to interpolate between them in real
time, so why not exploit this for storing the animations too. With your
approach I would need 30 keys (assuming one key/second) - 10x more data.

Your naive approach will simply not scale once you have to deal with
many animations coming from different sources with different framerates
(mocap, hand-animated, procedurally generated, different project, online
repositories, etc.). You cannot assume that everything will pass through
a converter that will normalize the framerate and pre-calculate the
interpolated keys for you - that is just impractical and costly.

Also, I have noticed that you have included scale keys. If you want only
rigid bones (the most common case, one rarely models something like the
"Gummi bears"), then you can drop both scale and translation. The
quaternions/rotation matrices/rotation vectors are enough, together with
the binding pose of the skeleton. You just apply the transformations
recursively from the root of the hierarchy each time. That allows a very
compact representation.

I think you did not read the examples code, there is not need to fill the time with a lot of keys...
code from osganimationskinning:
   osgAnimation::Animation* anim = new osgAnimation::Animation;
   {
osgAnimation::QuatKeyframeContainer* keys0 = new osgAnimation::QuatKeyframeContainer;
       osg::Quat rotate;
       rotate.makeRotate(osg::PI_2, osg::Vec3(0,0,1));
       keys0->push_back(osgAnimation::QuatKeyframe(0,osg::Quat(0,0,0,1)));
       keys0->push_back(osgAnimation::QuatKeyframe(3,rotate));
       keys0->push_back(osgAnimation::QuatKeyframe(6,rotate));
osgAnimation::QuatSphericalLinearSampler* sampler = new osgAnimation::QuatSphericalLinearSampler;
       sampler->setKeyframeContainer(keys0);
osgAnimation::AnimationUpdateCallback* cb = dynamic_cast<osgAnimation::AnimationUpdateCallback*>(right0->getUpdateCallback());
       cb->setName("right0");
osgAnimation::QuatSphericalLinearChannel* channel = new osgAnimation::QuatSphericalLinearChannel(sampler);
       channel->setName("quaternion");
       channel->setTargetName("right0");
       anim->addChannel(channel);
   }
3 keys for 6 seconds it's what you want isn't it ? and it animate only the quaternion, not the scale and not the position.

   {
osgAnimation::QuatKeyframeContainer* keys1 = new osgAnimation::QuatKeyframeContainer;
       osg::Quat rotate;
       rotate.makeRotate(osg::PI_2, osg::Vec3(0,0,1));
       keys1->push_back(osgAnimation::QuatKeyframe(0,osg::Quat(0,0,0,1)));
       keys1->push_back(osgAnimation::QuatKeyframe(3,osg::Quat(0,0,0,1)));
       keys1->push_back(osgAnimation::QuatKeyframe(6,rotate));
osgAnimation::QuatSphericalLinearSampler* sampler = new osgAnimation::QuatSphericalLinearSampler;
       sampler->setKeyframeContainer(keys1);
osgAnimation::QuatSphericalLinearChannel* channel = new osgAnimation::QuatSphericalLinearChannel(sampler); osgAnimation::AnimationUpdateCallback* cb = dynamic_cast<osgAnimation::AnimationUpdateCallback*>(right1->getUpdateCallback());
       cb->setName("right1");
       channel->setName("quaternion");
       channel->setTargetName("right1");
       anim->addChannel(channel);
   }
3 keys for 6 seconds it's what you want isn't it ? and it animate only the quaternion, not the scale and not the position. But the code i know is not very easy to read, some effort will have to be made in this direction.
the format stored is VertexGroup.
For a geometry you have a set of VertexGroup, a vertex group is a list
of 'id of the vertex' and its 'weight'.
The name of vertex group identify the target typically the bone. Using
this format is generic. For example
if you want to extend the mesh, like adding new vertexes, you can add a
group for them and give it the name
to the new bone or other elements that could influence those vertexes.
Then rebuild
the association on the fly. I choiced this format for genericity it's
easier to manipulate, but i know sometime it's less readable in
the osg file.

I am not concerned about readability of the osg files - those files are
intended to be machine readable, not necessarily human readable.
However, the amount of memory and the efficiency of manipulation of the
data is a problem - do realize that a practical scenario can have
2000-3000 characters visible and animated at any given moment. I have
done this with osgCal before and it worked, even with software skinning.

This is a detail, though, but it leads to long lists of vertices that
are duplicated several times, for each bone affecting the vertex. A more
usual way is to have a vertex id followed by a list: bone id weight bone
id weight ... That allows to have the long list only once. A
pathological worst case would be a mesh where every vertex is affected
by all bones. With the current format one would have e.g. 2000 vertices
x 15 bones = 30000 vertex entries. With the format I have mentioned, one
would have only 2000 entries.
It's the same amount of data. it just differents way, you suggest
2000 x 15
and it's currently
15 x 2000
but i am agree your solution produces less lines.

Not really - it makes a difference to have to parse all that and also to
keep that in memory. E.g. if you want to add a new bone that will affect
your vertex group, with my approach I just add a new weight to the
relevant vertices. With yours I need to duplicate the whole list of
vertex IDs and add new weights. The format I am proposing is equally
generic as what you have, but more efficient in practice, IMO. The idea
of vertex groups is really important for the modeler/exporter, but not
at all while you are actually rendering the animation (there you care
just about the weights and bone matrices), so I do not see why to keep
it there.
This format is used as source then depending of the skinning you want software or hardware, there is format generated that fit better for each implementation. Currently there is only software. For software it builds a set of matrix by set of vertex, then after it means only one matrix per vertex. do optimize like that It requires to pre process a little the source vertex group. The format you propose is better for hardware skinning ready to play. But less for software preparation of data. so because i started with software skinning
i did it in this way.
Your format will be also pretty hard to translate to a vertex shader -
there you need for each vertex all the bones and weights that are
affecting it so that you can transform it. However, what you have is a
list of vertices for each bone instead, requiring a costly run-time
conversion.
It's not so costly, and even in cal3d there is process to prepare that for gpu (even if i guess it's less expensive than what i would need to do). It's not new. Because source of my data is less prepared than what you suggest, it will be little harder. Anyway the format can't be adapted for all ready to use case, so yes there will be code that will prepare data for gpu.

You are right, it's not yet here, it's the next thing i plan to do.

OK

Of course it's essential too, it's in the pipe too

OK

- Hardware accelerated skinning - at the moment the skinning seems
to be
done all in software, not using vertex shaders. There is code in osgCal
that does this already. I believe that there was also the osgCharacter
nodekit doing skinning in hardware.
Yes not yet inside osgAnimation. The current software implementation can be
optimized too. But i dont have time to do that right now. I have to
finish some functionnalities
before. If someone wants to help :)

Well, as I said - with your current architecture this will be hard to
do. Look at how Vladimir did it for osgCal (Cal3D does software skinning
only). I know that the GPL version of osgCal had hw skinning as well.
No it will not so hard.
Thank you for the list of remarks, don't hesitate to i would like your
opinion on the sceduler/mixer
i plan to do. I would like to make something like in flash, a timeline
where you can put at any frame
a callback. And when we could compose sequence of animation as timeline
too recursively. It can be confusing
but i have not found a good way to manager animation in time, even with
osgcal it was hard to plan animation in
time, and do introspection when you need.
Example when you click on mouse, you compose a squence of different
animation on a timeline and then you play this timeline.
(sitdown, drink a beer, ...). i mean to manage sequence it look very
interesting. and easy to make introspection like removing the last
animation of squence if an event is catch
...
What do you think ?

I think you should realize what is the goal - making an animation
composer/editor or an engine to actually *play* the animations? What you
have designed is very complex and not needed for replacing osgCal alone.

A simple mixer takes a list of active animations and blends them using
their weights. This is done by calculating the corresponding poses for
all active animations, weighting the resulting bone positions using the
animation weights and summing them. If you want to make it more
sophisticated, you can add code ensuring that the bones actually stay
rigid (i.e. do not stretch or shrink - that is usually unwanted while
mixing).

The animation scheduling what you are asking about is a different issue
and typically not something you need to really bother too much with.
What is important for the higher level code is to be able to know
whether and which animations are active, have a
callback/signal/something to know when an animation has stopped and good
ease-in, ease-out capability, with blending between the finishing
animation and the one starting next. Then it is the responsibility of
the higher level code to sequence the animations.

Pushing this into the low level code is not going to be practical unless
you want to "pre-script" the whole activity, which is rare. A typical
case could be a character walking, sometimes jumping and turning to
avoid obstacles. The obstacle avoidance is driven by the user (e.g.
using cursor keys/mouse to steer it like in a shooter) or by some kind
of AI and will not be deterministic - I cannot make a timeline/schedule
when to schedule a jump or turn. Typically, the user/AI needs to turn
*now* because it has detected an obstacle/incoming bullet/whatever, not
sometime in the future when you have scheduled it.
Ok i listen when you say that what you want is only to manipulate a mixer. I always need to prepare sequence, so i guess it was right for most usage, but ok i understand what
you want.

ReplicantBody is implemented as described above - Cal3D deals with the
low level stuff and Replicant strings the animations together into
actions, including things such as proper walking without sliding and
similar. I think that this division needs to be maintained - you will
not be able to devise a "one size fits all" scheduler that will be
efficient, sufficiently flexible and not a crazily complex monster.

The end-of-animation notification/callback is important for the AI or
animation driver to know when to start a next action - that could be an
animation or something else. This is something Cal3D doesn't have and
one needs to resort to inefficient polling.
Yes
Regards,

Jan
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mandriva - http://enigmail.mozdev.org

iD8DBQFJEsdFn11XseNj94gRAoenAJ9nQCfD4jBEoU2+LRgEtPB2XQqyPgCgsN/+
VqfggL06xVJ5F0rr0eS9Dco=
=20Eq
-----END PGP SIGNATURE-----
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

--
+33 (0) 6 63 20 03 56  Cedric Pinson mailto:[EMAIL PROTECTED] 
http://www.plopbyte.net


_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to