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

Revision 5381, 36.6 kB (checked in by robert, 8 years ago)

Added viewer.cleanup_frame() to all examples.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* details about distances and rotation on http://www.solarviews.com/eng/solarsys.htm */
2
3#include <iostream>
4
5#include <osg/Notify>
6#include <osg/MatrixTransform>
7#include <osg/PositionAttitudeTransform>
8#include <osg/Geometry>
9#include <osg/Geode>
10#include <osg/ShapeDrawable>
11#include <osg/Texture2D>
12#include <osg/Material>
13#include <osg/Light>
14#include <osg/LightSource>
15#include <osg/LightModel>
16#include <osg/Billboard>
17#include <osg/LineWidth>
18#include <osg/TexEnv>
19#include <osg/TexEnvCombine>
20#include <osg/ClearNode>
21
22
23#include <osgUtil/Optimizer>
24
25#include <osgDB/Registry>
26#include <osgDB/ReadFile>
27#include <osgDB/WriteFile>
28
29
30#include <osgGA/NodeTrackerManipulator>
31#include <osgGA/TrackballManipulator>
32#include <osgGA/FlightManipulator>
33#include <osgGA/DriveManipulator>
34
35#include <osgProducer/Viewer>
36
37
38static osg::Vec3 defaultPos( 0.0f, 0.0f, 0.0f );
39static osg::Vec3 centerScope(0.0f, 0.0f, 0.0f);
40
41
42/** create quad at specified position. */
43osg::Drawable* createSquare(const osg::Vec3& corner,const osg::Vec3& width,const osg::Vec3& height, osg::Image* image=NULL)
44{
45    // set up the Geometry.
46    osg::Geometry* geom = new osg::Geometry;
47
48    osg::Vec3Array* coords = new osg::Vec3Array(4);
49    (*coords)[0] = corner;
50    (*coords)[1] = corner+width;
51    (*coords)[2] = corner+width+height;
52    (*coords)[3] = corner+height;
53
54
55    geom->setVertexArray(coords);
56
57    osg::Vec3Array* norms = new osg::Vec3Array(1);
58    (*norms)[0] = width^height;
59    (*norms)[0].normalize();
60   
61    geom->setNormalArray(norms);
62    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
63
64    osg::Vec2Array* tcoords = new osg::Vec2Array(4);
65    (*tcoords)[0].set(0.0f,0.0f);
66    (*tcoords)[1].set(1.0f,0.0f);
67    (*tcoords)[2].set(1.0f,1.0f);
68    (*tcoords)[3].set(0.0f,1.0f);
69    geom->setTexCoordArray(0,tcoords);
70   
71    osg::Vec4Array* colours = new osg::Vec4Array(1);
72    (*colours)[0].set(1.0f,1.0f,1.0f,1.0f);
73    geom->setColorArray(colours);
74    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
75
76
77    geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
78   
79    if (image)
80    {
81        osg::StateSet* stateset = new osg::StateSet;
82        osg::Texture2D* texture = new osg::Texture2D;
83        texture->setImage(image);
84        stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
85        stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
86        stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
87        stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
88        geom->setStateSet(stateset);
89    }
90   
91    return geom;
92}
93
94osg::Image* createBillboardImage(const osg::Vec4& centerColour, unsigned int size, float power)
95{
96    osg::Vec4 backgroundColour = centerColour;
97    backgroundColour[3] = 0.0f;
98   
99    osg::Image* image = new osg::Image;
100    image->allocateImage(size,size,1,
101                         GL_RGBA,GL_UNSIGNED_BYTE);
102     
103     
104    float mid = (float(size)-1)*0.5f;
105    float div = 2.0f/float(size);
106    for(unsigned int r=0;r<size;++r)
107    {
108        unsigned char* ptr = image->data(0,r,0);
109        for(unsigned int c=0;c<size;++c)
110        {
111            float dx = (float(c) - mid)*div;
112            float dy = (float(r) - mid)*div;
113            float r = powf(1.0f-sqrtf(dx*dx+dy*dy),power);
114            if (r<0.0f) r=0.0f;
115            osg::Vec4 color = centerColour*r+backgroundColour*(1.0f-r);
116            // color.set(1.0f,1.0f,1.0f,0.5f);
117            *ptr++ = (unsigned char)((color[0])*255.0f);
118            *ptr++ = (unsigned char)((color[1])*255.0f);
119            *ptr++ = (unsigned char)((color[2])*255.0f);
120            *ptr++ = (unsigned char)((color[3])*255.0f);
121        }
122    }
123    return image;
124
125    //return osgDB::readImageFile("spot.dds");
126}
127
128osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime)
129{
130    // set up the animation path
131    osg::AnimationPath* animationPath = new osg::AnimationPath;
132    animationPath->setLoopMode(osg::AnimationPath::LOOP);
133   
134    int numSamples = 1000;
135    float yaw = 0.0f;
136    float yaw_delta = -2.0f*osg::PI/((float)numSamples-1.0f);
137    float roll = osg::inDegrees(30.0f);
138   
139    double time=0.0f;
140    double time_delta = looptime/(double)numSamples;
141    for(int i=0;i<numSamples;++i)
142    {
143        osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));
144        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)));
145       
146        animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
147
148        yaw += yaw_delta;
149        time += time_delta;
150
151    }
152    return animationPath;   
153}// end createAnimationPath
154
155
156class SolarSystem
157{
158
159public:
160    double _radiusSpace;
161    double _radiusSun;
162    double _radiusMercury;
163    double _radiusVenus;
164    double _radiusEarth;
165    double _radiusMoon;
166    double _radiusMars;
167    double _radiusJupiter;
168
169    double _RorbitMercury;
170    double _RorbitVenus;
171    double _RorbitEarth;
172    double _RorbitMoon;
173    double _RorbitMars;
174    double _RorbitJupiter;
175
176    double _rotateSpeedSun;
177    double _rotateSpeedMercury;
178    double _rotateSpeedVenus;
179    double _rotateSpeedEarthAndMoon;
180    double _rotateSpeedEarth;
181    double _rotateSpeedMoon;
182    double _rotateSpeedMars;
183    double _rotateSpeedJupiter;
184
185    double _tiltEarth;
186
187    std::string _mapSpace;
188    std::string _mapSun;
189    std::string _mapVenus;   
190    std::string _mapMercury;   
191    std::string _mapEarth;
192    std::string _mapEarthNight;
193    std::string _mapMoon;
194    std::string _mapMars;
195    std::string _mapJupiter;
196   
197    double _rotateSpeedFactor;
198    double _RorbitFactor;
199    double _radiusFactor;
200   
201    SolarSystem()
202    {
203        _radiusSpace    = 500.0;
204        _radiusSun      = 109.0;
205        _radiusMercury  = 0.38;
206        _radiusVenus    = 0.95;
207        _radiusEarth    = 1.0;
208        _radiusMoon     = 0.1;
209        _radiusMars     = 0.53;
210        _radiusJupiter  = 5.0;
211       
212        _RorbitMercury  = 11.7;
213        _RorbitVenus    = 21.6;
214        _RorbitEarth    = 30.0;
215        _RorbitMoon     = 1.0;
216        _RorbitMars     = 45.0;
217        _RorbitJupiter  = 156.0;
218       
219                                                // orbital period in days
220        _rotateSpeedSun             = 0.0;      // should be 11.97;  // 30.5 average
221        _rotateSpeedMercury         = 4.15;     // 87.96
222        _rotateSpeedVenus           = 1.62;     // 224.70
223        _rotateSpeedEarthAndMoon    = 1.0;      // 365.25
224        _rotateSpeedEarth           = 1.0;      //
225        _rotateSpeedMoon            = 0.95;     //
226        _rotateSpeedMars            = 0.53;     // 686.98
227        _rotateSpeedJupiter         = 0.08;     // 4332.71
228
229        _tiltEarth                  = 23.45; // degrees
230       
231        _mapSpace       = "Images/spacemap2.jpg";
232        _mapSun         = "SolarSystem/sun256128.jpg";
233        _mapMercury     = "SolarSystem/mercury256128.jpg";
234        _mapVenus       = "SolarSystem/venus256128.jpg";
235        _mapEarth       = "Images/land_shallow_topo_2048.jpg";
236        _mapEarthNight  = "Images/land_ocean_ice_lights_2048.jpg";
237        _mapMoon        = "SolarSystem/moon256128.jpg";
238        _mapMars        = "SolarSystem/mars256128.jpg";
239        _mapJupiter     = "SolarSystem/jupiter256128.jpg";
240
241        _rotateSpeedFactor = 0.5;
242        _RorbitFactor   = 15.0;
243        _radiusFactor   = 10.0;
244    }
245   
246    osg::MatrixTransform* createTranslationAndTilt( double translation, double tilt );
247    osg::MatrixTransform* createRotation( double orbit, double speed );
248   
249    osg::Geode* createSpace( const std::string& name, const std::string& textureName );
250    osg::Geode* createPlanet( double radius, const std::string& name, const osg::Vec4& color , const std::string& textureName );
251    osg::Geode* createPlanet( double radius, const std::string& name, const osg::Vec4& color , const std::string& textureName1, const std::string& textureName2);
252    osg::Group* createSunLight();
253   
254    void rotateSpeedCorrection()
255    {
256        _rotateSpeedSun             *= _rotateSpeedFactor;
257        _rotateSpeedMercury         *= _rotateSpeedFactor;
258        _rotateSpeedVenus           *= _rotateSpeedFactor;
259        _rotateSpeedEarthAndMoon    *= _rotateSpeedFactor;
260        _rotateSpeedEarth           *= _rotateSpeedFactor;
261        _rotateSpeedMoon            *= _rotateSpeedFactor;
262        _rotateSpeedMars            *= _rotateSpeedFactor;
263        _rotateSpeedJupiter         *= _rotateSpeedFactor;
264       
265        std::cout << "rotateSpeed corrected by factor " << _rotateSpeedFactor << std::endl;
266    }
267   
268    void RorbitCorrection()
269    {
270        _RorbitMercury  *= _RorbitFactor;
271        _RorbitVenus    *= _RorbitFactor;
272        _RorbitEarth    *= _RorbitFactor;
273        _RorbitMoon     *= _RorbitFactor;
274        _RorbitMars     *= _RorbitFactor;
275        _RorbitJupiter  *= _RorbitFactor;
276       
277        std::cout << "Rorbits corrected by factor " << _RorbitFactor << std::endl;
278    }
279   
280    void radiusCorrection()
281    {
282        _radiusSpace    *= _radiusFactor;
283        //_radiusSun      *= _radiusFactor;
284        _radiusMercury  *= _radiusFactor;
285        _radiusVenus    *= _radiusFactor;
286        _radiusEarth    *= _radiusFactor;
287        _radiusMoon     *= _radiusFactor;
288        _radiusMars     *= _radiusFactor;
289        _radiusJupiter  *= _radiusFactor;
290 
291        std::cout << "Radius corrected by factor " << _radiusFactor << std::endl;
292    }
293    void printParameters();
294       
295};  // end SolarSystem
296
297class FindNamedNodeVisitor : public osg::NodeVisitor
298{
299public:
300    FindNamedNodeVisitor(const std::string& name):
301        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
302        _name(name) {}
303   
304    virtual void apply(osg::Node& node)
305    {
306        if (node.getName()==_name)
307        {
308            _foundNodes.push_back(&node);
309        }
310        traverse(node);
311    }
312   
313    typedef std::vector< osg::ref_ptr<osg::Node> > NodeList;
314
315    std::string _name;
316    NodeList _foundNodes;
317};
318
319
320osg::MatrixTransform* SolarSystem::createRotation( double orbit, double speed )
321{
322    osg::Vec3 center( 0.0, 0.0, 0.0 );
323    float animationLength = 10.0f;
324    osg::AnimationPath* animationPath = createAnimationPath( center, orbit, animationLength );
325
326    osg::MatrixTransform* rotation = new osg::MatrixTransform;
327    rotation->setUpdateCallback( new osg::AnimationPathCallback( animationPath, 0.0f, speed ) );
328
329    return rotation;
330}// end SolarSystem::createEarthRotation
331
332
333osg::MatrixTransform* SolarSystem::createTranslationAndTilt( double /*translation*/, double tilt )
334{
335    osg::MatrixTransform* moonPositioned = new osg::MatrixTransform;
336    moonPositioned->setMatrix(osg::Matrix::translate(osg::Vec3( 0.0, _RorbitMoon, 0.0 ) )*
337                                 osg::Matrix::scale(1.0, 1.0, 1.0)*
338                                 osg::Matrix::rotate(osg::inDegrees( tilt ),0.0f,0.0f,1.0f));
339
340    return moonPositioned;
341}// end SolarSystem::createTranslationAndTilt
342   
343   
344osg::Geode* SolarSystem::createSpace( const std::string& name, const std::string& textureName )
345{
346    osg::Sphere *spaceSphere = new osg::Sphere( osg::Vec3( 0.0, 0.0, 0.0 ), _radiusSpace );
347
348    osg::ShapeDrawable *sSpaceSphere = new osg::ShapeDrawable( spaceSphere );
349
350    if( !textureName.empty() )
351    {
352        osg::Image* image = osgDB::readImageFile( textureName );
353        if ( image )
354        {
355            sSpaceSphere->getOrCreateStateSet()->setTextureAttributeAndModes( 0, new osg::Texture2D( image ), osg::StateAttribute::ON );
356
357            // reset the object color to white to allow the texture to set the colour.
358            sSpaceSphere->setColor( osg::Vec4(1.0f,1.0f,1.0f,1.0f) );
359        }
360    }
361
362    osg::Geode* geodeSpace = new osg::Geode();
363    geodeSpace->setName( name );
364
365    geodeSpace->addDrawable( sSpaceSphere );
366
367    return( geodeSpace );
368
369}// end SolarSystem::createSpace
370
371   
372osg::Geode* SolarSystem::createPlanet( double radius, const std::string& name, const osg::Vec4& color , const std::string& textureName)
373{
374    // create a container that makes the sphere drawable
375    osg::Geometry *sPlanetSphere = new osg::Geometry();
376
377    {
378        // set the single colour so bind overall
379        osg::Vec4Array* colours = new osg::Vec4Array(1);
380        (*colours)[0] = color;
381        sPlanetSphere->setColorArray(colours);
382        sPlanetSphere->setColorBinding(osg::Geometry::BIND_OVERALL);
383
384
385        // now set up the coords, normals and texcoords for geometry
386        unsigned int numX = 100;
387        unsigned int numY = 50;
388        unsigned int numVertices = numX*numY;
389
390        osg::Vec3Array* coords = new osg::Vec3Array(numVertices);
391        sPlanetSphere->setVertexArray(coords);
392
393        osg::Vec3Array* normals = new osg::Vec3Array(numVertices);
394        sPlanetSphere->setNormalArray(normals);
395        sPlanetSphere->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
396
397        osg::Vec2Array* texcoords = new osg::Vec2Array(numVertices);
398        sPlanetSphere->setTexCoordArray(0,texcoords);
399        sPlanetSphere->setTexCoordArray(1,texcoords);
400
401        double delta_elevation = osg::PI / (double)(numY-1);
402        double delta_azim = 2.0*osg::PI / (double)(numX-1);
403        float delta_tx = 1.0 / (float)(numX-1);
404        float delta_ty = 1.0 / (float)(numY-1);
405
406        double elevation = -osg::PI*0.5;
407        float ty = 0.0;
408        unsigned int vert = 0;
409        unsigned j;
410        for(j=0;
411            j<numY;
412            ++j, elevation+=delta_elevation, ty+=delta_ty )
413        {
414            double azim = 0.0;
415            float tx = 0.0;
416            for(unsigned int i=0;
417                i<numX;
418                ++i, ++vert, azim+=delta_azim, tx+=delta_tx)
419            {
420                osg::Vec3 direction(cos(azim)*cos(elevation), sin(azim)*cos(elevation), sin(elevation));
421                (*coords)[vert].set(direction*radius);
422                (*normals)[vert].set(direction);
423                (*texcoords)[vert].set(tx,ty);
424            }
425        }
426
427        for(j=0;
428            j<numY-1;
429            ++j)
430        {
431            unsigned int curr_row = j*numX;
432            unsigned int next_row = curr_row+numX;
433            osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
434            for(unsigned int i=0;
435                i<numX;
436                ++i)
437            {
438                elements->push_back(next_row + i);
439                elements->push_back(curr_row + i);
440            }
441            sPlanetSphere->addPrimitiveSet(elements);
442        }
443    }
444   
445
446    // set the object color
447    //sPlanetSphere->setColor( color );
448
449    // create a geode object to as a container for our drawable sphere object
450    osg::Geode* geodePlanet = new osg::Geode();
451    geodePlanet->setName( name );
452
453    if( !textureName.empty() )
454    {
455        osg::Image* image = osgDB::readImageFile( textureName );
456        if ( image )
457        {
458            osg::Texture2D* tex2d = new osg::Texture2D( image );
459            tex2d->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
460            tex2d->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
461            geodePlanet->getOrCreateStateSet()->setTextureAttributeAndModes( 0, tex2d, osg::StateAttribute::ON );
462
463            // reset the object color to white to allow the texture to set the colour.
464            //sPlanetSphere->setColor( osg::Vec4(1.0f,1.0f,1.0f,1.0f) );
465        }
466    }
467
468    // add our drawable sphere to the geode container
469    geodePlanet->addDrawable( sPlanetSphere );
470
471    return( geodePlanet );
472
473}// end SolarSystem::createPlanet
474   
475osg::Geode* SolarSystem::createPlanet( double radius, const std::string& name, const osg::Vec4& color , const std::string& textureName1, const std::string& textureName2)
476{
477    osg::Geode* geodePlanet = createPlanet( radius, name, color , textureName1);
478   
479    if( !textureName2.empty() )
480    {
481        osg::Image* image = osgDB::readImageFile( textureName2 );
482        if ( image )
483        {
484            osg::StateSet* stateset = geodePlanet->getOrCreateStateSet();
485           
486            osg::TexEnvCombine* texenv = new osg::TexEnvCombine;
487           
488            texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
489            texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
490            texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
491            texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE);
492            texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
493            texenv->setSource2_RGB(osg::TexEnvCombine::PRIMARY_COLOR);
494            texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR);
495
496            stateset->setTextureAttribute( 1, texenv );
497            osg::Texture2D* tex2d = new osg::Texture2D( image );
498            tex2d->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
499            tex2d->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
500            stateset->setTextureAttributeAndModes( 1, tex2d, osg::StateAttribute::ON );
501        }
502    }
503
504    return( geodePlanet );
505
506}// end SolarSystem::createPlanet
507
508osg::Group* SolarSystem::createSunLight()
509{
510
511    osg::LightSource* sunLightSource = new osg::LightSource;
512
513    osg::Light* sunLight = sunLightSource->getLight();
514    sunLight->setPosition( osg::Vec4( 0.0f, 0.0f, 0.0f, 1.0f ) );
515    sunLight->setAmbient( osg::Vec4( 0.0f, 0.0f, 0.0f, 1.0f ) );
516
517    sunLightSource->setLight( sunLight );
518    sunLightSource->setLocalStateSetModes( osg::StateAttribute::ON );
519    sunLightSource->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);
520
521    osg::LightModel* lightModel = new osg::LightModel;
522    lightModel->setAmbientIntensity(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
523    sunLightSource->getOrCreateStateSet()->setAttribute(lightModel);
524
525
526    return sunLightSource;
527}// end SolarSystem::createSunLight
528   
529void SolarSystem::printParameters()
530{
531    std::cout << "radiusSpace(" << _radiusSpace << ")" << std::endl;
532    std::cout << "radiusSun(" << _radiusSun << ")" << std::endl;
533    std::cout << "radiusMercury(" << _radiusMercury << ")" << std::endl;
534    std::cout << "radiusVenus(" << _radiusVenus << ")" << std::endl;
535    std::cout << "radiusEarth(" << _radiusEarth << ")" << std::endl;
536    std::cout << "radiusMoon(" << _radiusMoon << ")" << std::endl;
537    std::cout << "radiusMars(" << _radiusMars << ")" << std::endl;
538    std::cout << "radiusJupiter(" << _radiusJupiter << ")" << std::endl;
539
540    std::cout << "RorbitMercury(" << _RorbitMercury << ")" << std::endl;
541    std::cout << "RorbitVenus(" << _RorbitVenus << ")" << std::endl;
542    std::cout << "RorbitEarth(" << _RorbitEarth << ")" << std::endl;
543    std::cout << "RorbitMoon(" << _RorbitMoon << ")" << std::endl;
544    std::cout << "RorbitMars(" << _RorbitMars << ")" << std::endl;
545    std::cout << "RorbitJupiter(" << _RorbitJupiter << ")" << std::endl;
546
547    std::cout << "rotateSpeedMercury(" << _rotateSpeedMercury << ")" << std::endl;
548    std::cout << "rotateSpeedVenus(" << _rotateSpeedVenus << ")" << std::endl;
549    std::cout << "rotateSpeedEarthAndMoon(" << _rotateSpeedEarthAndMoon << ")" << std::endl;
550    std::cout << "rotateSpeedEarth(" << _rotateSpeedEarth << ")" << std::endl;
551    std::cout << "rotateSpeedMoon(" << _rotateSpeedMoon << ")" << std::endl;
552    std::cout << "rotateSpeedMars(" << _rotateSpeedMars << ")" << std::endl;
553    std::cout << "rotateSpeedJupiter(" << _rotateSpeedJupiter << ")" << std::endl;
554
555    std::cout << "tiltEarth(" << _tiltEarth << ")" << std::endl;
556
557    std::cout << "mapSpace(" << _mapSpace << ")" << std::endl;
558    std::cout << "mapSun(" << _mapSun << ")" << std::endl;
559    std::cout << "mapMercury(" << _mapMercury << ")" << std::endl;
560    std::cout << "mapVenus(" << _mapVenus << ")" << std::endl;
561    std::cout << "mapEarth(" << _mapEarth << ")" << std::endl;
562    std::cout << "mapEarthNight(" << _mapEarthNight << ")" << std::endl;
563    std::cout << "mapMoon(" << _mapMoon << ")" << std::endl;
564    std::cout << "mapMars(" << _mapMars << ")" << std::endl;
565    std::cout << "mapJupiter(" << _mapJupiter << ")" << std::endl;
566   
567    std::cout << "rotateSpeedFactor(" << _rotateSpeedFactor << ")" << std::endl;
568    std::cout << "RorbitFactor(" << _RorbitFactor << ")" << std::endl;
569    std::cout << "radiusFactor(" << _radiusFactor << ")" << std::endl;
570}
571
572
573int main( int argc, char **argv )
574{
575    // use an ArgumentParser object to manage the program arguments.
576    osg::ArgumentParser arguments(&argc,argv);
577
578    // set up the usage document, in case we need to print out how to use this program.
579    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of osg::AnimationPath and UpdateCallbacks for adding animation to your scenes.");
580    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
581    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
582    arguments.getApplicationUsage()->addCommandLineOption("-o <filename>","Write created model to file");
583
584    // initialize the viewer.
585    osgProducer::Viewer viewer(arguments);
586
587    // set up the value with sensible default event handlers.
588    viewer.setUpViewer(osgProducer::Viewer::ESCAPE_SETS_DONE | osgProducer::Viewer::VIEWER_MANIPULATOR | osgProducer::Viewer::STATE_MANIPULATOR);
589
590    // get details on keyboard and mouse bindings used by the viewer.
591    viewer.getUsage(*arguments.getApplicationUsage());
592
593    SolarSystem solarSystem;
594
595    while (arguments.read("--radiusSpace",solarSystem._radiusSpace)) { }
596    while (arguments.read("--radiusSun",solarSystem._radiusSun)) { }
597    while (arguments.read("--radiusMercury",solarSystem._radiusMercury)) { }
598    while (arguments.read("--radiusVenus",solarSystem._radiusVenus)) { }
599    while (arguments.read("--radiusEarth",solarSystem._radiusEarth)) { }
600    while (arguments.read("--radiusMoon",solarSystem._radiusMoon)) { }
601    while (arguments.read("--radiusMars",solarSystem._radiusMars)) { }
602    while (arguments.read("--radiusJupiter",solarSystem._radiusJupiter)) { }
603   
604    while (arguments.read("--RorbitEarth",solarSystem._RorbitEarth)) { }
605    while (arguments.read("--RorbitMoon",solarSystem._RorbitMoon)) { }
606   
607    while (arguments.read("--rotateSpeedEarthAndMoon",solarSystem._rotateSpeedEarthAndMoon)) { }
608    while (arguments.read("--rotateSpeedEarth",solarSystem._rotateSpeedEarth)) { }
609    while (arguments.read("--rotateSpeedMoon",solarSystem._rotateSpeedMoon)) { }
610    while (arguments.read("--tiltEarth",solarSystem._tiltEarth)) { }
611   
612    while (arguments.read("--mapSpace",solarSystem._mapSpace)) { }
613    while (arguments.read("--mapEarth",solarSystem._mapEarth)) { }
614    while (arguments.read("--mapEarthNight",solarSystem._mapEarthNight)) { }
615    while (arguments.read("--mapMoon",solarSystem._mapMoon)) { }
616
617    while (arguments.read("--rotateSpeedFactor",solarSystem._rotateSpeedFactor)) { }
618    while (arguments.read("--RorbitFactor",solarSystem._RorbitFactor)) { }
619    while (arguments.read("--radiusFactor",solarSystem._radiusFactor)) { }
620   
621    solarSystem.rotateSpeedCorrection();
622    solarSystem.RorbitCorrection();
623    solarSystem.radiusCorrection();
624   
625    std::string writeFileName;
626    while (arguments.read("-o",writeFileName)) { }
627   
628   
629    osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
630    std::string mode;
631    while (arguments.read("--tracker-mode",mode))
632    {
633        if (mode=="NODE_CENTER_AND_ROTATION") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
634        else if (mode=="NODE_CENTER_AND_AZIM") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_AZIM;
635        else if (mode=="NODE_CENTER") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
636        else
637        {
638            std::cout<<"Unrecognized --tracker-mode option "<<mode<<", valid options are:"<<std::endl;
639            std::cout<<"    NODE_CENTER_AND_ROTATION"<<std::endl;
640            std::cout<<"    NODE_CENTER_AND_AZIM"<<std::endl;
641            std::cout<<"    NODE_CENTER"<<std::endl;
642            return 1;
643        }
644    }
645   
646   
647    osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::TRACKBALL;
648    while (arguments.read("--rotation-mode",mode))
649    {
650        if (mode=="TRACKBALL") rotationMode = osgGA::NodeTrackerManipulator::TRACKBALL;
651        else if (mode=="ELEVATION_AZIM") rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
652        else
653        {
654            std::cout<<"Unrecognized --rotation-mode option "<<mode<<", valid options are:"<<std::endl;
655            std::cout<<"    TRACKBALL"<<std::endl;
656            std::cout<<"    ELEVATION_AZIM"<<std::endl;
657            return 1;
658        }
659    }
660   
661
662    // solarSystem.printParameters();
663
664    // if user request help write it out to cout.
665    if (arguments.read("-h") || arguments.read("--help"))
666    {
667        std::cout << "setup the following arguments: " << std::endl;
668        std::cout << "\t--radiusSpace: double" << std::endl;
669        std::cout << "\t--radiusSun: double" << std::endl;
670        std::cout << "\t--radiusMercury: double" << std::endl;
671        std::cout << "\t--radiusVenus: double" << std::endl;
672        std::cout << "\t--radiusEarth: double" << std::endl;
673        std::cout << "\t--radiusMoon: double" << std::endl;
674        std::cout << "\t--radiusMars: double" << std::endl;
675        std::cout << "\t--radiusJupiter: double" << std::endl;
676       
677        std::cout << "\t--RorbitMercury: double" << std::endl;
678        std::cout << "\t--RorbitVenus: double" << std::endl;
679        std::cout << "\t--RorbitEarth: double" << std::endl;
680        std::cout << "\t--RorbitMoon: double" << std::endl;
681        std::cout << "\t--RorbitMars: double" << std::endl;
682        std::cout << "\t--RorbitJupiter: double" << std::endl;
683       
684        std::cout << "\t--rotateSpeedMercury: double" << std::endl;
685        std::cout << "\t--rotateSpeedVenus: double" << std::endl;
686        std::cout << "\t--rotateSpeedEarthAndMoon: double" << std::endl;
687        std::cout << "\t--rotateSpeedEarth: double" << std::endl;
688        std::cout << "\t--rotateSpeedMoon: double" << std::endl;
689        std::cout << "\t--rotateSpeedMars: double" << std::endl;
690        std::cout << "\t--rotateSpeedJupiter: double" << std::endl;
691
692        std::cout << "\t--tiltEarth: double" << std::endl;
693       
694        std::cout << "\t--mapSpace: string" << std::endl;
695        std::cout << "\t--mapSun: string" << std::endl;
696        std::cout << "\t--mapMercury: string" << std::endl;
697        std::cout << "\t--mapVenus: string" << std::endl;
698        std::cout << "\t--mapEarth: string" << std::endl;
699        std::cout << "\t--mapEarthNight: string" << std::endl;
700        std::cout << "\t--mapMoon: string" << std::endl;
701        std::cout << "\t--mapMars: string" << std::endl;
702        std::cout << "\t--mapJupiter: string" << std::endl;
703       
704        std::cout << "\t--rotateSpeedFactor: string" << std::endl;
705        std::cout << "\t--RorbitFactor: string" << std::endl;
706        std::cout << "\t--radiusFactor: string" << std::endl;
707                       
708        return 1;
709    }
710
711    // any option left unread are converted into errors to write out later.
712    arguments.reportRemainingOptionsAsUnrecognized();
713
714    // report any errors if they have occured when parsing the program aguments.
715    if (arguments.errors())
716    {
717        arguments.writeErrorMessages(std::cout);
718        return 1;
719    }
720   
721   
722    osg::Group* root = new osg::Group;
723   
724    osg::ClearNode* clearNode = new osg::ClearNode;
725    clearNode->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
726    root->addChild(clearNode);
727
728    osg::Group* sunLight = solarSystem.createSunLight();
729    root->addChild(sunLight);
730
731    // create the sun
732    osg::Node* solarSun = solarSystem.createPlanet( solarSystem._radiusSun, "Sun", osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), solarSystem._mapSun );
733    osg::StateSet* sunStateSet = solarSun->getOrCreateStateSet();
734    osg::Material* material = new osg::Material;
735    material->setEmission( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 0.0f, 0.0f ) );
736    sunStateSet->setAttributeAndModes( material, osg::StateAttribute::ON );
737
738    osg::Billboard* sunBillboard = new osg::Billboard();
739    sunBillboard->setMode(osg::Billboard::POINT_ROT_EYE);
740    sunBillboard->addDrawable(
741        createSquare(osg::Vec3(-150.0f,0.0f,-150.0f),osg::Vec3(300.0f,0.0f,0.0f),osg::Vec3(0.0f,0.0f,300.0f),createBillboardImage( osg::Vec4( 1.0, 1.0, 0, 1.0f), 64, 1.0) ),
742        osg::Vec3(0.0f,0.0f,0.0f));
743       
744    sunLight->addChild( sunBillboard );
745
746
747    // stick sun right under root, no transformations for the sun
748    sunLight->addChild( solarSun );
749
750    // create light source in the sun
751
752/*
753*********************************************
754**  earthMoonGroup and Transformations
755*********************************************
756*/
757    // create earth and moon
758    osg::Node* earth = solarSystem.createPlanet( solarSystem._radiusEarth, "Earth", osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), solarSystem._mapEarth, solarSystem._mapEarthNight );
759    osg::Node* moon = solarSystem.createPlanet( solarSystem._radiusMoon, "Moon", osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), solarSystem._mapMoon );
760
761    // create transformations for the earthMoonGroup
762    osg::MatrixTransform* aroundSunRotationEarthMoonGroup = solarSystem.createRotation( solarSystem._RorbitEarth, solarSystem._rotateSpeedEarthAndMoon );
763//    osg::MatrixTransform* earthMoonGroupPosition = solarSystem.createTranslationAndTilt( solarSystem._RorbitEarth, solarSystem._tiltEarth );
764    osg::MatrixTransform* earthMoonGroupPosition = solarSystem.createTranslationAndTilt( solarSystem._RorbitEarth, 0.0 );
765
766
767    //Group with earth and moon under it
768    osg::Group* earthMoonGroup = new osg::Group;
769   
770    //transformation to rotate the earth around itself
771    osg::MatrixTransform* earthAroundItselfRotation = solarSystem.createRotation ( 0.0, solarSystem._rotateSpeedEarth );
772
773    //transformations for the moon
774    osg::MatrixTransform* moonAroundEarthRotation = solarSystem.createRotation( solarSystem._RorbitMoon, solarSystem._rotateSpeedMoon );
775    osg::MatrixTransform* moonTranslation = solarSystem.createTranslationAndTilt( solarSystem._RorbitMoon, 0.0 );
776
777
778    moonTranslation->addChild( moon );
779    moonAroundEarthRotation->addChild( moonTranslation );
780    earthMoonGroup->addChild( moonAroundEarthRotation );
781
782    earthAroundItselfRotation->addChild( earth );
783    earthMoonGroup->addChild( earthAroundItselfRotation );
784   
785    earthMoonGroupPosition->addChild( earthMoonGroup );
786
787    aroundSunRotationEarthMoonGroup->addChild( earthMoonGroupPosition );
788
789    sunLight->addChild( aroundSunRotationEarthMoonGroup );
790/*
791*********************************************
792**  end earthMoonGroup and Transformations
793*********************************************
794*/
795
796/*
797*********************************************
798**  Mercury and Transformations
799*********************************************
800*/
801    osg::Node* mercury = solarSystem.createPlanet( solarSystem._radiusMercury, "Mercury", osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ), solarSystem._mapMercury, "" );
802   
803    osg::MatrixTransform* aroundSunRotationMercury = solarSystem.createRotation( solarSystem._RorbitMercury, solarSystem._rotateSpeedMercury );
804    osg::MatrixTransform* mercuryPosition = solarSystem.createTranslationAndTilt( solarSystem._RorbitMercury, 0.0f );
805   
806    mercuryPosition->addChild( mercury );
807    aroundSunRotationMercury->addChild( mercuryPosition );
808   
809    sunLight->addChild( aroundSunRotationMercury );
810/*
811*********************************************
812**  end Mercury and Transformations
813*********************************************
814*/
815
816/*
817*********************************************
818**  Venus and Transformations
819*********************************************
820*/
821    osg::Node* venus = solarSystem.createPlanet( solarSystem._radiusVenus, "Venus", osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ), solarSystem._mapVenus, "" );
822   
823    osg::MatrixTransform* aroundSunRotationVenus = solarSystem.createRotation( solarSystem._RorbitVenus, solarSystem._rotateSpeedVenus );
824    osg::MatrixTransform* venusPosition = solarSystem.createTranslationAndTilt( solarSystem._RorbitVenus, 0.0f );
825   
826    venusPosition->addChild( venus );
827    aroundSunRotationVenus->addChild( venusPosition );
828   
829    sunLight->addChild( aroundSunRotationVenus );
830/*
831*********************************************
832**  end Venus and Transformations
833*********************************************
834*/
835
836/*
837*********************************************
838**  Mars and Transformations
839*********************************************
840*/
841    osg::Node* mars = solarSystem.createPlanet( solarSystem._radiusMars, "Mars", osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ), solarSystem._mapMars, "" );
842   
843    osg::MatrixTransform* aroundSunRotationMars = solarSystem.createRotation( solarSystem._RorbitMars, solarSystem._rotateSpeedMars );
844    osg::MatrixTransform* marsPosition = solarSystem.createTranslationAndTilt( solarSystem._RorbitMars, 0.0f );
845   
846    marsPosition->addChild( mars );
847    aroundSunRotationMars->addChild( marsPosition );
848   
849    sunLight->addChild( aroundSunRotationMars );
850/*
851*********************************************
852**  end Mars and Transformations
853*********************************************
854*/
855
856/*
857*********************************************
858**  Jupiter and Transformations
859*********************************************
860*/
861    osg::Node* jupiter = solarSystem.createPlanet( solarSystem._radiusJupiter, "Jupiter", osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ), solarSystem._mapJupiter, "" );
862   
863    osg::MatrixTransform* aroundSunRotationJupiter = solarSystem.createRotation( solarSystem._RorbitJupiter, solarSystem._rotateSpeedJupiter );
864    osg::MatrixTransform* jupiterPosition = solarSystem.createTranslationAndTilt( solarSystem._RorbitJupiter, 0.0f );
865   
866    jupiterPosition->addChild( jupiter );
867    aroundSunRotationJupiter->addChild( jupiterPosition );
868   
869    sunLight->addChild( aroundSunRotationJupiter );
870/*
871*********************************************
872**  end Jupiter and Transformations
873*********************************************
874*/
875
876/*
877    // add space, but don't light it, as its not illuminated by our sun
878    osg::Node* space = solarSystem.createSpace( "Space", solarSystem._mapSpace );
879    space->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
880    root->addChild( space );
881*/   
882     
883    if (!writeFileName.empty())
884    {
885        osgDB::writeNodeFile(*root, writeFileName);
886        std::cout<<"Written solar system to \""<<writeFileName<<"\""<<std::endl;
887        return 0;
888    }
889
890
891    // run optimization over the scene graph
892    osgUtil::Optimizer optimzer;
893    optimzer.optimize( root );
894     
895    // set the scene to render
896    viewer.setSceneData( root );
897
898
899    // set up tracker manipulators, once for each astral body
900   
901    {
902        FindNamedNodeVisitor fnnv("Moon");
903        root->accept(fnnv);
904
905        if (!fnnv._foundNodes.empty())
906        {
907            // set up the node tracker.
908            osgGA::NodeTrackerManipulator* tm = new osgGA::NodeTrackerManipulator;
909            tm->setTrackerMode( trackerMode );
910            tm->setRotationMode( rotationMode );
911            tm->setTrackNode( fnnv._foundNodes.front().get() );
912
913            unsigned int num = viewer.addCameraManipulator( tm );
914            viewer.selectCameraManipulator( num );
915        }
916    }   
917
918    {
919        FindNamedNodeVisitor fnnv("Earth");
920        root->accept(fnnv);
921
922        if (!fnnv._foundNodes.empty())
923        {
924            // set up the node tracker.
925            osgGA::NodeTrackerManipulator* tm = new osgGA::NodeTrackerManipulator;
926            tm->setTrackerMode( trackerMode );
927            tm->setRotationMode( rotationMode );
928            tm->setTrackNode( fnnv._foundNodes.front().get() );
929
930            unsigned int num = viewer.addCameraManipulator( tm );
931            viewer.selectCameraManipulator( num );
932        }
933    }   
934   
935    {
936        FindNamedNodeVisitor fnnv("Sun");
937        root->accept(fnnv);
938
939        if (!fnnv._foundNodes.empty())
940        {
941            // set up the node tracker.
942            osgGA::NodeTrackerManipulator* tm = new osgGA::NodeTrackerManipulator;
943            tm->setTrackerMode( trackerMode );
944            tm->setRotationMode( rotationMode );
945            tm->setTrackNode( fnnv._foundNodes.front().get() );
946
947            unsigned int num = viewer.addCameraManipulator( tm );
948            viewer.selectCameraManipulator( num );
949        }
950    }   
951   
952    // create the windows and run the threads.
953    viewer.realize();
954   
955    while( !viewer.done() )
956    {
957        // wait for all cull and draw threads to complete.
958        viewer.sync();
959
960        // update the scene by traversing it with the the update visitor which will
961        // call all node update callbacks and animations.
962        viewer.update();
963         
964        // fire off the cull and draw traversals of the scene.
965        viewer.frame();
966       
967    }
968   
969   
970    // wait for all cull and draw threads to complete.
971    viewer.sync();
972
973    // run a clean up frame to delete all OpenGL objects.
974    viewer.cleanup_frame();
975
976    // wait for all the clean up frame to complete.
977    viewer.sync();
978
979    return 0;
980}// end main
Note: See TracBrowser for help on using the browser.