root/OpenSceneGraph/trunk/examples/osganimationskinning/osganimationskinning.cpp @ 11009

Revision 11009, 10.6 kB (checked in by robert, 5 years ago)

From Cedric Pinson, "Here a list of changes:
Bone now inherit from MatrixTransform?. It simplify a lot the update of
Bone matrix. It helps to have the bone system more generic. eg it's now
possible to have animation data with precomputed bind matrix. The other
benefit, is now the collada plugin will be able to use osgAnimation to
display skinned mesh. Michael Plating did a great work to improve this
aspect, he is working on the collada plugin and should be able to submit
a new version soon.
The RigGeometry? has been refactored so now it works when you save and
reload RigGeometry? because the source is not touched anymore. The
benefit with this update is that it should be now possible to use a
MorphGeometry? as source for a RigGeometry?.

The bad news is that the format has changed, so i have rebuild osg-data
related to osgAnimation data, updated the blender exporter to export to
the new format.
The fbx plugin could be touched about this commit, i dont compile it so
i can't give more information about it.
The bvh plugin has been updated by Wang rui so this one is fixed with
the new code of osgAnimation.
The examples has been updated to work with the new code too...

The example osg-data/example.osg should be remove, it's an old example
that does not work.

For people using blender the blender exporter up to date is here:
http://hg.plopbyte.net/osgexport2/
it will be merge to http://hg.plopbyte.net/osgexport/ as soon as the
modification will be push in the trunk.
"

