diff --git a/examples/osgspheresegment/osgspheresegment.cpp b/examples/osgspheresegment/osgspheresegment.cpp index 02bb9e514..98525917a 100644 --- a/examples/osgspheresegment/osgspheresegment.cpp +++ b/examples/osgspheresegment/osgspheresegment.cpp @@ -227,20 +227,29 @@ void build_world(osg::Group *root) // create particle effects { - osg::PositionAttitudeTransform* positionEffects = new osg::PositionAttitudeTransform; - positionEffects->setPosition(computeTerrainIntersection(terrainGeode,100.0f,100.0f)); - root->addChild(positionEffects); + osg::Vec3 position = computeTerrainIntersection(terrainGeode,100.0f,100.0f); - osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect; - osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect; - osgParticle::FireEffect* fire = new osgParticle::FireEffect; - - positionEffects->addChild(explosion); - positionEffects->addChild(smoke); - positionEffects->addChild(fire); + osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 10.0f); + osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 10.0f); + osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, 10.0f); + root->addChild(explosion); + root->addChild(smoke); + root->addChild(fire); } + // create particle effects + { + osg::Vec3 position = computeTerrainIntersection(terrainGeode,200.0f,100.0f); + + osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 1.0f); + osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 1.0f); + osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, 1.0f); + + root->addChild(explosion); + root->addChild(smoke); + root->addChild(fire); + } // create the moving models. { diff --git a/include/osgParticle/ExplosionEffect b/include/osgParticle/ExplosionEffect index 39ca0234d..76c03d57e 100644 --- a/include/osgParticle/ExplosionEffect +++ b/include/osgParticle/ExplosionEffect @@ -15,6 +15,8 @@ #define OSGPARTICLE_EXPLOSIONEFFECT #include +#include +#include namespace osgParticle { @@ -23,18 +25,27 @@ namespace osgParticle { public: - ExplosionEffect(); + ExplosionEffect(const osg::Vec3& position=osg::Vec3(0.0f,0.0f,0.0f), float scale=1.0f, float intensity=1.0f); ExplosionEffect(const ExplosionEffect& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); META_Node(osgParticle,ExplosionEffect); virtual void setDefaults(); - - virtual void buildEffect(); + virtual void setUpEmitterAndProgram(); + + virtual Emitter* getEmitter() { return _emitter.get(); } + virtual const Emitter* getEmitter() const { return _emitter.get(); } + + virtual Program* getProgram() { return _program.get(); } + virtual const Program* getProgram() const { return _program.get(); } + protected: + osg::ref_ptr _emitter; + osg::ref_ptr _program; + }; } diff --git a/include/osgParticle/FireEffect b/include/osgParticle/FireEffect index 0ed8047ba..3188242fd 100644 --- a/include/osgParticle/FireEffect +++ b/include/osgParticle/FireEffect @@ -15,6 +15,8 @@ #define OSGPARTICLE_FireEffect #include +#include +#include namespace osgParticle { @@ -23,7 +25,7 @@ namespace osgParticle { public: - FireEffect(); + FireEffect(const osg::Vec3& position=osg::Vec3(0.0f,0.0f,0.0f), float scale=1.0f, float intensity=1.0f); FireEffect(const FireEffect& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); @@ -31,10 +33,20 @@ namespace osgParticle virtual void setDefaults(); - virtual void buildEffect(); + virtual void setUpEmitterAndProgram(); + virtual Emitter* getEmitter() { return _emitter.get(); } + virtual const Emitter* getEmitter() const { return _emitter.get(); } + + virtual Program* getProgram() { return _program.get(); } + virtual const Program* getProgram() const { return _program.get(); } + protected: + osg::ref_ptr _emitter; + osg::ref_ptr _program; + + }; } diff --git a/include/osgParticle/ParticleEffect b/include/osgParticle/ParticleEffect index ab93fd017..dbe66f4ac 100644 --- a/include/osgParticle/ParticleEffect +++ b/include/osgParticle/ParticleEffect @@ -24,35 +24,63 @@ namespace osgParticle { public: - ParticleEffect() {} + ParticleEffect(): + _scale(1.0f), + _intensity(1.0f), + _startTime(0.0), + _duration(1.0), + _direction(0.0f,0.0f,1.0f) + {} ParticleEffect(const ParticleEffect& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); + virtual const char *libraryName() const { return "osgParticle"; } virtual const char *className() const { return "ParticleEffect"; } virtual bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast(obj) != 0; } virtual void accept(osg::NodeVisitor& nv) { if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); } } - void setEmitter(Emitter* emitter) { _emitter = emitter; } - Emitter* getEmitter() { return _emitter.get(); } - const Emitter* getEmitter() const { return _emitter.get(); } + void setPosition(const osg::Vec3& position); + const osg::Vec3& getPosition() const { return _position; } - void setProgram(Program* program) { _program = program; } - Program* getProgram() { return _program.get(); } - const Program* getProgram() const { return _program.get(); } + void setScale(float scale); + float getScale() const { return _scale; } + + void setIntensity(float intensity); + float getIntensity() const { return _intensity; } - void setParticleSystem(ParticleSystem* ps) { _particleSystem = ps; } - ParticleSystem* getParticleSystem() { return _particleSystem.get(); } - const ParticleSystem* getParticleSystem() const { return _particleSystem.get(); } + void setStartTime(double startTime); + double getStartTime() const { return _startTime; } - virtual void buildEffect() = 0; + void setDuration(double duration); + double getDuration() const { return _duration; } + + + virtual Emitter* getEmitter() = 0; + virtual const Emitter* getEmitter() const = 0; + + virtual Program* getProgram() = 0; + virtual const Program* getProgram() const = 0; + + virtual ParticleSystem* getParticleSystem() { return _particleSystem.get(); } + virtual const ParticleSystem* getParticleSystem() const { return _particleSystem.get(); } + + virtual void setDefaults(); + + virtual void setUpEmitterAndProgram() = 0; + + virtual void buildEffect(); protected: - osg::ref_ptr _emitter; - osg::ref_ptr _program; osg::ref_ptr _particleSystem; - + + osg::Vec3 _position; + float _scale; + float _intensity; + double _startTime; + double _duration; + osg::Vec3 _direction; }; } diff --git a/include/osgParticle/ParticleSystem b/include/osgParticle/ParticleSystem index 25c3fe67f..00a512768 100644 --- a/include/osgParticle/ParticleSystem +++ b/include/osgParticle/ParticleSystem @@ -124,8 +124,11 @@ namespace osgParticle inline int getLastFrameNumber() const; /// Get a reference to the default particle template. - inline const Particle &getDefaultParticleTemplate() const; + inline Particle &getDefaultParticleTemplate(); + /// Get a const reference to the default particle template. + inline const Particle &getDefaultParticleTemplate() const; + /// Set the default particle template (particle is copied). inline void setDefaultParticleTemplate(const Particle &p); @@ -323,6 +326,11 @@ namespace osgParticle } } + inline Particle &ParticleSystem::getDefaultParticleTemplate() + { + return def_ptemp_; + } + inline const Particle &ParticleSystem::getDefaultParticleTemplate() const { return def_ptemp_; diff --git a/include/osgParticle/SmokeEffect b/include/osgParticle/SmokeEffect index 0cefd7206..4bd51b340 100644 --- a/include/osgParticle/SmokeEffect +++ b/include/osgParticle/SmokeEffect @@ -15,6 +15,8 @@ #define OSGPARTICLE_SmokeEffect #include +#include +#include namespace osgParticle { @@ -23,18 +25,27 @@ namespace osgParticle { public: - SmokeEffect(); + SmokeEffect(const osg::Vec3& position=osg::Vec3(0.0f,0.0f,0.0f), float scale=1.0f, float intensity=1.0f); SmokeEffect(const SmokeEffect& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); META_Node(osgParticle,SmokeEffect); virtual void setDefaults(); - - virtual void buildEffect(); + virtual void setUpEmitterAndProgram(); + + virtual Emitter* getEmitter() { return _emitter.get(); } + virtual const Emitter* getEmitter() const { return _emitter.get(); } + + virtual Program* getProgram() { return _program.get(); } + virtual const Program* getProgram() const { return _program.get(); } + protected: + osg::ref_ptr _emitter; + osg::ref_ptr _program; + }; } diff --git a/src/osgParticle/ExplosionEffect.cpp b/src/osgParticle/ExplosionEffect.cpp index fa49e5ab6..e213d20a0 100644 --- a/src/osgParticle/ExplosionEffect.cpp +++ b/src/osgParticle/ExplosionEffect.cpp @@ -27,9 +27,15 @@ using namespace osgParticle; -ExplosionEffect::ExplosionEffect() +ExplosionEffect::ExplosionEffect(const osg::Vec3& position, float scale, float intensity) { setDefaults(); + + _position = position; + _scale = scale; + _intensity = intensity; + + buildEffect(); } ExplosionEffect::ExplosionEffect(const ExplosionEffect& copy, const osg::CopyOp& copyop): @@ -38,6 +44,11 @@ ExplosionEffect::ExplosionEffect(const ExplosionEffect& copy, const osg::CopyOp& } void ExplosionEffect::setDefaults() +{ + ParticleEffect::setDefaults(); +} + +void ExplosionEffect::setUpEmitterAndProgram() { osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem; ps->setDefaultAttributes("Images/particle.rgb", false, false); @@ -64,28 +75,28 @@ void ExplosionEffect::setDefaults() osg::Vec4(0.5, 0.5f, 0.0f, 0.0f))); // these are physical properties of the particle - ptemplate.setRadius(0.1f); // 5 cm wide particles - ptemplate.setMass(1.0f); // 1kg heavy + ptemplate.setRadius(0.1f*_scale); // 5 cm wide particles + ptemplate.setMass(1.0f*_scale); // 1kg heavy // assign the particle template to the system. ps->setDefaultParticleTemplate(ptemplate); //osgParticle::LimitedDurationRandomRateCounter* counter = new osgParticle::LimitedDurationRandomRateCounter; osgParticle::RandomRateCounter* counter = new osgParticle::RandomRateCounter; - counter->setRateRange(2000,2000); // generate 1000 particles per second + counter->setRateRange(2000*_intensity,2000*_intensity); // generate 1000 particles per second emitter->setCounter(counter); osgParticle::SectorPlacer* placer = new osgParticle::SectorPlacer; - placer->setCenter(osg::Vec3(0.0,0.0,0.0)); - placer->setRadiusRange(0.0f,1.0f); + placer->setCenter(_position); + placer->setRadiusRange(0.0f,1.0f*_scale); emitter->setPlacer(placer); osgParticle::RadialShooter* shooter = new osgParticle::RadialShooter; shooter->setThetaRange(0.0f, osg::PI_2); - shooter->setInitialSpeedRange(5.0f,30.0f); + shooter->setInitialSpeedRange(5.0f*_scale,30.0f*_scale); emitter->setShooter(shooter); - emitter->setStartTime(0.0f); + emitter->setStartTime(_startTime); emitter->setResetTime(5.0f); emitter->setLifeTime(0.1f); emitter->setEndless(false); @@ -113,29 +124,5 @@ void ExplosionEffect::setDefaults() } - buildEffect(); } - -void ExplosionEffect::buildEffect() -{ - // clear the children. - removeChild(0,getNumChildren()); - if (!_emitter || !_particleSystem || !_program) return; - - // add the emitter - addChild(_emitter.get()); - - // add the program to update the particles - addChild(_program.get()); - - // add the particle system updater. - osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater; - psu->addParticleSystem(_particleSystem.get()); - addChild(psu); - - // add the geode to the scene graph - osg::Geode *geode = new osg::Geode; - geode->addDrawable(_particleSystem.get()); - addChild(geode); -} diff --git a/src/osgParticle/FireEffect.cpp b/src/osgParticle/FireEffect.cpp index a21eaff85..969208bd5 100644 --- a/src/osgParticle/FireEffect.cpp +++ b/src/osgParticle/FireEffect.cpp @@ -26,9 +26,15 @@ using namespace osgParticle; -FireEffect::FireEffect() +FireEffect::FireEffect(const osg::Vec3& position, float scale, float intensity) { setDefaults(); + + _position = position; + _scale = scale; + _intensity = intensity; + + buildEffect(); } FireEffect::FireEffect(const FireEffect& copy, const osg::CopyOp& copyop): @@ -37,6 +43,11 @@ FireEffect::FireEffect(const FireEffect& copy, const osg::CopyOp& copyop): } void FireEffect::setDefaults() +{ + ParticleEffect::setDefaults(); +} + +void FireEffect::setUpEmitterAndProgram() { osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem; ps->setDefaultAttributes("Images/smoke.rgb", true, false); @@ -64,27 +75,27 @@ void FireEffect::setDefaults() osg::Vec4(1, 0.0f, 0.f, 0.0f))); // these are physical properties of the particle - ptemplate.setRadius(0.05f); // 5 cm wide particles - ptemplate.setMass(0.01f); // 10g heavy + ptemplate.setRadius(0.05f*_scale); // 5 cm wide particles + ptemplate.setMass(0.01f*_scale); // 10g heavy // assign the particle template to the system. ps->setDefaultParticleTemplate(ptemplate); osgParticle::RandomRateCounter* counter = new osgParticle::RandomRateCounter; - counter->setRateRange(1,10); // generate 1000 particles per second + counter->setRateRange(1*_intensity*_scale,10*_intensity*_scale); // generate 1000 particles per second emitter->setCounter(counter); osgParticle::SectorPlacer* placer = new osgParticle::SectorPlacer; - placer->setCenter(osg::Vec3(0.0,0.0,0.0)); - placer->setRadiusRange(0.0f,0.25f); + placer->setCenter(_position); + placer->setRadiusRange(0.0f*_scale,0.25f*_scale); emitter->setPlacer(placer); osgParticle::RadialShooter* shooter = new osgParticle::RadialShooter; shooter->setThetaRange(0.0f, osg::PI_4); - shooter->setInitialSpeedRange(0.0f,0.0f); + shooter->setInitialSpeedRange(0.0f*_scale,0.0f*_scale); emitter->setShooter(shooter); - emitter->setStartTime(0.0f); + emitter->setStartTime(_startTime); _emitter = emitter; } @@ -108,31 +119,4 @@ void FireEffect::setDefaults() // add the program to the scene graph _program = program; } - - - buildEffect(); -} - -void FireEffect::buildEffect() -{ - // clear the children. - removeChild(0,getNumChildren()); - - if (!_emitter || !_particleSystem || !_program) return; - - // add the emitter - addChild(_emitter.get()); - - // add the program to update the particles - addChild(_program.get()); - - // add the particle system updater. - osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater; - psu->addParticleSystem(_particleSystem.get()); - addChild(psu); - - // add the geode to the scene graph - osg::Geode *geode = new osg::Geode; - geode->addDrawable(_particleSystem.get()); - addChild(geode); } diff --git a/src/osgParticle/ParticleEffect.cpp b/src/osgParticle/ParticleEffect.cpp index 770f23641..b9366842d 100644 --- a/src/osgParticle/ParticleEffect.cpp +++ b/src/osgParticle/ParticleEffect.cpp @@ -12,13 +12,80 @@ */ #include +#include +#include using namespace osgParticle; ParticleEffect::ParticleEffect(const ParticleEffect& copy, const osg::CopyOp& copyop): osg::Group(copy,copyop)/*, - _emitter(), - _program(), _particleSystem(copy._particleSystem.valid()?copy._particleSystem->clone():0)*/ { } + +void ParticleEffect::setPosition(const osg::Vec3& position) +{ + _position = position; +} + +void ParticleEffect::setScale(float scale) +{ + _scale = scale; +} + +void ParticleEffect::setIntensity(float intensity) +{ + _intensity = intensity; +} + +void ParticleEffect::setStartTime(double startTime) +{ + _startTime = startTime; +} + +void ParticleEffect::setDuration(double duration) +{ + _duration = duration; +} + + +void ParticleEffect::setDefaults() +{ + _scale = 1.0f; + _intensity = 1.0f; + _startTime = 0.0; + _duration = 1.0; + _direction.set(0.0f,0.0f,1.0f); +} + +void ParticleEffect::buildEffect() +{ + setUpEmitterAndProgram(); + + Emitter* emitter = getEmitter(); + Program* program = getProgram(); + ParticleSystem* particleSystem = getParticleSystem(); + + if (!emitter || !particleSystem || !program) return; + + + // clear the children. + removeChild(0,getNumChildren()); + + // add the emitter + addChild(emitter); + + // add the program to update the particles + addChild(program); + + // add the particle system updater. + osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater; + psu->addParticleSystem(particleSystem); + addChild(psu); + + // add the geode to the scene graph + osg::Geode *geode = new osg::Geode; + geode->addDrawable(particleSystem); + addChild(geode); +} + diff --git a/src/osgParticle/SmokeEffect.cpp b/src/osgParticle/SmokeEffect.cpp index 85b30bfb5..2b588ed58 100644 --- a/src/osgParticle/SmokeEffect.cpp +++ b/src/osgParticle/SmokeEffect.cpp @@ -13,8 +13,6 @@ #include -#include -#include #include #include #include @@ -26,9 +24,15 @@ using namespace osgParticle; -SmokeEffect::SmokeEffect() +SmokeEffect::SmokeEffect(const osg::Vec3& position, float scale, float intensity) { setDefaults(); + + _position = position; + _scale = scale; + _intensity = intensity; + + buildEffect(); } SmokeEffect::SmokeEffect(const SmokeEffect& copy, const osg::CopyOp& copyop): @@ -37,6 +41,11 @@ SmokeEffect::SmokeEffect(const SmokeEffect& copy, const osg::CopyOp& copyop): } void SmokeEffect::setDefaults() +{ + ParticleEffect::setDefaults(); +} + +void SmokeEffect::setUpEmitterAndProgram() { osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem; @@ -54,35 +63,35 @@ void SmokeEffect::setDefaults() osgParticle::Particle ptemplate; - ptemplate.setLifeTime(10); // 3 seconds of life + ptemplate.setLifeTime(10*_scale); // the following ranges set the envelope of the respective // graphical properties in time. ptemplate.setSizeRange(osgParticle::rangef(0.75f, 3.0f)); - ptemplate.setAlphaRange(osgParticle::rangef(0.0f, 1.0f)); + ptemplate.setAlphaRange(osgParticle::rangef(0.1f, 1.0f)); ptemplate.setColorRange(osgParticle::rangev4( osg::Vec4(1, 1.0f, 1.0f, 1.0f), osg::Vec4(1, 1.0f, 1.f, 0.0f))); // these are physical properties of the particle - ptemplate.setRadius(0.05f); // 5 cm wide particles - ptemplate.setMass(0.01f); // 10g heavy + ptemplate.setRadius(0.05f*_scale); // 5 cm wide particles + ptemplate.setMass(0.01f*_scale); // 10g heavy // assign the particle template to the system. ps->setDefaultParticleTemplate(ptemplate); osgParticle::RandomRateCounter* counter = new osgParticle::RandomRateCounter; - counter->setRateRange(1,2); // generate 1000 particles per second + counter->setRateRange(1*_intensity*_scale,2*_intensity*_scale); // generate 1000 particles per second emitter->setCounter(counter); osgParticle::SectorPlacer* placer = new osgParticle::SectorPlacer; - placer->setCenter(osg::Vec3(0.0,0.0,0.0)); - placer->setRadiusRange(0.0f,0.5f); + placer->setCenter(_position); + placer->setRadiusRange(0.0f*_scale,0.25f*_scale); emitter->setPlacer(placer); osgParticle::RadialShooter* shooter = new osgParticle::RadialShooter; shooter->setThetaRange(0.0f, osg::PI_4); - shooter->setInitialSpeedRange(0.0f,0.0f); + shooter->setInitialSpeedRange(0.0f*_scale,0.0f*_scale); emitter->setShooter(shooter); emitter->setStartTime(0.0f); @@ -108,30 +117,4 @@ void SmokeEffect::setDefaults() _program = program; } - - buildEffect(); -} - -void SmokeEffect::buildEffect() -{ - // clear the children. - removeChild(0,getNumChildren()); - - if (!_emitter || !_particleSystem || !_program) return; - - // add the emitter - addChild(_emitter.get()); - - // add the program to update the particles - addChild(_program.get()); - - // add the particle system updater. - osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater; - psu->addParticleSystem(_particleSystem.get()); - addChild(psu); - - // add the geode to the scene graph - osg::Geode *geode = new osg::Geode; - geode->addDrawable(_particleSystem.get()); - addChild(geode); }