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

Revision 13574, 8.9 kB (checked in by robert, 12 days ago)

Moved widgets from VolumeEditorWidget? to TransferFunctionWidget?, and widget utilities into WidgetUtils?.

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