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

Revision 13574, 36.5 kB (checked in by robert, 3 hours ago)

Improved handling of setting of the depth of the UI.

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