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

Revision 7648, 37.0 kB (checked in by robert, 6 years ago)

From Roland Smeenk, "Attached you will find a large set of small typo fixes (mainly in the comments)."

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