root/OpenSceneGraph/trunk/examples/osgplanets/osgplanets.cpp @ 3551

Revision 3551, 14.4 kB (checked in by robert, 9 years ago)

Updates for Rainer, and with a few changes by Robert.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <iostream>
2
3#include <osg/Notify>
4#include <osg/MatrixTransform>
5#include <osg/PositionAttitudeTransform>
6#include <osg/Geometry>
7#include <osg/Geode>
8#include <osg/ShapeDrawable>
9#include <osg/Texture2D>
10#include <osg/Material>
11#include <osg/Light>
12#include <osg/LightSource>
13#include <osg/LightModel>
14
15
16#include <osgUtil/Optimizer>
17
18#include <osgDB/Registry>
19#include <osgDB/ReadFile>
20
21#include <osgGA/TrackballManipulator>
22#include <osgGA/FlightManipulator>
23#include <osgGA/DriveManipulator>
24
25#include <osgProducer/Viewer>
26
27
28static osg::Vec3 defaultPos( 0.0f, 0.0f, 0.0f );
29static osg::Vec3 centerScope(0.0f, 0.0f, 0.0f);
30
31
32osg::Group* createSunLight()
33{
34    osg::Group* lightNode = new osg::Group;
35
36    osg::Light* sunLight = new osg::Light;
37    sunLight->setPosition( osg::Vec4( 0.0f, 0.0f, 0.0f, 1.0f ) );
38    sunLight->setAmbient( osg::Vec4( 0.0f, 0.0f, 0.0f, 1.0f ) );
39
40    osg::LightSource* sunLightSource = new osg::LightSource;
41    sunLightSource->setLight( sunLight );
42   
43    lightNode->addChild( sunLightSource );
44   
45    osg::LightModel* lightModel = new osg::LightModel;
46    lightModel->setAmbientIntensity(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
47    lightNode->getOrCreateStateSet()->setAttribute(lightModel);
48
49
50    return lightNode;       
51}// end createSunLight
52
53
54osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime)
55{
56    // set up the animation path
57    osg::AnimationPath* animationPath = new osg::AnimationPath;
58    animationPath->setLoopMode(osg::AnimationPath::LOOP);
59   
60    int numSamples = 40;
61    float yaw = 0.0f;
62    float yaw_delta = 2.0f*osg::PI/((float)numSamples-1.0f);
63    float roll = osg::inDegrees(30.0f);
64   
65    double time=0.0f;
66    double time_delta = looptime/(double)numSamples;
67    for(int i=0;i<numSamples;++i)
68    {
69        osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));
70        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)));
71       
72        animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
73
74        yaw += yaw_delta;
75        time += time_delta;
76
77    }
78    return animationPath;   
79}// end createAnimationPath
80
81
82osg::MatrixTransform* createEarthTranslationAndTilt( double RorbitEarth, double tiltEarth )
83{
84        osg::MatrixTransform* earthPositioned = new osg::MatrixTransform;
85        //earthPositioned->setDataVariance(osg::Object::STATIC);
86        earthPositioned->setMatrix(osg::Matrix::translate(osg::Vec3( 0.0, RorbitEarth, 0.0 ) )*
87                                     osg::Matrix::scale(1.0, 1.0, 1.0)*
88                                     osg::Matrix::rotate(osg::inDegrees( tiltEarth ),0.0f,0.0f,1.0f));
89                                     
90        return earthPositioned;
91}// end createEarthTranslationAndTilt
92
93
94osg::MatrixTransform* createRotation( double orbit, double speed )
95{
96    osg::Vec3 center( 0.0, 0.0, 0.0 );
97    float animationLength = 10.0f;
98    osg::AnimationPath* animationPath = createAnimationPath( center, orbit, animationLength );
99   
100    osg::MatrixTransform* rotation = new osg::MatrixTransform;
101    rotation->setUpdateCallback( new osg::AnimationPathCallback( animationPath, 0.0f, speed ) );
102   
103    return rotation;
104}// end createEarthRotation
105
106
107osg::MatrixTransform* createMoonTranslation( double RorbitMoon )
108{
109    osg::MatrixTransform* moonPositioned = new osg::MatrixTransform;
110    //earthPositioned->setDataVariance(osg::Object::STATIC);
111    //earthPositioned->setMatrix(osg::Matrix::translate(osg::Vec3( RorbitEarth, 0.0, 0.0 ) )*
112    moonPositioned->setMatrix(osg::Matrix::translate(osg::Vec3( 0.0, RorbitMoon, 0.0 ) )*
113    //earthPositioned->setMatrix(osg::Matrix::translate(osg::Vec3( 0.0, 0.0, RorbitEarth ) )*
114                                 osg::Matrix::scale(1.0, 1.0, 1.0)*
115                                 osg::Matrix::rotate(osg::inDegrees(0.0f),0.0f,0.0f,1.0f));
116
117    return moonPositioned;
118}// end createMoonTranslation
119
120
121osg::Geode* createSpace( double radius, const std::string& name, const std::string& textureName )
122{
123    osg::Sphere *spaceSphere = new osg::Sphere( osg::Vec3( 0.0, 0.0, 0.0 ), radius );
124   
125    osg::ShapeDrawable *sSpaceSphere = new osg::ShapeDrawable( spaceSphere );
126   
127    if( !textureName.empty() )
128    {
129        osg::Image* image = osgDB::readImageFile( textureName );
130        if ( image )
131        {
132            sSpaceSphere->getOrCreateStateSet()->setTextureAttributeAndModes( 0, new osg::Texture2D( image ), osg::StateAttribute::ON );
133
134            // reset the object color to white to allow the texture to set the colour.
135            sSpaceSphere->setColor( osg::Vec4(1.0f,1.0f,1.0f,1.0f) );
136        }
137    }
138   
139    osg::Geode* geodeSpace = new osg::Geode();
140    geodeSpace->setName( name );
141   
142    geodeSpace->addDrawable( sSpaceSphere );
143
144    return( geodeSpace );
145   
146}// end createSpace
147
148
149osg::Geode* createPlanet( double radius, const std::string& name, const osg::Vec4& color , const std::string& textureName )
150{
151    // create a cube shape
152    osg::Sphere *planetSphere = new osg::Sphere( osg::Vec3( 0.0, 0.0, 0.0 ), radius );
153
154    // create a container that makes the sphere drawable
155    osg::ShapeDrawable *sPlanetSphere = new osg::ShapeDrawable( planetSphere );
156
157    // set the object color
158    sPlanetSphere->setColor( color );
159
160    if( !textureName.empty() )
161    {
162        osg::Image* image = osgDB::readImageFile( textureName );
163        if ( image )
164        {
165            sPlanetSphere->getOrCreateStateSet()->setTextureAttributeAndModes( 0, new osg::Texture2D( image ), osg::StateAttribute::ON );
166
167            // reset the object color to white to allow the texture to set the colour.
168            sPlanetSphere->setColor( osg::Vec4(1.0f,1.0f,1.0f,1.0f) );
169        }
170    }
171 
172   
173    // create a geode object to as a container for our drawable sphere object
174    osg::Geode* geodePlanet = new osg::Geode();
175    geodePlanet->setName( name );
176   
177    // add our drawable sphere to the geode container
178    geodePlanet->addDrawable( sPlanetSphere );
179
180    return( geodePlanet );
181   
182}// end createPlanet
183
184
185class SolarSystem
186{
187
188public:
189    double _radiusSun;
190    double _radiusEarth;
191    double _RorbitEarth;
192    double _tiltEarth;
193    double _rotateSpeedEarthAndMoon;
194    double _rotateSpeedEarth;
195    double _radiusMoon;
196    double _RorbitMoon;
197    double _rotateSpeedMoon;
198    double _radiusSpace;
199   
200    SolarSystem()
201    {
202        _radiusSun = 5.0;
203        _radiusEarth = 2.0;
204        _RorbitEarth = 10.0;
205        _tiltEarth = 18.0;
206        _rotateSpeedEarthAndMoon = 1.0;
207        _rotateSpeedEarth = 1.0;
208        _radiusMoon = 0.5;
209        _RorbitMoon = 2.0;
210        _rotateSpeedMoon = 1.0;
211        _radiusSpace = 300.0;
212    }
213   
214    osg::Group* built()
215    {
216        osg::Group* thisSystem = new osg::Group;
217       
218        osg::StateSet* sunStateSet = new osg::StateSet;
219        osg::Material* material = new osg::Material;
220        material->setEmission( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 0.0f, 0.0f ) );
221        sunStateSet->setAttributeAndModes( material, osg::StateAttribute::ON );
222       
223       
224       
225        // create the sun
226        osg::Node* sun = createPlanet( _radiusSun, "Sun", osg::Vec4( 0, 0, 0, 1.0f), "" );
227        sun->setStateSet( sunStateSet );
228       
229        // stick sun right under root, no transformations for the sun
230        thisSystem->addChild( sun );
231       
232       
233        // create light source in the sun
234        osg::Group* sunLight = createSunLight();
235       
236        //creating right side of the graph with earth and moon and the rotations above it
237       
238        // create earth and moon
239        osg::Node* earth = createPlanet( _radiusEarth, "Earth", osg::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), "Images/land_shallow_topo_2048.jpg" );
240        osg::Node* moon = createPlanet( _radiusMoon, "Moon", osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), "Images/moon256128.TGA" );
241       
242        // create transformations for the earthMoonGroup
243        osg::MatrixTransform* aroundSunRotation = createRotation( _RorbitEarth, _rotateSpeedEarthAndMoon );
244        osg::MatrixTransform* earthPosition = createEarthTranslationAndTilt( _RorbitEarth, _tiltEarth );
245       
246        //Group with earth and moon under it
247        osg::Group* earthMoonGroup = new osg::Group;
248       
249        //transformation to rotate the earth around itself
250        osg::MatrixTransform* earthRotationAroundItself = createRotation ( 0.0, _rotateSpeedEarth );
251       
252        //transformations for the moon
253        osg::MatrixTransform* moonAroundEarthXform = createRotation( _RorbitMoon, _rotateSpeedMoon );
254        osg::MatrixTransform* moonTranslation = createMoonTranslation( _RorbitMoon );
255       
256       
257        moonTranslation->addChild( moon );
258        moonAroundEarthXform->addChild( moonTranslation );
259        earthMoonGroup->addChild( moonAroundEarthXform );
260       
261        earthRotationAroundItself->addChild( earth );
262        earthMoonGroup->addChild( earthRotationAroundItself );
263       
264       
265        earthPosition->addChild( earthMoonGroup );
266        aroundSunRotation->addChild( earthPosition );
267       
268        sunLight->addChild( aroundSunRotation );
269       
270        thisSystem->addChild( sunLight );
271
272#if 0
273        // add space, but don't light it, as its not illuminated by our sun
274        osg::Node* space = createSpace( _radiusSpace, "Space", "Images/spacemap1.jpg" );
275        space->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
276        thisSystem->addChild( space );
277#endif       
278               
279        return( thisSystem );
280    }
281   
282    void printParameters()
283    {
284        std::cout << "radiusSun\t= " << _radiusSun << std::endl;
285        std::cout << "radiusEarth\t= " << _radiusEarth << std::endl;
286        std::cout << "RorbitEarth\t= " << _RorbitEarth << std::endl;
287        std::cout << "tiltEarth\t= " << _tiltEarth << std::endl;
288        std::cout << "rotateSpeedEarthAndMoon= " << _rotateSpeedEarthAndMoon     << std::endl;
289        std::cout << "rotateSpeedEarth= " << _rotateSpeedEarth << std::endl;
290        std::cout << "radiusMoon\t= " << _radiusMoon << std::endl;
291        std::cout << "RorbitMoon\t= " << _RorbitMoon << std::endl;
292        std::cout << "rotateSpeedMoon\t= " << _rotateSpeedMoon << std::endl;
293        std::cout << "radiusSpace\t= " << _radiusSpace << std::endl;
294       
295    }
296   
297};  // end SolarSystem
298
299
300int main( int argc, char **argv )
301{
302    // use an ArgumentParser object to manage the program arguments.
303    osg::ArgumentParser arguments(&argc,argv);
304
305    // set up the usage document, in case we need to print out how to use this program.
306    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of osg::AnimationPath and UpdateCallbacks for adding animation to your scenes.");
307    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
308    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
309
310    // initialize the viewer.
311    osgProducer::Viewer viewer(arguments);
312
313    // set up the value with sensible default event handlers.
314    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
315
316    // get details on keyboard and mouse bindings used by the viewer.
317    viewer.getUsage(*arguments.getApplicationUsage());
318
319    SolarSystem solarSystem;
320
321    while (arguments.read("--radiusSun",solarSystem._radiusSun)) { }
322    while (arguments.read("--radiusEarth",solarSystem._radiusEarth)) { }
323    while (arguments.read("--RorbitEarth",solarSystem._RorbitEarth)) { }
324    while (arguments.read("--tiltEarth",solarSystem._tiltEarth)) { }
325    while (arguments.read("--rotateSpeedEarthAndMoon",solarSystem._rotateSpeedEarthAndMoon)) { }
326    while (arguments.read("--rotateSpeedEarth",solarSystem._rotateSpeedEarth)) { }
327    while (arguments.read("--radiusMoon",solarSystem._radiusMoon)) { }
328    while (arguments.read("--RorbitMoon",solarSystem._RorbitMoon)) { }
329    while (arguments.read("--rotateSpeedMoon",solarSystem._rotateSpeedMoon)) { }
330    while (arguments.read("--radiusSpace",solarSystem._radiusSpace)) { }
331   
332
333    solarSystem.printParameters();
334
335    // if user request help write it out to cout.
336    if (arguments.read("-h") || arguments.read("--help"))
337    {
338        std::cout << "setup the following arguments: " << std::endl;
339        std::cout << "--radiusSun: double" << std::endl;
340        std::cout << "--radiusEarth: double" << std::endl;
341        std::cout << "--RorbitEarth: double" << std::endl;
342        std::cout << "--tiltEarth: double" << std::endl;
343        std::cout << "--rotateSpeedEarthAndMoon: double" << std::endl;
344        std::cout << "--rotateSpeedEarth: double" << std::endl;
345        std::cout << "--radiusMoon: double" << std::endl;
346        std::cout << "--RorbitMoon: double" << std::endl;
347        std::cout << "--rotateSpeedMoon: double" << std::endl;
348        std::cout << "--radiusSpace: double" << std::endl;
349       
350               
351        return 1;
352    }
353
354    // any option left unread are converted into errors to write out later.
355    arguments.reportRemainingOptionsAsUnrecognized();
356
357    // report any errors if they have occured when parsing the program aguments.
358    if (arguments.errors())
359    {
360        arguments.writeErrorMessages(std::cout);
361        return 1;
362    }
363   
364   
365    osg::Group* root = solarSystem.built();
366       
367    /*
368    // tilt the scene so the default eye position is looking down on the model.
369    osg::MatrixTransform* rootnode = new osg::MatrixTransform;
370    rootnode->setMatrix(osg::Matrix::rotate(osg::inDegrees(30.0f),1.0f,0.0f,0.0f));
371    rootnode->addChild(model);
372    */
373
374    // run optimization over the scene graph
375    osgUtil::Optimizer optimzer;
376    optimzer.optimize( root );
377     
378    // set the scene to render
379    viewer.setSceneData( root );
380
381    // create the windows and run the threads.
382    viewer.realize();
383   
384    osg::Matrix lookAt;
385    lookAt.makeLookAt( osg::Vec3(0.0f, -80.0f, 0.0f), centerScope, osg::Vec3(0.0f, 0.0f, 1.0f ) );
386
387    viewer.setView( lookAt );
388   
389    viewer.setClearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
390
391    while( !viewer.done() )
392    {
393        // wait for all cull and draw threads to complete.
394        viewer.sync();
395
396        // update the scene by traversing it with the the update visitor which will
397        // call all node update callbacks and animations.
398        viewer.update();
399         
400        // fire off the cull and draw traversals of the scene.
401        viewer.frame();
402       
403    }
404   
405    // wait for all cull and draw threads to complete before exit.
406    viewer.sync();
407
408    return 0;
409}
Note: See TracBrowser for help on using the browser.