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

Revision 10697, 9.9 kB (checked in by robert, 5 years ago)

From Cedric Pinson, updates to osganimation example to keep in sync with changes with osgAnimation, and introduction of a hardware skinning example

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