Improved ParticleEffects

This commit is contained in:
Robert Osfield
2005-04-04 07:54:52 +00:00
parent e4580f2028
commit 22e446dbc9
25 changed files with 917 additions and 289 deletions

View File

@@ -35,6 +35,9 @@ ExplosionEffect::ExplosionEffect(const osg::Vec3& position, float scale, float i
_scale = scale;
_intensity = intensity;
_emitterDuration = 1.0;
_particleDuration = 0.5+0.1*_scale;
buildEffect();
}
@@ -46,83 +49,98 @@ ExplosionEffect::ExplosionEffect(const ExplosionEffect& copy, const osg::CopyOp&
void ExplosionEffect::setDefaults()
{
ParticleEffect::setDefaults();
_emitterDuration = 1.0;
_particleDuration = 0.5+0.1*_scale;
}
void ExplosionEffect::setUpEmitterAndProgram()
{
osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem;
ps->setDefaultAttributes("Images/particle.rgb", false, false);
_particleSystem = ps;
//_particleSystem->setUseIntialViewMatrix(true);
// set up the emitter
// set up particle system
if (!_particleSystem)
{
osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter;
emitter->setParticleSystem(ps);
emitter->setReferenceFrame(osgParticle::ParticleProcessor::ABSOLUTE_RF);
_particleSystem = new osgParticle::ParticleSystem;
}
osgParticle::Particle ptemplate;
if (_particleSystem.valid())
{
_particleSystem->setDefaultAttributes("Images/smoke.rgb", false, false);
ptemplate.setLifeTime(3); // 3 seconds of life
osgParticle::Particle& ptemplate = _particleSystem->getDefaultParticleTemplate();
ptemplate.setLifeTime(_particleDuration);
float radius = 0.4f*_scale;
float density = 1.2f; // 1.0kg/m^3
// 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.setSizeRange(osgParticle::rangef(radius*0.75f, radius*3.0f));
ptemplate.setAlphaRange(osgParticle::rangef(0.1f, 1.0f));
ptemplate.setColorRange(osgParticle::rangev4(
osg::Vec4(1, 1.0f, 0.0f, 1.0f),
osg::Vec4(0.5, 0.5f, 0.0f, 0.0f)));
osg::Vec4(1.0f, 0.8f, 0.2f, 1.0f),
osg::Vec4(1.0f, 0.4f, 0.1f, 0.0f)));
// these are physical properties of the particle
ptemplate.setRadius(0.1f*_scale); // 5 cm wide particles
ptemplate.setMass(1.0f*_scale); // 1kg heavy
ptemplate.setRadius(radius); // 5 cm wide particles
ptemplate.setMass(density*osg::PI*4.0f*radius*radius*radius/3.0f);
// 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*_intensity,2000*_intensity); // generate 1000 particles per second
emitter->setCounter(counter);
osgParticle::SectorPlacer* placer = new osgParticle::SectorPlacer;
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*_scale,30.0f*_scale);
emitter->setShooter(shooter);
emitter->setStartTime(_startTime);
emitter->setResetTime(5.0f);
emitter->setLifeTime(0.1f);
emitter->setEndless(false);
_emitter = emitter;
// set up emitter
if (!_emitter)
{
_emitter = new osgParticle::ModularEmitter;
_emitter->setCounter(new osgParticle::RandomRateCounter);
_emitter->setPlacer(new osgParticle::SectorPlacer);
_emitter->setShooter(new osgParticle::RadialShooter);
}
if (_emitter.valid())
{
_emitter->setParticleSystem(_particleSystem.get());
_emitter->setReferenceFrame(_useLocalParticleSystem?
osgParticle::ParticleProcessor::ABSOLUTE_RF:
osgParticle::ParticleProcessor::RELATIVE_RF);
_emitter->setStartTime(_startTime);
_emitter->setLifeTime(_emitterDuration);
_emitter->setEndless(false);
osgParticle::RandomRateCounter* counter = dynamic_cast<osgParticle::RandomRateCounter*>(_emitter->getCounter());
if (counter)
{
counter->setRateRange(50*_intensity,100*_intensity);
}
osgParticle::SectorPlacer* placer = dynamic_cast<osgParticle::SectorPlacer*>(_emitter->getPlacer());
if (placer)
{
placer->setCenter(_position);
placer->setRadiusRange(0.0f*_scale,0.25f*_scale);
}
osgParticle::RadialShooter* shooter = dynamic_cast<osgParticle::RadialShooter*>(_emitter->getShooter());
if (shooter)
{
shooter->setThetaRange(0.0f, osg::PI_2);
shooter->setInitialSpeedRange(1.0f*_scale,10.0f*_scale);
}
}
// set up the program
{
osgParticle::ModularProgram *program = new osgParticle::ModularProgram;
program->setParticleSystem(ps);
// create an operator that simulates the gravity acceleration.
osgParticle::AccelOperator *op1 = new osgParticle::AccelOperator;
op1->setToGravity();
program->addOperator(op1);
// let's add a fluid operator to simulate air friction.
osgParticle::FluidFrictionOperator *op3 = new osgParticle::FluidFrictionOperator;
op3->setFluidToAir();
program->addOperator(op3);
_program = program;
if (!_program)
{
_program = new osgParticle::FluidProgram;
}
if (_program.valid())
{
_program->setParticleSystem(_particleSystem.get());
_program->setWind(_wind);
}
}