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

Revision 3589, 27.2 kB (checked in by robert, 9 years ago)

Added rainer's changes for adding billboard glow around sun.

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