RevLine 
[9097]1/*  -*-c++-*-
[10697]2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
[9097]3 *
4 * This library is open source and may be redistributed and/or modified under 
5 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
6 * (at your option) any later version.  The full license is in LICENSE file
7 * included with this distribution, and on the openscenegraph.org website.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * OpenSceneGraph Public License for more details.
13*/
14
15#include <iostream>
16#include <osg/Geometry>
17#include <osg/MatrixTransform>
18#include <osg/Geode>
19#include <osgViewer/Viewer>
20#include <osgGA/TrackballManipulator>
[11009]21#include <osgDB/WriteFile>
[9097]22#include <osgUtil/SmoothingVisitor>
23#include <osg/io_utils>
24
25#include <osgAnimation/Bone>
26#include <osgAnimation/Skeleton>
27#include <osgAnimation/RigGeometry>
[9370]28#include <osgAnimation/BasicAnimationManager>
[11009]29#include <osgAnimation/UpdateMatrixTransform>
30#include <osgAnimation/UpdateBone>
31#include <osgAnimation/StackedTransform>
32#include <osgAnimation/StackedTranslateElement>
33#include <osgAnimation/StackedRotateAxisElement>
[9097]34
35osg::Geode* createAxis()
36{
37    osg::Geode* geode (new osg::Geode()); 
38    osg::Geometry* geometry (new osg::Geometry());
39
40    osg::Vec3Array* vertices (new osg::Vec3Array());
41    vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
42    vertices->push_back (osg::Vec3 ( 1.0, 0.0, 0.0));
43    vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
44    vertices->push_back (osg::Vec3 ( 0.0, 1.0, 0.0));
45    vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
46    vertices->push_back (osg::Vec3 ( 0.0, 0.0, 1.0));
47    geometry->setVertexArray (vertices);
48
49    osg::Vec4Array* colors (new osg::Vec4Array());
50    colors->push_back (osg::Vec4 (1.0f, 0.0f, 0.0f, 1.0f));
51    colors->push_back (osg::Vec4 (1.0f, 0.0f, 0.0f, 1.0f));
52    colors->push_back (osg::Vec4 (0.0f, 1.0f, 0.0f, 1.0f));
53    colors->push_back (osg::Vec4 (0.0f, 1.0f, 0.0f, 1.0f));
54    colors->push_back (osg::Vec4 (0.0f, 0.0f, 1.0f, 1.0f));
55    colors->push_back (osg::Vec4 (0.0f, 0.0f, 1.0f, 1.0f));
56    geometry->setColorArray (colors);
57
58    geometry->setColorBinding (osg::Geometry::BIND_PER_VERTEX);   
59    geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,6));
60
61    geode->addDrawable( geometry );
62    return geode;
63}
64
65osgAnimation::RigGeometry* createTesselatedBox(int nsplit, float size)
66{
[11009]67    osgAnimation::RigGeometry* riggeometry = new osgAnimation::RigGeometry;
[9097]68
[11009]69    osg::Geometry* geometry = new osg::Geometry;
[9097]70    osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array());
71    osg::ref_ptr<osg::Vec3Array> colors (new osg::Vec3Array());
72    geometry->setVertexArray (vertices.get());
73    geometry->setColorArray (colors.get());
74    geometry->setColorBinding (osg::Geometry::BIND_PER_VERTEX);   
75 
76    float step = size / nsplit;
77    float s = 0.5/4.0;
78    for (int i = 0; i < nsplit; i++)
79    {
80        float x = -1 + i * step;
81        std::cout << x << std::endl;
82        vertices->push_back (osg::Vec3 ( x, s, s));
83        vertices->push_back (osg::Vec3 ( x, -s, s));
84        vertices->push_back (osg::Vec3 ( x, -s, -s));
85        vertices->push_back (osg::Vec3 ( x, s, -s));
86        osg::Vec3 c (0,0,0);
87        c[i%3] = 1;
88        colors->push_back (c);
89        colors->push_back (c);
90        colors->push_back (c);
91        colors->push_back (c);
92    }
93
94    osg::ref_ptr<osg::UIntArray> array = new osg::UIntArray;
95    for (int i = 0; i < nsplit - 1; i++)
96    {
97        int base = i * 4;
98        array->push_back(base);
99        array->push_back(base+1);
100        array->push_back(base+4);
101        array->push_back(base+1);
102        array->push_back(base+5);
103        array->push_back(base+4);
104
105        array->push_back(base+3);
106        array->push_back(base);
107        array->push_back(base+4);
108        array->push_back(base+7);
109        array->push_back(base+3);
110        array->push_back(base+4);
111
112        array->push_back(base+5);
113        array->push_back(base+1);
114        array->push_back(base+2);
115        array->push_back(base+2);
116        array->push_back(base+6);
117        array->push_back(base+5);
118
119        array->push_back(base+2);
120        array->push_back(base+3);
121        array->push_back(base+7);
122        array->push_back(base+6);
123        array->push_back(base+2);
124        array->push_back(base+7);
125    }
126 
127    geometry->addPrimitiveSet(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, array->size(), &array->front()));
128    geometry->setUseDisplayList( false );
[11009]129    riggeometry->setSourceGeometry(geometry);
130    return riggeometry;
[9097]131}
132
133
134void initVertexMap(osgAnimation::Bone* b0,
135                   osgAnimation::Bone* b1,
136                   osgAnimation::Bone* b2,
137                   osgAnimation::RigGeometry* geom,
138                   osg::Vec3Array* array)
139{
140    osgAnimation::VertexInfluenceSet vertexesInfluences;
141    osgAnimation::VertexInfluenceMap* vim = new osgAnimation::VertexInfluenceMap;
142
143    (*vim)[b0->getName()].setName(b0->getName());
144    (*vim)[b1->getName()].setName(b1->getName());
145    (*vim)[b2->getName()].setName(b2->getName());
146
147    for (int i = 0; i < (int)array->size(); i++)
148    {
149        float val = (*array)[i][0];
150        std::cout << val << std::endl;
151        if (val >= -1 && val <= 0)
152            (*vim)[b0->getName()].push_back(osgAnimation::VertexIndexWeight(i,1));
153        else if ( val > 0 && val <= 1)
154            (*vim)[b1->getName()].push_back(osgAnimation::VertexIndexWeight(i,1));
155        else if ( val > 1)
156            (*vim)[b2->getName()].push_back(osgAnimation::VertexIndexWeight(i,1));
157    }
158
159    geom->setInfluenceMap(vim);
160}
161
162
163
164int main (int argc, char* argv[])
165{
[9459]166    osg::ArgumentParser arguments(&argc, argv);
167    osgViewer::Viewer viewer(arguments);
168
[9097]169    viewer.setCameraManipulator(new osgGA::TrackballManipulator());
170
171    osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton;
[9474]172    skelroot->setDefaultUpdateCallback();
[9097]173    osg::ref_ptr<osgAnimation::Bone> root = new osgAnimation::Bone;
[11009]174    root->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(-1,0,0)));
175    root->setName("root");
176    osgAnimation::UpdateBone* pRootUpdate = new osgAnimation::UpdateBone("root");
177    pRootUpdate->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate",osg::Vec3(-1,0,0)));
178    root->setUpdateCallback(pRootUpdate);
[9097]179
180    osg::ref_ptr<osgAnimation::Bone> right0 = new osgAnimation::Bone;
[11009]181    right0->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(0,0,0)));
[9097]182    right0->setName("right0");
[11009]183    osgAnimation::UpdateBone* pRight0Update = new osgAnimation::UpdateBone("right0");
184    pRight0Update->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate", osg::Vec3(1,0,0)));
185    pRight0Update->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement("rotate", osg::Vec3(0,0,1), 0));
186    right0->setUpdateCallback(pRight0Update);
[9097]187
188    osg::ref_ptr<osgAnimation::Bone> right1 = new osgAnimation::Bone;
[11009]189    right1->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(1,0,0)));
[9097]190    right1->setName("right1");
[11009]191    osgAnimation::UpdateBone* pRight1Update = new osgAnimation::UpdateBone("right1");
192    pRight1Update->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate", osg::Vec3(1,0,0)));
193    pRight1Update->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement("rotate", osg::Vec3(0,0,1), 0));
194    right1->setUpdateCallback(pRight1Update);
[9097]195
196    root->addChild(right0.get());
197    right0->addChild(right1.get());
198    skelroot->addChild(root.get());
199
[9370]200    osg::Group* scene = new osg::Group;
201    osg::ref_ptr<osgAnimation::BasicAnimationManager> manager = new osgAnimation::BasicAnimationManager;
202    scene->setUpdateCallback(manager.get());
[9097]203
204    osgAnimation::Animation* anim = new osgAnimation::Animation;
205    {
[11009]206        osgAnimation::FloatKeyframeContainer* keys0 = new osgAnimation::FloatKeyframeContainer;
207        keys0->push_back(osgAnimation::FloatKeyframe(0,0));
208        keys0->push_back(osgAnimation::FloatKeyframe(3,osg::PI_2));
209        keys0->push_back(osgAnimation::FloatKeyframe(6,osg::PI_2));
210        osgAnimation::FloatLinearSampler* sampler = new osgAnimation::FloatLinearSampler;
[9097]211        sampler->setKeyframeContainer(keys0);
[11009]212        osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
213        channel->setName("rotate");
[9097]214        channel->setTargetName("right0");
215        anim->addChannel(channel);
216    }
217
218    {
[11009]219        osgAnimation::FloatKeyframeContainer* keys1 = new osgAnimation::FloatKeyframeContainer;
220        keys1->push_back(osgAnimation::FloatKeyframe(0,0));
221        keys1->push_back(osgAnimation::FloatKeyframe(3,0));
222        keys1->push_back(osgAnimation::FloatKeyframe(6,osg::PI_2));
223        osgAnimation::FloatLinearSampler* sampler = new osgAnimation::FloatLinearSampler;
[9097]224        sampler->setKeyframeContainer(keys1);
[11009]225        osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
226        channel->setName("rotate");
[9097]227        channel->setTargetName("right1");
228        anim->addChannel(channel);
229    }
230    manager->registerAnimation(anim);
231    manager->buildTargetReference();
232 
233    // let's start !
234    manager->playAnimation(anim);
235
236    // we will use local data from the skeleton
237    osg::MatrixTransform* rootTransform = new osg::MatrixTransform;
238    rootTransform->setMatrix(osg::Matrix::rotate(osg::PI_2,osg::Vec3(1,0,0)));
239    right0->addChild(createAxis());
240    right0->setDataVariance(osg::Object::DYNAMIC);
241    right1->addChild(createAxis());
242    right1->setDataVariance(osg::Object::DYNAMIC);
243    osg::MatrixTransform* trueroot = new osg::MatrixTransform;
244    trueroot->setMatrix(osg::Matrix(root->getMatrixInBoneSpace().ptr()));
245    trueroot->addChild(createAxis());
[9531]246    trueroot->addChild(skelroot.get());
[9097]247    trueroot->setDataVariance(osg::Object::DYNAMIC);
[9474]248    rootTransform->addChild(trueroot);
[9097]249    scene->addChild(rootTransform);
250 
251    osgAnimation::RigGeometry* geom = createTesselatedBox(4, 4.0);
252    osg::Geode* geode = new osg::Geode;
253    geode->addDrawable(geom);
254    skelroot->addChild(geode);
[11009]255    osg::ref_ptr<osg::Vec3Array> src = dynamic_cast<osg::Vec3Array*>(geom->getSourceGeometry()->getVertexArray());
[9097]256    geom->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
257    geom->setDataVariance(osg::Object::DYNAMIC);
258
259    initVertexMap(root.get(), right0.get(), right1.get(), geom, src.get());
260
261    // let's run !
262    viewer.setSceneData( scene );
263    viewer.realize();
264
265    while (!viewer.done())
266    {
267        viewer.frame();
268    }
269
[11009]270    osgDB::writeNodeFile(*scene, "skinning.osg");
[9097]271    return 0;
272}
273
Note: See TracBrowser for help on using the browser.