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

Revision 13576, 10.7 kB (checked in by robert, 2 days ago)

Reordered method implemenations to make it easier to compare similar methods

  • 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, osg::Array::BIND_PER_VERTEX);
57    geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,6));
58
59    geode->addDrawable( geometry );
60    return geode;
61}
62
63osgAnimation::RigGeometry* createTesselatedBox(int nsplit, float size)
64{
65    osgAnimation::RigGeometry* riggeometry = new osgAnimation::RigGeometry;
66
67    osg::Geometry* geometry = new osg::Geometry;
68    osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array());
69    osg::ref_ptr<osg::Vec3Array> colors (new osg::Vec3Array());
70    geometry->setVertexArray (vertices.get());
71    geometry->setColorArray (colors.get(), osg::Array::BIND_PER_VERTEX);
72
73    float step = size / static_cast<float>(nsplit);
74    float s = 0.5f/4.0f;
75    for (int i = 0; i < nsplit; i++)
76    {
77        float x = -1.0f + static_cast<float>(i) * step;
78        std::cout << x << std::endl;
79        vertices->push_back (osg::Vec3 ( x, s, s));
80        vertices->push_back (osg::Vec3 ( x, -s, s));
81        vertices->push_back (osg::Vec3 ( x, -s, -s));
82        vertices->push_back (osg::Vec3 ( x, s, -s));
83        osg::Vec3 c (0.0f,0.0f,0.0f);
84        c[i%3] = 1.0f;
85        colors->push_back (c);
86        colors->push_back (c);
87        colors->push_back (c);
88        colors->push_back (c);
89    }
90
91    osg::ref_ptr<osg::UIntArray> array = new osg::UIntArray;
92    for (int i = 0; i < nsplit - 1; i++)
93    {
94        int base = i * 4;
95        array->push_back(base);
96        array->push_back(base+1);
97        array->push_back(base+4);
98        array->push_back(base+1);
99        array->push_back(base+5);
100        array->push_back(base+4);
101
102        array->push_back(base+3);
103        array->push_back(base);
104        array->push_back(base+4);
105        array->push_back(base+7);
106        array->push_back(base+3);
107        array->push_back(base+4);
108
109        array->push_back(base+5);
110        array->push_back(base+1);
111        array->push_back(base+2);
112        array->push_back(base+2);
113        array->push_back(base+6);
114        array->push_back(base+5);
115
116        array->push_back(base+2);
117        array->push_back(base+3);
118        array->push_back(base+7);
119        array->push_back(base+6);
120        array->push_back(base+2);
121        array->push_back(base+7);
122    }
123
124    geometry->addPrimitiveSet(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, array->size(), &array->front()));
125    geometry->setUseDisplayList( false );
126    riggeometry->setSourceGeometry(geometry);
127    return riggeometry;
128}
129
130
131void initVertexMap(osgAnimation::Bone* b0,
132                   osgAnimation::Bone* b1,
133                   osgAnimation::Bone* b2,
134                   osgAnimation::RigGeometry* geom,
135                   osg::Vec3Array* array)
136{
137    osgAnimation::VertexInfluenceSet vertexesInfluences;
138    osgAnimation::VertexInfluenceMap* vim = new osgAnimation::VertexInfluenceMap;
139
140    (*vim)[b0->getName()].setName(b0->getName());
141    (*vim)[b1->getName()].setName(b1->getName());
142    (*vim)[b2->getName()].setName(b2->getName());
143
144    for (int i = 0; i < (int)array->size(); i++)
145    {
146        float val = (*array)[i][0];
147        std::cout << val << std::endl;
148        if (val >= -1.0f && val <= 0.0f)
149            (*vim)[b0->getName()].push_back(osgAnimation::VertexIndexWeight(i,1.0f));
150        else if ( val > 0.0f && val <= 1.0f)
151            (*vim)[b1->getName()].push_back(osgAnimation::VertexIndexWeight(i,1.0f));
152        else if ( val > 1.0f)
153            (*vim)[b2->getName()].push_back(osgAnimation::VertexIndexWeight(i,1.0f));
154    }
155
156    geom->setInfluenceMap(vim);
157}
158
159
160
161int main (int argc, char* argv[])
162{
163    osg::ArgumentParser arguments(&argc, argv);
164    osgViewer::Viewer viewer(arguments);
165
166    viewer.setCameraManipulator(new osgGA::TrackballManipulator());
167
168    osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton;
169    skelroot->setDefaultUpdateCallback();
170    osg::ref_ptr<osgAnimation::Bone> root = new osgAnimation::Bone;
171    root->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(-1.0,0.0,0.0)));
172    root->setName("root");
173    osgAnimation::UpdateBone* pRootUpdate = new osgAnimation::UpdateBone("root");
174    pRootUpdate->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate",osg::Vec3(-1.0f,0.0f,0.0f)));
175    root->setUpdateCallback(pRootUpdate);
176
177    osg::ref_ptr<osgAnimation::Bone> right0 = new osgAnimation::Bone;
178    right0->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(0.0,0.0,0.0)));
179    right0->setName("right0");
180    osgAnimation::UpdateBone* pRight0Update = new osgAnimation::UpdateBone("right0");
181    pRight0Update->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate", osg::Vec3(1.0f,0.0f,0.0f)));
182    pRight0Update->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement("rotate", osg::Vec3(0.0f,0.0f,1.0f), 0.0));
183    right0->setUpdateCallback(pRight0Update);
184
185    osg::ref_ptr<osgAnimation::Bone> right1 = new osgAnimation::Bone;
186    right1->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(1.0,0.0,0.0)));
187    right1->setName("right1");
188    osgAnimation::UpdateBone* pRight1Update = new osgAnimation::UpdateBone("right1");
189    pRight1Update->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate", osg::Vec3(1.0f,0.0f,0.0f)));
190    pRight1Update->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement("rotate", osg::Vec3(0.0f,0.0f,1.0f), 0.0));
191    right1->setUpdateCallback(pRight1Update);
192
193    root->addChild(right0.get());
194    right0->addChild(right1.get());
195    skelroot->addChild(root.get());
196
197    osg::Group* scene = new osg::Group;
198    osg::ref_ptr<osgAnimation::BasicAnimationManager> manager = new osgAnimation::BasicAnimationManager;
199    scene->setUpdateCallback(manager.get());
200
201    osgAnimation::Animation* anim = new osgAnimation::Animation;
202    {
203        osgAnimation::FloatKeyframeContainer* keys0 = new osgAnimation::FloatKeyframeContainer;
204        keys0->push_back(osgAnimation::FloatKeyframe(0.0,0.0f));
205        keys0->push_back(osgAnimation::FloatKeyframe(3.0,osg::PI_2));
206        keys0->push_back(osgAnimation::FloatKeyframe(6.0,osg::PI_2));
207        osgAnimation::FloatLinearSampler* sampler = new osgAnimation::FloatLinearSampler;
208        sampler->setKeyframeContainer(keys0);
209        osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
210        channel->setName("rotate");
211        channel->setTargetName("right0");
212        anim->addChannel(channel);
213    }
214
215    {
216        osgAnimation::FloatKeyframeContainer* keys1 = new osgAnimation::FloatKeyframeContainer;
217        keys1->push_back(osgAnimation::FloatKeyframe(0.0,0.0f));
218        keys1->push_back(osgAnimation::FloatKeyframe(3.0,0.0f));
219        keys1->push_back(osgAnimation::FloatKeyframe(6.0,osg::PI_2));
220        osgAnimation::FloatLinearSampler* sampler = new osgAnimation::FloatLinearSampler;
221        sampler->setKeyframeContainer(keys1);
222        osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
223        channel->setName("rotate");
224        channel->setTargetName("right1");
225        anim->addChannel(channel);
226    }
227    manager->registerAnimation(anim);
228    manager->buildTargetReference();
229
230    // let's start !
231    manager->playAnimation(anim);
232
233    // we will use local data from the skeleton
234    osg::MatrixTransform* rootTransform = new osg::MatrixTransform;
235    rootTransform->setMatrix(osg::Matrix::rotate(osg::PI_2,osg::Vec3(1.0f,0.0f,0.0f)));
236    right0->addChild(createAxis());
237    right0->setDataVariance(osg::Object::DYNAMIC);
238    right1->addChild(createAxis());
239    right1->setDataVariance(osg::Object::DYNAMIC);
240    osg::MatrixTransform* trueroot = new osg::MatrixTransform;
241    trueroot->setMatrix(osg::Matrix(root->getMatrixInBoneSpace().ptr()));
242    trueroot->addChild(createAxis());
243    trueroot->addChild(skelroot.get());
244    trueroot->setDataVariance(osg::Object::DYNAMIC);
245    rootTransform->addChild(trueroot);
246    scene->addChild(rootTransform);
247
248    osgAnimation::RigGeometry* geom = createTesselatedBox(4, 4.0f);
249    osg::Geode* geode = new osg::Geode;
250    geode->addDrawable(geom);
251    skelroot->addChild(geode);
252    osg::ref_ptr<osg::Vec3Array> src = dynamic_cast<osg::Vec3Array*>(geom->getSourceGeometry()->getVertexArray());
253    geom->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
254    geom->setDataVariance(osg::Object::DYNAMIC);
255
256    initVertexMap(root.get(), right0.get(), right1.get(), geom, src.get());
257
258    // let's run !
259    viewer.setSceneData( scene );
260    viewer.realize();
261
262    while (!viewer.done())
263    {
264        viewer.frame();
265    }
266
267    osgDB::writeNodeFile(*scene, "skinning.osg");
268    return 0;
269}
270
Note: See TracBrowser for help on using the browser.