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

Revision 12292, 10.6 kB (checked in by robert, 4 years ago)

Ran svn propset -R svn:eol-style native . on the OpenSceneGraph

  • Property svn:eol-style set to native
Line 
1/*  -*-c++-*-
2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
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>
21#include <osgDB/WriteFile>
22#include <osgUtil/SmoothingVisitor>
23#include <osg/io_utils>
24
25#include <osgAnimation/Bone>
26#include <osgAnimation/Skeleton>
27#include <osgAnimation/RigGeometry>
28#include <osgAnimation/BasicAnimationManager>
29#include <osgAnimation/UpdateMatrixTransform>
30#include <osgAnimation/UpdateBone>
31#include <osgAnimation/StackedTransform>
32#include <osgAnimation/StackedTranslateElement>
33#include <osgAnimation/StackedRotateAxisElement>
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{
67    osgAnimation::RigGeometry* riggeometry = new osgAnimation::RigGeometry;
68
69    osg::Geometry* geometry = new osg::Geometry;
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 );
129    riggeometry->setSourceGeometry(geometry);
130    return riggeometry;
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{
166    osg::ArgumentParser arguments(&argc, argv);
167    osgViewer::Viewer viewer(arguments);
168
169    viewer.setCameraManipulator(new osgGA::TrackballManipulator());
170
171    osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton;
172    skelroot->setDefaultUpdateCallback();
173    osg::ref_ptr<osgAnimation::Bone> root = new osgAnimation::Bone;
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);
179
180    osg::ref_ptr<osgAnimation::Bone> right0 = new osgAnimation::Bone;
181    right0->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(0,0,0)));
182    right0->setName("right0");
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);
187
188    osg::ref_ptr<osgAnimation::Bone> right1 = new osgAnimation::Bone;
189    right1->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(1,0,0)));
190    right1->setName("right1");
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);
195
196    root->addChild(right0.get());
197    right0->addChild(right1.get());
198    skelroot->addChild(root.get());
199
200    osg::Group* scene = new osg::Group;
201    osg::ref_ptr<osgAnimation::BasicAnimationManager> manager = new osgAnimation::BasicAnimationManager;
202    scene->setUpdateCallback(manager.get());
203
204    osgAnimation::Animation* anim = new osgAnimation::Animation;
205    {
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;
211        sampler->setKeyframeContainer(keys0);
212        osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
213        channel->setName("rotate");
214        channel->setTargetName("right0");
215        anim->addChannel(channel);
216    }
217
218    {
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;
224        sampler->setKeyframeContainer(keys1);
225        osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
226        channel->setName("rotate");
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());
246    trueroot->addChild(skelroot.get());
247    trueroot->setDataVariance(osg::Object::DYNAMIC);
248    rootTransform->addChild(trueroot);
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);
255    osg::ref_ptr<osg::Vec3Array> src = dynamic_cast<osg::Vec3Array*>(geom->getSourceGeometry()->getVertexArray());
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
270    osgDB::writeNodeFile(*scene, "skinning.osg");
271    return 0;
272}
273
Note: See TracBrowser for help on using the browser.