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

Revision 3532, 11.6 kB (checked in by robert, 9 years ago)

From Rainer, updates to osgplanet.

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