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

Revision 13469, 9.0 kB (checked in by robert, 4 days ago)

Improved support for controlling the ShadingModel? via the VolumeSettings? object

  • 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);
121    geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
122   
123    geom->setNormalArray(normals);
124    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
125   
126    geom->addPrimitiveSet(whitePrimitives.get());
127    geom->addPrimitiveSet(blackPrimitives.get());
128   
129    osg::Geode* geode = new osg::Geode;
130    geode->addDrawable(geom);
131   
132    return geode;
133}
134
135osg::Node* createMovingModel(const osg::Vec3& center, float radius)
136{
137    float animationLength = 10.0f;
138
139    osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength);
140
141    osg::Group* model = new osg::Group;
142
143    osg::Node* glider = osgDB::readNodeFile("glider.osgt");
144    if (glider)
145    {
146        const osg::BoundingSphere& bs = glider->getBound();
147
148        float size = radius/bs.radius()*0.3f;
149        osg::MatrixTransform* positioned = new osg::MatrixTransform;
150        positioned->setDataVariance(osg::Object::STATIC);
151        positioned->setMatrix(osg::Matrix::translate(-bs.center())*
152                                     osg::Matrix::scale(size,size,size)*
153                                     osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,0.0f,1.0f));
154   
155        positioned->addChild(glider);
156   
157        osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;   
158        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));
159        xform->addChild(positioned);
160
161        model->addChild(xform);
162    }
163 
164    osg::Node* cessna = osgDB::readNodeFile("cessna.osgt");
165    if (cessna)
166    {
167        const osg::BoundingSphere& bs = cessna->getBound();
168
169        float size = radius/bs.radius()*0.3f;
170        osg::MatrixTransform* positioned = new osg::MatrixTransform;
171        positioned->setDataVariance(osg::Object::STATIC);
172        positioned->setMatrix(osg::Matrix::translate(-bs.center())*
173                                     osg::Matrix::scale(size,size,size)*
174                                     osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,1.0f));
175   
176        positioned->addChild(cessna);
177   
178        osg::MatrixTransform* xform = new osg::MatrixTransform;
179        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
180        xform->addChild(positioned);
181
182        model->addChild(xform);
183    }
184   
185    return model;
186}
187
188osg::Node* createModel(bool overlay, osgSim::OverlayNode::OverlayTechnique technique)
189{
190    osg::Vec3 center(0.0f,0.0f,0.0f);
191    float radius = 100.0f;
192
193    osg::Group* root = new osg::Group;
194
195    float baseHeight = center.z()-radius*0.5;
196    osg::Node* baseModel = createBase(osg::Vec3(center.x(), center.y(), baseHeight),radius);
197    osg::Node* movingModel = createMovingModel(center,radius*0.8f);
198
199    if (overlay)
200    {
201        osgSim::OverlayNode* overlayNode = new osgSim::OverlayNode(technique);
202        overlayNode->setContinuousUpdate(true);
203        overlayNode->setOverlaySubgraph(movingModel);
204        overlayNode->setOverlayBaseHeight(baseHeight-0.01);
205        overlayNode->addChild(baseModel);
206        root->addChild(overlayNode);
207    }
208    else
209    {
210   
211        root->addChild(baseModel);
212    }
213   
214    root->addChild(movingModel);
215
216    return root;
217}
218
219
220int main( int argc, char **argv )
221{
222   
223    bool overlay = false;
224    osg::ArgumentParser arguments(&argc,argv);
225    while (arguments.read("--overlay")) overlay = true;
226   
227    osgSim::OverlayNode::OverlayTechnique technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
228    while (arguments.read("--object")) { technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY; overlay=true; }
229    while (arguments.read("--ortho") || arguments.read("--orthographic")) { technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY; overlay=true; }
230    while (arguments.read("--persp") || arguments.read("--perspective")) { technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY; overlay=true; }
231   
232
233    // initialize the viewer.
234    osgViewer::Viewer viewer;
235
236    // load the nodes from the commandline arguments.
237    osg::Node* model = createModel(overlay, technique);
238    if (!model)
239    {
240        return 1;
241    }
242   
243    // tilt the scene so the default eye position is looking down on the model.
244    osg::MatrixTransform* rootnode = new osg::MatrixTransform;
245    rootnode->setMatrix(osg::Matrix::rotate(osg::inDegrees(30.0f),1.0f,0.0f,0.0f));
246    rootnode->addChild(model);
247
248    // run optimization over the scene graph
249    osgUtil::Optimizer optimzer;
250    optimzer.optimize(rootnode);
251     
252    // set the scene to render
253    viewer.setSceneData(rootnode);
254
255    viewer.setCameraManipulator(new osgGA::TrackballManipulator());
256
257    // viewer.setUpViewOnSingleScreen(1);
258
259#if 0
260
261    // use of custom simulation time.
262   
263    viewer.realize();
264   
265    double simulationTime = 0.0;
266   
267    while (!viewer.done())
268    {
269        viewer.frame(simulationTime);
270        simulationTime += 0.001;
271    }
272   
273    return 0;
274#else
275
276    // normal viewer usage.
277    return viewer.run();
278
279#endif
280}
Note: See TracBrowser for help on using the browser.