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

Revision 13576, 10.7 kB (checked in by robert, 18 hours ago)

Changed the osgUI behaviour so that events are set to be handled by Widgets that have focus even if they don't directly use them.

  • 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.