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

Revision 9370, 9.9 kB (checked in by robert, 6 years ago)

From Cedric Pinson and Jeremey Moles, Changes to OpenSceneGraph-osgWidget-dev branch.

Notes from Robert Osfield, Merged changes to OpenSceneGraph-osgWidget-dev r9367 (prior to my botched attempt at merged svn/trunk into the branch).

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