Show
Ignore:
Timestamp:
04/13/06 21:05:26 (8 years ago)
Author:
robert
Message:

Added command line options and various speed improvements.

Files:
1 modified

Legend:

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

    r5086 r5087  
    2828float random(float min,float max) { return min + (max-min)*(float)rand()/(float)RAND_MAX; } 
    2929 
     30struct PrecipatationParameters : public osg::Referenced 
     31{ 
     32    PrecipatationParameters(): 
     33        particleVelocity(0.0,0.0,-5.0), 
     34        particleSize(0.02), 
     35        particleColour(0.6, 0.6, 0.6, 1.0), 
     36        numberOfParticles(10000000), 
     37        numberOfCellsX(100), 
     38        numberOfCellsY(100), 
     39        numberOfCellsZ(1), 
     40        nearTransition(25.0), 
     41        farTransition(100.0) 
     42    {} 
     43 
     44    void rain (float intensity) 
     45    { 
     46        particleVelocity = osg::Vec3(0.0,0.0,-2.0) + osg::Vec3(0.0,0.0,-10.0)*intensity; 
     47        particleSize = 0.01 + 0.04*intensity; 
     48        numberOfParticles = intensity * 100000000; 
     49        particleColour = osg::Vec4(0.6, 0.6, 0.6, 1.0); 
     50    } 
     51 
     52    void snow(float intensity) 
     53    { 
     54        particleVelocity = osg::Vec3(0.0,0.0,-1.0) + osg::Vec3(0.0,0.0,-0.5)*intensity; 
     55        particleSize = 0.02 + 0.05*intensity; 
     56        numberOfParticles = intensity * 100000000; 
     57        particleColour = osg::Vec4(0.8, 0.8, 0.8, 1.0); 
     58    } 
     59 
     60    osg::BoundingBox    boundingBox; 
     61    osg::Vec3           particleVelocity; 
     62    float               particleSize; 
     63    osg::Vec4           particleColour; 
     64    unsigned int        numberOfParticles; 
     65    unsigned int        numberOfCellsX; 
     66    unsigned int        numberOfCellsY; 
     67    unsigned int        numberOfCellsZ; 
     68    float               nearTransition; 
     69    float               farTransition; 
     70}; 
     71 
     72struct PrecipitationCullCallback : public virtual osg::Drawable::CullCallback 
     73{ 
     74    PrecipitationCullCallback() {} 
     75 
     76    PrecipitationCullCallback(const PrecipitationCullCallback&,const osg::CopyOp&) {} 
     77 
     78    META_Object(osg,PrecipitationCullCallback); 
     79 
     80    /** do customized cull code, return true if drawable should be culled.*/ 
     81    virtual bool cull(osg::NodeVisitor* nodeVisitor, osg::Drawable* drawable, osg::State* state) const 
     82    { 
     83        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nodeVisitor); 
     84        if (cv) 
     85        { 
     86            float distance = nodeVisitor->getDistanceFromEyePoint(drawable->getBound().center(),true); 
     87 
     88//            if (distance<-4.0) return true; 
     89             
     90#if 0 
     91             
     92            const osg::BoundingBox& bb = drawable->getBound(); 
     93            const osg::Polytope& frustum = cv->getCurrentCullingSet().getFrustum(); 
     94            int numPointsInside = 0; 
     95            for(unsigned int i=0; i<8; ++i) 
     96            { 
     97                if (frustum.contains(bb.corner(i))) ++numPointsInside; 
     98            } 
     99         
     100            std::cout<<" "<<drawable->getName()<<" distance "<<distance<<"num Points inside = "<<numPointsInside<<std::endl; 
     101 
     102            if (cv->isCulled(drawable->getBound())) 
     103            { 
     104                std::cout<<" isCulled "<<drawable->getName()<<std::endl; 
     105                return true; 
     106            } 
     107#endif 
     108 
     109        } 
     110     
     111        return false; 
     112    } 
     113}; 
     114 
     115 
    30116class PrecipitationGeometry : public osg::Geometry 
    31117{ 
     
    35121        { 
    36122            setSupportsDisplayList(false); 
     123             
     124            setCullCallback(new PrecipitationCullCallback()); 
    37125        } 
    38126 
     
    69157 
    70158            _internalGeometry->draw(state); 
     159             
     160             
     161            static int s_frameNumber = 0xffffffff; 
     162            static unsigned int s_NumberQuads = 0; 
     163            static unsigned int s_NumberQuadsVertices = 0; 
     164            static unsigned int s_NumberLines = 0; 
     165            static unsigned int s_NumberLinesVertices = 0; 
     166            static unsigned int s_NumberPoints = 0; 
     167            static unsigned int s_NumberPointsVertices = 0; 
     168             
     169            if (s_frameNumber != state.getFrameStamp()->getFrameNumber()) 
     170            { 
     171                // std::cout<<"Frame "<< s_frameNumber<<"\tquads "<<s_NumberQuads<<", "<<s_NumberQuadsVertices<<"  points "<<s_NumberPoints<<", "<<s_NumberPointsVertices<<std::endl; 
     172             
     173                s_NumberQuads = 0; 
     174                s_NumberLines = 0; 
     175                s_NumberPoints = 0; 
     176                s_NumberQuadsVertices = 0; 
     177                s_NumberLinesVertices = 0; 
     178                s_NumberPointsVertices = 0; 
     179 
     180                s_frameNumber = state.getFrameStamp()->getFrameNumber(); 
     181            } 
     182             
     183             
     184            if (_internalGeometry->getName()=="quad")  
     185            { 
     186                s_NumberQuads++; 
     187                s_NumberQuadsVertices+= _internalGeometry->getVertexArray()->getNumElements(); 
     188            } 
     189            else if (_internalGeometry->getName()=="line") 
     190            { 
     191                s_NumberLines++; 
     192                s_NumberLinesVertices+= _internalGeometry->getVertexArray()->getNumElements(); 
     193            } 
     194            else if (_internalGeometry->getName()=="point") 
     195            { 
     196                s_NumberPoints++; 
     197                s_NumberPointsVertices+= _internalGeometry->getVertexArray()->getNumElements(); 
     198            } 
    71199        } 
    72200 
     
    213341    if (quad_geometry) 
    214342    { 
     343        quad_geometry->setName("quad"); 
     344     
    215345        quad_vertices = new osg::Vec3Array(numParticles*4); 
    216346        quad_offsets = new osg::Vec2Array(numParticles*4); 
     
    226356    if (line_geometry) 
    227357    { 
     358        line_geometry->setName("line"); 
     359 
    228360        line_vertices = new osg::Vec3Array(numParticles*2); 
    229361        line_offsets = new osg::Vec2Array(numParticles*2); 
     
    239371    if (point_geometry) 
    240372    { 
     373        point_geometry->setName("point"); 
     374 
    241375        point_vertices = new osg::Vec3Array(numParticles); 
    242376        point_offsets = new osg::Vec2Array(numParticles); 
     
    353487 
    354488 
    355 osg::Node* createRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity) 
     489osg::Node* createRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, float nearTransition, float farTransition) 
    356490{ 
    357491    osg::LOD* lod = new osg::LOD; 
    358492     
     493 
     494    // distance between start point and end of cyclce 
     495    osg::Vec3 position(bb.xMin(), bb.yMin(), bb.zMax()); 
     496 
    359497    // time taken to get from start to the end of cycle 
    360498    float period = fabs((bb.zMax()-bb.zMin()) / velocity.z()); 
    361  
    362     // distance between start point and end of cyclce 
    363     osg::Vec3 position(bb.xMin(), bb.yMin(), bb.zMax()); 
    364499    osg::Vec3 dv_i( bb.xMax()-bb.xMin(), 0.0f, 0.0f ); 
    365500    osg::Vec3 dv_j( 0.0f, bb.yMax()-bb.yMin(), 0.0f ); 
    366501    osg::Vec3 dv_k( velocity * period ); 
    367  
    368     float nearDistance = 25.0; 
    369     float farDistance = 100.0; 
    370502     
    371503    // high res LOD. 
     
    377509        highres_geode->addDrawable(geometry); 
    378510 
     511        geometry->setName("highres"); 
    379512        geometry->setPosition(position); 
    380513        geometry->setInitialBound(bb); 
     
    382515        geometry->setStateSet(quad_stateset.get()); 
    383516         
    384         lod->addChild( highres_geode, 0.0f, nearDistance ); 
     517        lod->addChild( highres_geode, 0.0f, nearTransition ); 
    385518    } 
    386519     
     
    389522        osg::Geode* lowres_geode = new osg::Geode; 
    390523 
     524 
    391525        PrecipitationGeometry* geometry = new PrecipitationGeometry; 
    392526 
    393527        lowres_geode->addDrawable(geometry); 
    394528 
     529        geometry->setName("lowres"); 
    395530        geometry->setPosition(position); 
    396531        geometry->setInitialBound(bb); 
     
    398533        geometry->setStateSet(point_stateset.get()); 
    399534         
    400         lod->addChild( lowres_geode, nearDistance, farDistance ); 
     535        lod->addChild( lowres_geode, nearTransition, farTransition ); 
    401536    } 
    402537 
     
    405540} 
    406541 
    407 osg::Node* createCellRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, unsigned int numParticles) 
    408 { 
    409      
    410     unsigned int numX = 100; 
    411     unsigned int numY = 100; 
     542osg::Node* createCellRainEffect(const PrecipatationParameters& parameters) 
     543{ 
     544     
     545    unsigned int numX = parameters.numberOfCellsX; 
     546    unsigned int numY = parameters.numberOfCellsY; 
    412547    unsigned int numCells = numX*numY; 
    413     unsigned int numParticlesPerCell = numParticles/numCells; 
     548    unsigned int numParticlesPerCell = parameters.numberOfParticles/numCells; 
    414549 
    415550    setUpGeometries(numParticlesPerCell); 
    416551     
    417     std::cout<<"Effect total number of particles = "<<numParticles<<std::endl; 
     552    const osg::BoundingBox& bb = parameters.boundingBox; 
     553     
     554    std::cout<<"Effect total number of particles = "<<parameters.numberOfParticles<<std::endl; 
    418555    std::cout<<"Number of cells = "<<numCells<<std::endl; 
    419556    std::cout<<"Number of particles per cell = "<<numParticlesPerCell<<std::endl; 
     
    434571                                     bb.zMax()); 
    435572 
    436             group->addChild(createRainEffect(bbLocal, velocity)); 
     573            group->addChild(createRainEffect(bbLocal, parameters.particleVelocity, parameters.nearTransition, parameters.farTransition)); 
    437574        }         
    438575    } 
     
    444581#endif     
    445582 
    446 #if 1 
    447583    osg::StateSet* stateset = group->getOrCreateStateSet(); 
    448584 
    449585    // time taken to get from start to the end of cycle 
    450     float period = fabs((bb.zMax()-bb.zMin()) / velocity.z()); 
     586    float period = fabs((bb.zMax()-bb.zMin()) / parameters.particleVelocity.z()); 
    451587 
    452588    // distance between start point and end of cyclce 
    453589    osg::Vec3 dv_i( (bb.xMax()-bb.xMin())/(float)(numX), 0.0f, 0.0f ); 
    454590    osg::Vec3 dv_j( 0.0f, (bb.yMax()-bb.yMin())/(float)(numY), 0.0f ); 
    455     osg::Vec3 dv_k( velocity * period ); 
     591    osg::Vec3 dv_k( parameters.particleVelocity * period ); 
    456592 
    457593    // set up uniforms 
     
    480616    stateset->setTextureAttribute(0, texture); 
    481617 
    482     stateset->addUniform(new osg::Uniform("particleColour", osg::Vec4(0.6,0.6,0.6,1.0))); 
    483     stateset->addUniform(new osg::Uniform("particleSize", 0.02f)); 
     618    stateset->addUniform(new osg::Uniform("particleColour", parameters.particleColour)); 
     619    stateset->addUniform(new osg::Uniform("particleSize", parameters.particleSize)); 
    484620   
    485621    osg::Uniform* previousModelViewUniform = new osg::Uniform("previousModelViewMatrix",osg::Matrix()); 
     
    487623     
    488624    group->setCullCallback(new CullCallback(previousModelViewUniform)); 
    489 #endif 
     625 
    490626 
    491627    return group; 
    492628} 
    493629 
    494 osg::Node* createModel(osg::Node* loadedModel, bool /*useShaders*/) 
     630osg::Node* createModel(osg::Node* loadedModel, PrecipatationParameters& parameters) 
    495631{ 
    496632    osg::Group* group = new osg::Group; 
     
    507643 
    508644        bb.set( -500, -500, 0, +500, +500, 10); 
     645         
     646        parameters.boundingBox = bb; 
    509647         
    510648        osg::StateSet* stateset = loadedModel->getOrCreateStateSet(); 
     
    531669    } 
    532670     
    533     group->addChild(createCellRainEffect(bb, velocity, numParticles)); 
     671    group->addChild(createCellRainEffect(parameters)); 
    534672 
    535673    return group;     
     
    560698    viewer.getUsage(*arguments.getApplicationUsage()); 
    561699 
    562     bool shader = true; 
    563     while (arguments.read("--shader")) shader = true; 
    564     while (arguments.read("--fixed")) shader = false; 
     700    PrecipatationParameters parameters; 
     701 
     702    float intensity; 
     703    while (arguments.read("--snow", intensity)) parameters.snow(intensity); 
     704    while (arguments.read("--rain", intensity)) parameters.rain(intensity); 
     705 
     706    float particleSize; 
     707    while (arguments.read("--particleSize", particleSize)) parameters.particleSize = particleSize; 
     708 
     709    osg::Vec3 particleVelocity; 
     710    while (arguments.read("--particleVelocity", particleVelocity.x(), particleVelocity.y(), particleVelocity.z() )) parameters.particleVelocity = particleVelocity; 
     711 
     712    float transition; 
     713    while (arguments.read("--nearTransition", transition )) parameters.nearTransition = transition; 
     714    while (arguments.read("--farTransition", transition )) parameters.farTransition = transition; 
    565715 
    566716    // if user request help write it out to cout. 
     
    587737    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments); 
    588738     
    589     loadedModel = createModel(loadedModel.get(), shader); 
     739    loadedModel = createModel(loadedModel.get(), parameters); 
    590740 
    591741    // if no model has been successfully loaded report failure.