1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 * (at your option) any later version. The full license is in LICENSE file 6 * included with this distribution, and on the openscenegraph.org website. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * OpenSceneGraph Public License for more details. 12 */ 13 14 #include <osgParticle/SmokeTrailEffect> 15 16 #include <osgParticle/ConstantRateCounter> 17 #include <osgParticle/RadialShooter> 18 #include <osgParticle/SectorPlacer> 19 #include <osgParticle/ParticleSystemUpdater> 20 #include <osgParticle/ConnectedParticleSystem> 21 22 #include <osg/Geode> 23 24 using namespace osgParticle; SmokeEffect(bool automaticSetup)25 26 SmokeTrailEffect::SmokeTrailEffect(bool automaticSetup): 27 ParticleEffect(automaticSetup) 28 { 29 setDefaults(); 30 31 _position.set(0.0f,0.0f,0.0f); 32 _scale = 1.0f; 33 _intensity = 1.0f; 34 35 _emitterDuration = 65.0; 36 _defaultParticleTemplate.setLifeTime(5.0*_scale); 37 38 if (_automaticSetup) buildEffect(); 39 } SmokeEffect(const osg::Vec3 & position,float scale,float intensity)40 41 SmokeTrailEffect::SmokeTrailEffect(const osg::Vec3& position, float scale, float intensity) 42 { 43 setDefaults(); 44 45 _position = position; 46 _scale = scale; 47 _intensity = intensity; 48 49 _emitterDuration = 65.0; 50 _defaultParticleTemplate.setLifeTime(5.0*_scale); 51 52 if (_automaticSetup) buildEffect(); 53 } SmokeEffect(const SmokeEffect & copy,const osg::CopyOp & copyop)54 55 SmokeTrailEffect::SmokeTrailEffect(const SmokeTrailEffect& copy, const osg::CopyOp& copyop): 56 ParticleEffect(copy,copyop) 57 { 58 if (_automaticSetup) buildEffect(); 59 } setDefaults()60 61 void SmokeTrailEffect::setDefaults() 62 { 63 ParticleEffect::setDefaults(); 64 65 _textureFileName = "Images/continous_smoke.rgb"; 66 _emitterDuration = 65.0; 67 68 // set up unit particle. 69 _defaultParticleTemplate.setLifeTime(5.0*_scale); 70 _defaultParticleTemplate.setSizeRange(osgParticle::rangef(0.75f, 2.0f)); 71 _defaultParticleTemplate.setAlphaRange(osgParticle::rangef(0.7f, 1.0f)); 72 _defaultParticleTemplate.setColorRange(osgParticle::rangev4( 73 osg::Vec4(1, 1.0f, 1.0f, 1.0f), 74 osg::Vec4(1, 1.0f, 1.f, 0.0f))); 75 76 77 } setUpEmitterAndProgram()78 79 void SmokeTrailEffect::setUpEmitterAndProgram() 80 { 81 // set up particle system 82 if (!_particleSystem) 83 { 84 _particleSystem = new osgParticle::ConnectedParticleSystem; 85 } 86 87 if (_particleSystem.valid()) 88 { 89 _particleSystem->setDefaultAttributes(_textureFileName, false, false); 90 91 osgParticle::Particle& ptemplate = _particleSystem->getDefaultParticleTemplate(); 92 93 float radius = 0.5f*_scale; 94 float density = 1.0f; // 1.0kg/m^3 95 96 ptemplate.setLifeTime(_defaultParticleTemplate.getLifeTime()); 97 98 // the following ranges set the envelope of the respective 99 // graphical properties in time. 100 ptemplate.setSizeRange(osgParticle::rangef(radius*_defaultParticleTemplate.getSizeRange().minimum, 101 radius*_defaultParticleTemplate.getSizeRange().maximum)); 102 ptemplate.setAlphaRange(_defaultParticleTemplate.getAlphaRange()); 103 ptemplate.setColorRange(_defaultParticleTemplate.getColorRange()); 104 105 // these are physical properties of the particle 106 ptemplate.setRadius(radius); 107 ptemplate.setMass(density*radius*radius*radius*osg::PI*4.0f/3.0f); 108 109 } 110 111 112 // set up emitter 113 if (!_emitter) 114 { 115 _emitter = new osgParticle::ModularEmitter; 116 _emitter->setCounter(new osgParticle::ConstantRateCounter); 117 _emitter->setPlacer(new osgParticle::SectorPlacer); 118 _emitter->setShooter(new osgParticle::RadialShooter); 119 } 120 121 if (_emitter.valid()) 122 { 123 _emitter->setParticleSystem(_particleSystem.get()); 124 _emitter->setReferenceFrame(_useLocalParticleSystem? 125 osgParticle::ParticleProcessor::ABSOLUTE_RF: 126 osgParticle::ParticleProcessor::RELATIVE_RF); 127 128 _emitter->setStartTime(_startTime); 129 _emitter->setLifeTime(_emitterDuration); 130 _emitter->setEndless(false); 131 132 osgParticle::ConstantRateCounter* counter = dynamic_cast<osgParticle::ConstantRateCounter*>(_emitter->getCounter()); 133 if (counter) 134 { 135 counter->setMinimumNumberOfParticlesToCreate(1); 136 counter->setNumberOfParticlesPerSecondToCreate(0.0); 137 } 138 139 osgParticle::SectorPlacer* placer = dynamic_cast<osgParticle::SectorPlacer*>(_emitter->getPlacer()); 140 if (placer) 141 { 142 placer->setCenter(_position); 143 placer->setRadiusRange(0.0f*_scale,0.0f*_scale); 144 } 145 146 osgParticle::RadialShooter* shooter = dynamic_cast<osgParticle::RadialShooter*>(_emitter->getShooter()); 147 if (shooter) 148 { 149 shooter->setThetaRange(0.0f, 0.0f); 150 shooter->setInitialSpeedRange(0.0f*_scale,0.0f*_scale); 151 } 152 } 153 154 // set up program. 155 if (!_program) 156 { 157 _program = new osgParticle::FluidProgram; 158 } 159 160 if (_program.valid()) 161 { 162 _program->setParticleSystem(_particleSystem.get()); 163 _program->setWind(_wind); 164 } 165 } 166