Show
Ignore:
Timestamp:
03/22/05 13:11:03 (10 years ago)
Author:
robert
Message:

Updated sphere segment example to use original osgsimulation source, adding
in terrain, moving models and particle effects.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgspheresegment/osgspheresegment.cpp

    r2740 r3934  
     1#include <osgProducer/Viewer> 
     2 
     3#include <osg/Group> 
    14#include <osg/Geode> 
    25#include <osg/ShapeDrawable> 
    3 #include <osg/Material> 
    46#include <osg/Texture2D> 
    5 #include <osg/Geometry> 
     7#include <osg/PositionAttitudeTransform> 
    68#include <osg/MatrixTransform> 
    7 #include <osg/PositionAttitudeTransform> 
    8 #include <osg/BlendFunc> 
    9 #include <osg/ClearNode> 
    10  
    11 #include <osgUtil/Tesselator> 
    12 #include <osgUtil/TransformCallback> 
    13 #include <osgUtil/CullVisitor> 
     9 
     10#include <osgDB/ReadFile> 
    1411 
    1512#include <osgText/Text> 
    1613 
    17 #include <osgGA/TrackballManipulator> 
    18 #include <osgProducer/Viewer> 
    19 #include <osgDB/ReadFile> 
    20  
    2114#include <osgSim/SphereSegment> 
    2215 
    23 using namespace osgSim; 
    24  
    25 class MyNodeCallback: public osg::NodeCallback 
    26 { 
    27     void operator()(osg::Node*,osg::NodeVisitor*); 
    28 }; 
    29  
    30 // void MyNodeCallback::operator()(osg::Node* n,osg::NodeVisitor* nv) 
    31 // { 
    32 //     if(osgSim::SphereSegment* ss=dynamic_cast<osgSim::SphereSegment*>(n)) 
    33 //     { 
    34 //         osg::Vec3 vec; 
    35 //         float azRange, elevRange; 
    36 //         ss->getArea(vec,azRange,elevRange); 
    37 // 
    38 //         float azRangeDeg = osg::RadiansToDegrees(azRange); 
    39 // 
    40 //         static bool azAscending = false; 
    41 // 
    42 //         if(azAscending){ 
    43 //             azRangeDeg += 1.0f; 
    44 //             if(azRangeDeg>89.0f) azAscending = false; 
    45 //         }else{ 
    46 //             azRangeDeg -= 1.0f; 
    47 //             if(azRangeDeg<2.0f) azAscending = true; 
    48 //         } 
    49 // 
    50 //         ss->setArea(vec,osg::DegreesToRadians(azRangeDeg),elevRange); 
    51 // 
    52 //     } 
    53 //     traverse(n,nv); 
    54 // } 
    55  
    56 void MyNodeCallback::operator()(osg::Node* n,osg::NodeVisitor* nv) 
    57 { 
    58     if(osgSim::SphereSegment* ss=dynamic_cast<osgSim::SphereSegment*>(n)) 
    59     { 
    60         osg::Vec3 vec; 
    61         float azRange, elevRange; 
    62         ss->getArea(vec,azRange,elevRange); 
    63  
    64         static float angle = 0.0f; 
    65         if(++angle > 359.0f) angle = 0.0f; 
    66         vec.set(sin(osg::DegreesToRadians(angle)),cos(osg::DegreesToRadians(angle)),0.0f); 
    67  
    68         std::cout<<"angle "<<angle<<" degrees, vec is "<<vec 
    69                         <<", azRange is "<<osg::RadiansToDegrees(azRange) 
    70                         <<", elevRange is "<<osg::RadiansToDegrees(elevRange) 
    71                         <<std::endl; 
    72  
    73         ss->setArea(vec,azRange,elevRange); 
    74     } 
    75     traverse(n,nv); 
    76 } 
    77  
    78 osg::Node* createSphereSegment() 
    79 { 
    80     SphereSegment* ss = new SphereSegment(osg::Vec3(0.0f,0.0f,0.0f), 1.0f, 
    81                     osg::Vec3(0.0f,1.0f,0.0f), 
    82                     osg::DegreesToRadians(90.0f), 
    83                     osg::DegreesToRadians(45.0f), 
    84                     60); 
    85     ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f)); 
    86     ss->setSideColor(osg::Vec4(0.0f,0.0f,1.0f,0.5f)); 
    87     //ss->setDrawMask(SphereSegment::DrawMask(SphereSegment::SPOKES | SphereSegment::EDGELINE)); 
    88  
    89     //ss->setUpdateCallback(new MyNodeCallback); 
    90  
    91     return ss; 
    92 } 
    93  
    94 int main( int argc, char **argv ) 
     16#include <osgParticle/ExplosionEffect> 
     17#include <osgParticle/SmokeEffect> 
     18#include <osgParticle/FireEffect> 
     19#include <osgParticle/ParticleSystemUpdater> 
     20 
     21// for the grid data.. 
     22#include "../osghangglide/terrain_coords.h" 
     23 
     24osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime) 
     25{ 
     26    // set up the animation path  
     27    osg::AnimationPath* animationPath = new osg::AnimationPath; 
     28    animationPath->setLoopMode(osg::AnimationPath::LOOP); 
     29     
     30    int numSamples = 40; 
     31    float yaw = 0.0f; 
     32    float yaw_delta = 2.0f*osg::PI/((float)numSamples-1.0f); 
     33    float roll = osg::inDegrees(30.0f); 
     34     
     35    double time=0.0f; 
     36    double time_delta = looptime/(double)numSamples; 
     37    for(int i=0;i<numSamples;++i) 
     38    { 
     39        osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f)); 
     40        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))); 
     41         
     42        animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation)); 
     43 
     44        yaw += yaw_delta; 
     45        time += time_delta; 
     46 
     47    } 
     48    return animationPath;     
     49} 
     50 
     51osg::Node* createMovingModel(const osg::Vec3& center, float radius) 
     52{ 
     53    float animationLength = 10.0f; 
     54 
     55    osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength); 
     56 
     57    osg::Group* model = new osg::Group; 
     58 
     59    osg::Node* glider = osgDB::readNodeFile("glider.osg"); 
     60    if (glider) 
     61    { 
     62        const osg::BoundingSphere& bs = glider->getBound(); 
     63 
     64        float size = radius/bs.radius()*0.3f; 
     65        osg::MatrixTransform* positioned = new osg::MatrixTransform; 
     66        positioned->setDataVariance(osg::Object::STATIC); 
     67        positioned->setMatrix(osg::Matrix::translate(-bs.center())* 
     68                                     osg::Matrix::scale(size,size,size)* 
     69                                     osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,0.0f,1.0f)); 
     70     
     71        positioned->addChild(glider); 
     72     
     73        osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;     
     74        xform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); 
     75        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0)); 
     76        xform->addChild(positioned); 
     77 
     78        model->addChild(xform); 
     79    } 
     80  
     81    osg::Node* cessna = osgDB::readNodeFile("cessna.osg"); 
     82    if (cessna) 
     83    { 
     84        const osg::BoundingSphere& bs = cessna->getBound(); 
     85 
     86        osgText::Text* text = new osgText::Text; 
     87        float size = radius/bs.radius()*0.3f; 
     88 
     89        text->setPosition(bs.center()); 
     90        text->setText("Cessna"); 
     91        text->setAlignment(osgText::Text::CENTER_CENTER); 
     92        text->setAxisAlignment(osgText::Text::SCREEN); 
     93        text->setCharacterSize(40.0f); 
     94        text->setCharacterSizeMode(osgText::Text::SCREEN_COORDS); 
     95         
     96        osg::Geode* geode = new osg::Geode; 
     97        geode->addDrawable(text); 
     98     
     99        osg::LOD* lod = new osg::LOD; 
     100        lod->setRangeMode(osg::LOD::PIXEL_SIZE_ON_SCREEN); 
     101        lod->addChild(geode,0.0f,100.0f); 
     102        lod->addChild(cessna,100.0f,10000.0f); 
     103 
     104 
     105        osg::MatrixTransform* positioned = new osg::MatrixTransform; 
     106        positioned->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); 
     107        positioned->setDataVariance(osg::Object::STATIC); 
     108        positioned->setMatrix(osg::Matrix::translate(-bs.center())* 
     109                                     osg::Matrix::scale(size,size,size)* 
     110                                     osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,1.0f)); 
     111     
     112        //positioned->addChild(cessna); 
     113        positioned->addChild(lod); 
     114     
     115        osg::MatrixTransform* xform = new osg::MatrixTransform; 
     116        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0)); 
     117        xform->addChild(positioned); 
     118 
     119        model->addChild(xform); 
     120    } 
     121     
     122    return model; 
     123} 
     124 
     125 
     126osg::Vec3 computeTerrainIntersection(osg::Node* subgraph,float x,float y) 
     127{ 
     128    osgUtil::IntersectVisitor iv; 
     129    osg::ref_ptr<osg::LineSegment> segDown = new osg::LineSegment; 
     130 
     131    const osg::BoundingSphere& bs = subgraph->getBound(); 
     132    float zMax = bs.center().z()+bs.radius(); 
     133    float zMin = bs.center().z()-bs.radius(); 
     134     
     135    segDown->set(osg::Vec3(x,y,zMin),osg::Vec3(x,y,zMax)); 
     136    iv.addLineSegment(segDown.get()); 
     137 
     138    subgraph->accept(iv); 
     139 
     140    if (iv.hits()) 
     141    { 
     142        osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get()); 
     143        if (!hitList.empty()) 
     144        { 
     145            osg::Vec3 ip = hitList.front().getWorldIntersectPoint(); 
     146            return  ip; 
     147        } 
     148    } 
     149 
     150    return osg::Vec3(x,y,0.0f); 
     151} 
     152 
     153 
     154////////////////////////////////////////////////////////////////////////////// 
     155// MAIN SCENE GRAPH BUILDING FUNCTION 
     156////////////////////////////////////////////////////////////////////////////// 
     157 
     158void build_world(osg::Group *root) 
     159{ 
     160 
     161    osg::Geode* terrainGeode = new osg::Geode; 
     162    // create terrain 
     163    { 
     164        osg::StateSet* stateset = new osg::StateSet(); 
     165        osg::Image* image = osgDB::readImageFile("Images/lz.rgb"); 
     166        if (image) 
     167        { 
     168            osg::Texture2D* texture = new osg::Texture2D; 
     169            texture->setImage(image); 
     170            stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON); 
     171        } 
     172 
     173        terrainGeode->setStateSet( stateset ); 
     174 
     175        float size = 1000; // 10km; 
     176        float scale = size/39.0f; // 10km; 
     177        float z_scale = scale*3.0f; 
     178 
     179        osg::HeightField* grid = new osg::HeightField; 
     180        grid->allocateGrid(38,39); 
     181        grid->setXInterval(scale); 
     182        grid->setYInterval(scale); 
     183 
     184        for(unsigned int r=0;r<39;++r) 
     185        { 
     186            for(unsigned int c=0;c<38;++c) 
     187            { 
     188                grid->setHeight(c,r,z_scale*vertex[r+c*39][2]); 
     189            } 
     190        } 
     191        terrainGeode->addDrawable(new osg::ShapeDrawable(grid)); 
     192         
     193        root->addChild(terrainGeode); 
     194    }     
     195 
     196    // create sphere segment 
     197    { 
     198        osgSim::SphereSegment* ss = new osgSim::SphereSegment( 
     199                        computeTerrainIntersection(terrainGeode,550.0f,780.0f), // center 
     200                        500.0f, // radius 
     201                        osg::DegreesToRadians(135.0f), 
     202                        osg::DegreesToRadians(245.0f), 
     203                        osg::DegreesToRadians(-10.0f), 
     204                        osg::DegreesToRadians(30.0f), 
     205                        60); 
     206        ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f)); 
     207        ss->setSideColor(osg::Vec4(0.0f,1.0f,1.0f,0.1f)); 
     208 
     209        root->addChild(ss);         
     210    } 
     211 
     212 
     213    // create particle effects 
     214    {     
     215        osg::PositionAttitudeTransform* positionEffects = new osg::PositionAttitudeTransform; 
     216        positionEffects->setPosition(computeTerrainIntersection(terrainGeode,100.0f,100.0f)); 
     217        root->addChild(positionEffects); 
     218 
     219        osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect; 
     220        osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect; 
     221        osgParticle::FireEffect* fire = new osgParticle::FireEffect; 
     222 
     223        osg::Geode* geode = new osg::Geode; 
     224        geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),10.0f))); 
     225        positionEffects->addChild(geode); 
     226 
     227        positionEffects->addChild(explosion); 
     228        positionEffects->addChild(smoke); 
     229        positionEffects->addChild(fire); 
     230 
     231        osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater; 
     232 
     233        psu->addParticleSystem(explosion->getParticleSystem()); 
     234        psu->addParticleSystem(smoke->getParticleSystem()); 
     235        psu->addParticleSystem(fire->getParticleSystem()); 
     236 
     237        // add the updater node to the scene graph 
     238        root->addChild(psu); 
     239    } 
     240     
     241     
     242    // create the moving models. 
     243    { 
     244        root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f)); 
     245    } 
     246} 
     247 
     248 
     249////////////////////////////////////////////////////////////////////////////// 
     250// main() 
     251////////////////////////////////////////////////////////////////////////////// 
     252 
     253 
     254int main(int argc, char **argv) 
    95255{ 
    96256    // use an ArgumentParser object to manage the program arguments. 
    97257    osg::ArgumentParser arguments(&argc,argv); 
    98  
     258     
    99259    // set up the usage document, in case we need to print out how to use this program. 
    100     arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates both text, animation and billboard via custom transform to create the OpenSceneGraph logo.."); 
    101     arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); 
     260    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of particle systems."); 
     261    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file_left_eye image_file_right_eye"); 
    102262    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); 
    103     arguments.getApplicationUsage()->addCommandLineOption("ps","Render the Professional Services logo"); 
     263     
    104264 
    105265    // construct the viewer. 
     
    128288        return 1; 
    129289    } 
    130  
    131     osg::Node* node = createSphereSegment(); 
    132  
    133     // add model to viewer. 
    134     viewer.setSceneData( node ); 
    135  
     290     
     291    osg::Group *root = new osg::Group; 
     292    build_world(root); 
     293    
     294    // add a viewport to the viewer and attach the scene graph. 
     295    viewer.setSceneData(root); 
     296         
    136297    // create the windows and run the threads. 
    137298    viewer.realize(); 
     
    145306        // call all node update callbacks and animations. 
    146307        viewer.update(); 
    147  
     308          
    148309        // fire off the cull and draw traversals of the scene. 
    149310        viewer.frame(); 
    150     } 
    151  
     311         
     312    } 
     313     
    152314    // wait for all cull and draw threads to complete before exit. 
    153315    viewer.sync();