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

Revision 3701, 36.4 kB (checked in by robert, 10 years ago)

from Mike Weiblen, added wrap mode to planet texture to avoid black seam, and
add option of specifying the texture to use in osgshape.

  • 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 before exit.
971    viewer.sync();
972
973    return 0;
974}// end main
Note: See TracBrowser for help on using the browser.