Changeset 10827

Show
Ignore:
Timestamp:
11/24/09 16:00:11 (3 years ago)
Author:
robert
Message:

From Martin Scheffler, "osgParticle: method to set start and end tile for particle texture (for animated particles). I also updated examples/osgParticle to show the feature.
The texture in data/Images should be copied to osg-data. I created the texture myself with the help of an explosion generator, so no license issues there.
"

Location:
OpenSceneGraph/trunk
Files:
3 modified

Legend:

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

    r10657 r10827  
    324324 
    325325 
     326 
     327////////////////////////////////////////////////////////////////////////////// 
     328// ANIMATED PARTICLE SYSTEM CREATION 
     329////////////////////////////////////////////////////////////////////////////// 
     330 
     331 
     332osgParticle::ParticleSystem *create_animated_particle_system(osg::Group *root) 
     333{ 
     334 
     335    // Now we will create a particle system that uses two emitters to  
     336    // display two animated particles, one showing an explosion, the other 
     337    // a smoke cloud. A particle system can only use one texture, so 
     338    // the animations for both particles are stored in a single bitmap. 
     339    // The frames of the animation are stored in tiles. For each particle 
     340    // template, the start and end tile of their animation have to be given. 
     341    // The example file used here has 64 tiles, stored in eight rows with 
     342    // eight images each. 
     343 
     344    // First create a prototype for the explosion particle. 
     345    osgParticle::Particle pexplosion; 
     346 
     347    // The frames of the explosion particle are played from birth to 
     348    // death of the particle. So if lifetime is one second, all 16 images  
     349    // of the particle are shown in this second. 
     350    pexplosion.setLifeTime(1); 
     351 
     352    // some other particle properties just as in the last example. 
     353    pexplosion.setSizeRange(osgParticle::rangef(0.75f, 3.0f)); 
     354    pexplosion.setAlphaRange(osgParticle::rangef(0.5f, 1.0f)); 
     355    pexplosion.setColorRange(osgParticle::rangev4( 
     356        osg::Vec4(1, 1, 1, 1),  
     357        osg::Vec4(1, 1, 1, 1))); 
     358    pexplosion.setRadius(0.05f); 
     359    pexplosion.setMass(0.05f); 
     360 
     361    // This command sets the animation tiles to be shown for the particle. 
     362    // The first two parameters define the tile layout of the texture image. 
     363    // 8, 8 means the texture has eight rows of tiles with eight columns each. 
     364    // 0, 15 defines the start and end tile  
     365    pexplosion.setTextureTileRange(8, 8, 0, 15); 
     366 
     367    // The smoke particle is just the same, only plays another tile range. 
     368    osgParticle::Particle psmoke = pexplosion; 
     369    psmoke.setTextureTileRange(8, 8, 32, 45); 
     370 
     371    // Create a single particle system for both particle types 
     372    osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem; 
     373 
     374    // Assign the tiled texture 
     375    ps->setDefaultAttributes("Images/fireparticle8x8.png", false, false); 
     376 
     377    // Create two emitters, one for the explosions, one for the smoke balls. 
     378    osgParticle::ModularEmitter *emitter1 = new osgParticle::ModularEmitter; 
     379    emitter1->setParticleSystem(ps); 
     380    emitter1->setParticleTemplate(pexplosion); 
     381 
     382    osgParticle::ModularEmitter *emitter2 = new osgParticle::ModularEmitter; 
     383    emitter2->setParticleSystem(ps); 
     384    emitter2->setParticleTemplate(psmoke); 
     385 
     386    // create a counter each. We could reuse the counter for both emitters, but 
     387    // then we could not control the ratio of smoke balls to explosions 
     388    osgParticle::RandomRateCounter *counter1 = new osgParticle::RandomRateCounter; 
     389    counter1->setRateRange(10, 10); 
     390    emitter1->setCounter(counter1); 
     391 
     392    osgParticle::RandomRateCounter *counter2 = new osgParticle::RandomRateCounter; 
     393    counter2->setRateRange(3, 4); 
     394    emitter2->setCounter(counter2); 
     395 
     396    // setup a single placer for both emitters. 
     397    osgParticle::SectorPlacer *placer = new osgParticle::SectorPlacer; 
     398    placer->setCenter(-8, 0, 0); 
     399    placer->setRadiusRange(2.5, 5); 
     400    placer->setPhiRange(0, 2 * osg::PI);    // 360° angle to make a circle 
     401    emitter1->setPlacer(placer); 
     402    emitter2->setPlacer(placer); 
     403 
     404    // the shooter is reused for both emitters 
     405    osgParticle::RadialShooter *shooter = new osgParticle::RadialShooter; 
     406    shooter->setInitialSpeedRange(0, 0); 
     407 
     408    // give particles a little spin 
     409    shooter->setInitialRotationalSpeedRange(osgParticle::rangev3( 
     410       osg::Vec3(0, 0, -1), 
     411       osg::Vec3(0, 0, 1))); 
     412    emitter1->setShooter(shooter); 
     413    emitter2->setShooter(shooter); 
     414 
     415    // add both emitters to the scene graph 
     416    root->addChild(emitter1); 
     417    root->addChild(emitter2); 
     418    
     419    // create a program, just as before 
     420    osgParticle::ModularProgram *program = new osgParticle::ModularProgram; 
     421    program->setParticleSystem(ps); 
     422 
     423    // create an operator that moves the particles upwards 
     424    osgParticle::AccelOperator *op1 = new osgParticle::AccelOperator; 
     425    op1->setAcceleration(osg::Vec3(0, 0, 2.0f)); 
     426    program->addOperator(op1);   
     427 
     428    // add the program to the scene graph 
     429    root->addChild(program); 
     430 
     431    // create a Geode to contain our particle system. 
     432    osg::Geode *geode = new osg::Geode; 
     433    geode->addDrawable(ps); 
     434 
     435    // add the geode to the scene graph. 
     436    root->addChild(geode); 
     437 
     438    return ps; 
     439} 
     440 
    326441////////////////////////////////////////////////////////////////////////////// 
    327442// MAIN SCENE GRAPH BUILDING FUNCTION 
     
    342457    osgParticle::ParticleSystem *ps1 = create_simple_particle_system(root); 
    343458    osgParticle::ParticleSystem *ps2 = create_complex_particle_system(root); 
     459    osgParticle::ParticleSystem *ps3 = create_animated_particle_system(root); 
    344460 
    345461    // Now that the particle systems and all other related objects have been 
     
    350466    psu->addParticleSystem(ps1); 
    351467    psu->addParticleSystem(ps2); 
     468    psu->addParticleSystem(ps3); 
    352469 
    353470    // add the updater node to the scene graph 
  • OpenSceneGraph/trunk/include/osgParticle/Particle

    r10660 r10827  
    155155         
    156156        /// Get number of texture tiles 
    157         inline int getNumTiles() const { return _num_tile; } 
     157        inline int getNumTiles() const { return _end_tile - _start_tile + 1; } 
    158158         
    159159        /** Kill the particle on next update 
     
    247247        inline float getCurrentSize() const; 
    248248         
    249         /// Specify how the particle texture is tiled 
    250         inline void setTextureTile(int sTile, int tTile, int numTiles = 0); 
     249        /// Specify how the particle texture is tiled. 
     250        /// All tiles in the given range are sequentially displayed during the lifetime 
     251        /// of the particle. When no range is given, all tiles are displayed during the lifetime. 
     252        inline void setTextureTileRange(int sTile, int tTile, int startTile, int endTile); 
     253 
     254        /// Same as above, range starts at 0 and ends at end 
     255        inline void setTextureTile(int sTile, int tTile, int end = -1); 
    251256 
    252257        /// Set the previous particle 
     
    300305        float _s_tile; 
    301306        float _t_tile; 
    302         int _num_tile; 
     307        int _start_tile; 
     308        int _end_tile; 
    303309        int _cur_tile; 
    304310        float _s_coord; 
     
    567573    } 
    568574 
    569     inline void Particle::setTextureTile(int sTile, int tTile, int numTiles) 
    570     { 
    571         _s_tile = (sTile>0) ? 1.0f / static_cast<float>(sTile) : 1.0f; 
    572         _t_tile = (tTile>0) ? 1.0f / static_cast<float>(tTile) : 1.0f; 
    573         if (numTiles <= 0) 
    574         { 
    575             _num_tile = sTile * tTile; 
    576         } 
    577         else 
    578         { 
    579             _num_tile = numTiles; 
    580         } 
    581     } 
    582  
     575 
     576    inline void Particle::setTextureTile(int sTile, int tTile, int end) 
     577    { 
     578        setTextureTileRange(sTile, tTile, -1, end); 
     579    } 
     580 
     581    inline void Particle::setTextureTileRange(int sTile, int tTile, int startTile, int endTile) 
     582    { 
     583       _s_tile = (sTile>0) ? 1.0f / static_cast<float>(sTile) : 1.0f; 
     584       _t_tile = (tTile>0) ? 1.0f / static_cast<float>(tTile) : 1.0f; 
     585        
     586       if(startTile == -1) 
     587       { 
     588          _start_tile = 0; 
     589       } 
     590       else 
     591       { 
     592          _start_tile = startTile; 
     593       } 
     594 
     595       if(endTile == -1) 
     596       { 
     597          _end_tile = sTile * tTile; 
     598       } 
     599       else 
     600       { 
     601          _end_tile = endTile; 
     602       } 
     603    } 
    583604 
    584605} 
  • OpenSceneGraph/trunk/src/osgParticle/Particle.cpp

    r10660 r10827  
    4646    _s_tile(1.0f), 
    4747    _t_tile(1.0f), 
    48     _num_tile(1), 
     48    _start_tile(0), 
     49    _end_tile(0), 
    4950    _cur_tile(-1), 
    5051    _s_coord(0.0f), 
     
    8081 
    8182    //Compute the current texture tile based on our normalized age 
    82     int currentTile = static_cast<int>(x * _num_tile); 
     83    int currentTile = _start_tile + static_cast<int>(x * getNumTiles()); 
    8384     
    8485    //If the current texture tile is different from previous, then compute new texture coords