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/ExplosionEffect>
15
16 #include <osgParticle/ExplosionEffect>
17 #include <osgParticle/ModularEmitter>
18 #include <osgParticle/ModularProgram>
19 #include <osgParticle/RandomRateCounter>
20 #include <osgParticle/SectorPlacer>
21 #include <osgParticle/RadialShooter>
22 #include <osgParticle/AccelOperator>
23 #include <osgParticle/FluidFrictionOperator>
24 #include <osgParticle/ParticleSystemUpdater>
25
26 #include <osg/Geode>
27
28 using namespace osgParticle;
29
ExplosionEffect(bool automaticSetup)30 ExplosionEffect::ExplosionEffect(bool automaticSetup):
31 ParticleEffect(automaticSetup)
32 {
33 setDefaults();
34
35 _position.set(0.0f,0.0f,0.0f);
36 _scale = 1.0f;
37 _intensity = 1.0f;
38
39 _emitterDuration = 1.0;
40
41 if (_automaticSetup) buildEffect();
42 }
43
ExplosionEffect(const osg::Vec3 & position,float scale,float intensity)44 ExplosionEffect::ExplosionEffect(const osg::Vec3& position, float scale, float intensity)
45 {
46 setDefaults();
47
48 _position = position;
49 _scale = scale;
50 _intensity = intensity;
51
52 _emitterDuration = 1.0;
53
54 if (_automaticSetup) buildEffect();
55 }
56
ExplosionEffect(const ExplosionEffect & copy,const osg::CopyOp & copyop)57 ExplosionEffect::ExplosionEffect(const ExplosionEffect& copy, const osg::CopyOp& copyop):
58 ParticleEffect(copy,copyop)
59 {
60 if (_automaticSetup) buildEffect();
61 }
62
setDefaults()63 void ExplosionEffect::setDefaults()
64 {
65 ParticleEffect::setDefaults();
66
67 _textureFileName = "Images/smoke.rgb";
68 _emitterDuration = 1.0;
69
70 // set up unit particle.
71 _defaultParticleTemplate.setLifeTime(0.5+0.1*_scale);
72 _defaultParticleTemplate.setSizeRange(osgParticle::rangef(0.75f, 3.0f));
73 _defaultParticleTemplate.setAlphaRange(osgParticle::rangef(0.1f, 1.0f));
74 _defaultParticleTemplate.setColorRange(osgParticle::rangev4(
75 osg::Vec4(1.0f, 0.8f, 0.2f, 1.0f),
76 osg::Vec4(1.0f, 0.4f, 0.1f, 0.0f)));
77
78 }
79
80
setUpEmitterAndProgram()81 void ExplosionEffect::setUpEmitterAndProgram()
82 {
83 // set up particle system
84 if (!_particleSystem)
85 {
86 _particleSystem = new osgParticle::ParticleSystem;
87 }
88
89 if (_particleSystem.valid())
90 {
91 _particleSystem->setDefaultAttributes(_textureFileName, false, false);
92
93 osgParticle::Particle& ptemplate = _particleSystem->getDefaultParticleTemplate();
94
95 float radius = 0.4f*_scale;
96 float density = 1.2f; // 1.0kg/m^3
97
98 ptemplate.setLifeTime(_defaultParticleTemplate.getLifeTime());
99
100 // the following ranges set the envelope of the respective
101 // graphical properties in time.
102 ptemplate.setSizeRange(osgParticle::rangef(radius*_defaultParticleTemplate.getSizeRange().minimum,
103 radius*_defaultParticleTemplate.getSizeRange().maximum));
104 ptemplate.setAlphaRange(_defaultParticleTemplate.getAlphaRange());
105 ptemplate.setColorRange(_defaultParticleTemplate.getColorRange());
106
107 // these are physical properties of the particle
108 ptemplate.setRadius(radius);
109 ptemplate.setMass(density*radius*radius*radius*osg::PI*4.0f/3.0f);
110
111 }
112
113
114 // set up emitter
115 if (!_emitter)
116 {
117 _emitter = new osgParticle::ModularEmitter;
118 _emitter->setCounter(new osgParticle::RandomRateCounter);
119 _emitter->setPlacer(new osgParticle::SectorPlacer);
120 _emitter->setShooter(new osgParticle::RadialShooter);
121 }
122
123 if (_emitter.valid())
124 {
125 _emitter->setParticleSystem(_particleSystem.get());
126 _emitter->setReferenceFrame(_useLocalParticleSystem?
127 osgParticle::ParticleProcessor::ABSOLUTE_RF:
128 osgParticle::ParticleProcessor::RELATIVE_RF);
129
130 _emitter->setStartTime(_startTime);
131 _emitter->setLifeTime(_emitterDuration);
132 _emitter->setEndless(false);
133
134 osgParticle::RandomRateCounter* counter = dynamic_cast<osgParticle::RandomRateCounter*>(_emitter->getCounter());
135 if (counter)
136 {
137 counter->setRateRange(50*_intensity,100*_intensity);
138 }
139
140 osgParticle::SectorPlacer* placer = dynamic_cast<osgParticle::SectorPlacer*>(_emitter->getPlacer());
141 if (placer)
142 {
143 placer->setCenter(_position);
144 placer->setRadiusRange(0.0f*_scale,0.25f*_scale);
145 }
146
147 osgParticle::RadialShooter* shooter = dynamic_cast<osgParticle::RadialShooter*>(_emitter->getShooter());
148 if (shooter)
149 {
150 shooter->setThetaRange(0.0f, osg::PI_2);
151 shooter->setInitialSpeedRange(1.0f*_scale,10.0f*_scale);
152 }
153 }
154
155 // set up the program
156 if (!_program)
157 {
158 _program = new osgParticle::FluidProgram;
159 }
160
161 if (_program.valid())
162 {
163 _program->setParticleSystem(_particleSystem.get());
164 _program->setWind(_wind);
165 }
166
167 }
168
169