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

Revision 13574, 8.9 kB (checked in by robert, 17 hours ago)

From Jason Beverage, "It looks like the Callback header got accidentally removed from the CMakeLists.txt in the submission yesterday for the geometry instancing example."

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osganimate.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osg/Notify>
20#include <osg/MatrixTransform>
21#include <osg/PositionAttitudeTransform>
22#include <osg/Geometry>
23#include <osg/Geode>
24
25#include <osgUtil/Optimizer>
26
27#include <osgDB/Registry>
28#include <osgDB/ReadFile>
29
30#include <osgGA/TrackballManipulator>
31#include <osgGA/FlightManipulator>
32#include <osgGA/DriveManipulator>
33
34#include <osgSim/OverlayNode>
35
36#include <osgViewer/Viewer>
37#include <iostream>
38
39osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime)
40{
41    // set up the animation path
42    osg::AnimationPath* animationPath = new osg::AnimationPath;
43    animationPath->setLoopMode(osg::AnimationPath::LOOP);
44
45    int numSamples = 40;
46    float yaw = 0.0f;
47    float yaw_delta = 2.0f*osg::PI/((float)numSamples-1.0f);
48    float roll = osg::inDegrees(30.0f);
49
50    double time=0.0f;
51    double time_delta = looptime/(double)numSamples;
52    for(int i=0;i<numSamples;++i)
53    {
54        osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));
55        osg::Quat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0))*osg::Quat(-(yaw+osg::inDegrees(90.0f)),osg::Vec3(0.0,0.0,1.0)));
56
57        animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
58
59        yaw += yaw_delta;
60        time += time_delta;
61
62    }
63    return animationPath;
64}
65
66osg::Node* createBase(const osg::Vec3& center,float radius)
67{
68
69
70
71    int numTilesX = 10;
72    int numTilesY = 10;
73
74    float width = 2*radius;
75    float height = 2*radius;
76
77    osg::Vec3 v000(center - osg::Vec3(width*0.5f,height*0.5f,0.0f));
78    osg::Vec3 dx(osg::Vec3(width/((float)numTilesX),0.0,0.0f));
79    osg::Vec3 dy(osg::Vec3(0.0f,height/((float)numTilesY),0.0f));
80
81    // fill in vertices for grid, note numTilesX+1 * numTilesY+1...
82    osg::Vec3Array* coords = new osg::Vec3Array;
83    int iy;
84    for(iy=0;iy<=numTilesY;++iy)
85    {
86        for(int ix=0;ix<=numTilesX;++ix)
87        {
88            coords->push_back(v000+dx*(float)ix+dy*(float)iy);
89        }
90    }
91
92    //Just two colours - black and white.
93    osg::Vec4Array* colors = new osg::Vec4Array;
94    colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); // white
95    colors->push_back(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); // black
96
97    osg::ref_ptr<osg::DrawElementsUShort> whitePrimitives = new osg::DrawElementsUShort(GL_QUADS);
98    osg::ref_ptr<osg::DrawElementsUShort> blackPrimitives = new osg::DrawElementsUShort(GL_QUADS);
99
100    int numIndicesPerRow=numTilesX+1;
101    for(iy=0;iy<numTilesY;++iy)
102    {
103        for(int ix=0;ix<numTilesX;++ix)
104        {
105            osg::DrawElementsUShort* primitives = ((iy+ix)%2==0) ? whitePrimitives.get() : blackPrimitives.get();
106            primitives->push_back(ix    +(iy+1)*numIndicesPerRow);
107            primitives->push_back(ix    +iy*numIndicesPerRow);
108            primitives->push_back((ix+1)+iy*numIndicesPerRow);
109            primitives->push_back((ix+1)+(iy+1)*numIndicesPerRow);
110        }
111    }
112
113    // set up a single normal
114    osg::Vec3Array* normals = new osg::Vec3Array;
115    normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
116
117    osg::Geometry* geom = new osg::Geometry;
118    geom->setVertexArray(coords);
119
120    geom->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET);
121
122    geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
123
124    geom->addPrimitiveSet(whitePrimitives.get());
125    geom->addPrimitiveSet(blackPrimitives.get());
126
127    osg::Geode* geode = new osg::Geode;
128    geode->addDrawable(geom);
129
130    return geode;
131}
132
133osg::Node* createMovingModel(const osg::Vec3& center, float radius)
134{
135    float animationLength = 10.0f;
136
137    osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength);
138
139    osg::Group* model = new osg::Group;
140
141    osg::Node* glider = osgDB::readNodeFile("glider.osgt");
142    if (glider)
143    {
144        const osg::BoundingSphere& bs = glider->getBound();
145
146        float size = radius/bs.radius()*0.3f;
147        osg::MatrixTransform* positioned = new osg::MatrixTransform;
148        positioned->setDataVariance(osg::Object::STATIC);
149        positioned->setMatrix(osg::Matrix::translate(-bs.center())*
150                                     osg::Matrix::scale(size,size,size)*
151                                     osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,0.0f,1.0f));
152
153        positioned->addChild(glider);
154
155        osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;
156        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));
157        xform->addChild(positioned);
158
159        model->addChild(xform);
160    }
161
162    osg::Node* cessna = osgDB::readNodeFile("cessna.osgt");
163    if (cessna)
164    {
165        const osg::BoundingSphere& bs = cessna->getBound();
166
167        float size = radius/bs.radius()*0.3f;
168        osg::MatrixTransform* positioned = new osg::MatrixTransform;
169        positioned->setDataVariance(osg::Object::STATIC);
170        positioned->setMatrix(osg::Matrix::translate(-bs.center())*
171                                     osg::Matrix::scale(size,size,size)*
172                                     osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,1.0f));
173
174        positioned->addChild(cessna);
175
176        osg::MatrixTransform* xform = new osg::MatrixTransform;
177        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
178        xform->addChild(positioned);
179
180        model->addChild(xform);
181    }
182
183    return model;
184}
185
186osg::Node* createModel(bool overlay, osgSim::OverlayNode::OverlayTechnique technique)
187{
188    osg::Vec3 center(0.0f,0.0f,0.0f);
189    float radius = 100.0f;
190
191    osg::Group* root = new osg::Group;
192
193    float baseHeight = center.z()-radius*0.5;
194    osg::Node* baseModel = createBase(osg::Vec3(center.x(), center.y(), baseHeight),radius);
195    osg::Node* movingModel = createMovingModel(center,radius*0.8f);
196
197    if (overlay)
198    {
199        osgSim::OverlayNode* overlayNode = new osgSim::OverlayNode(technique);
200        overlayNode->setContinuousUpdate(true);
201        overlayNode->setOverlaySubgraph(movingModel);
202        overlayNode->setOverlayBaseHeight(baseHeight-0.01);
203        overlayNode->addChild(baseModel);
204        root->addChild(overlayNode);
205    }
206    else
207    {
208
209        root->addChild(baseModel);
210    }
211
212    root->addChild(movingModel);
213
214    return root;
215}
216
217
218int main( int argc, char **argv )
219{
220
221    bool overlay = false;
222    osg::ArgumentParser arguments(&argc,argv);
223    while (arguments.read("--overlay")) overlay = true;
224
225    osgSim::OverlayNode::OverlayTechnique technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
226    while (arguments.read("--object")) { technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY; overlay=true; }
227    while (arguments.read("--ortho") || arguments.read("--orthographic")) { technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY; overlay=true; }
228    while (arguments.read("--persp") || arguments.read("--perspective")) { technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY; overlay=true; }
229
230
231    // initialize the viewer.
232    osgViewer::Viewer viewer;
233
234    // load the nodes from the commandline arguments.
235    osg::Node* model = createModel(overlay, technique);
236    if (!model)
237    {
238        return 1;
239    }
240
241    // tilt the scene so the default eye position is looking down on the model.
242    osg::MatrixTransform* rootnode = new osg::MatrixTransform;
243    rootnode->setMatrix(osg::Matrix::rotate(osg::inDegrees(30.0f),1.0f,0.0f,0.0f));
244    rootnode->addChild(model);
245
246    // run optimization over the scene graph
247    osgUtil::Optimizer optimzer;
248    optimzer.optimize(rootnode);
249
250    // set the scene to render
251    viewer.setSceneData(rootnode);
252
253    viewer.setCameraManipulator(new osgGA::TrackballManipulator());
254
255    // viewer.setUpViewOnSingleScreen(1);
256
257#if 0
258
259    // use of custom simulation time.
260
261    viewer.realize();
262
263    double simulationTime = 0.0;
264
265    while (!viewer.done())
266    {
267        viewer.frame(simulationTime);
268        simulationTime += 0.001;
269    }
270
271    return 0;
272#else
273
274    // normal viewer usage.
275    return viewer.run();
276
277#endif
278}
Note: See TracBrowser for help on using the browser.