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

Revision 6941, 9.2 kB (checked in by robert, 7 years ago)

From Martin Lavery and Robert Osfield, Updated examples to use a variation of the MIT License

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