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

Revision 3659, 30.3 kB (checked in by robert, 9 years ago)

From Vivek Rajan, fixes to Solaris build.

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