1 // particles.hxx - classes to manage particles
2 // Copyright (C) 2008 Tiago Gusmão
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License as
6 // published by the Free Software Foundation; either version 2 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #ifndef _SG_PARTICLES_HXX
20 #define _SG_PARTICLES_HXX 1
22 #include <osg/ref_ptr>
23 #include <osgParticle/SmokeTrailEffect>
24 #include <osgParticle/Particle>
25 #include <osgParticle/ModularEmitter>
26 #include <osgDB/ReaderWriter>
27 #include <osgDB/FileNameUtils>
28 #include <osgDB/FileUtils>
29 #include <osgDB/ReadFile>
36 class MatrixTransform;
44 class ParticleSystemUpdater;
47 #include <simgear/scene/util/SGNodeMasks.hxx>
48 #include <simgear/props/props.hxx>
49 #include <simgear/props/condition.hxx>
50 #include <simgear/structure/SGExpression.hxx>
51 #include <simgear/structure/SGSharedPtr.hxx>
52 #include <simgear/math/SGQuat.hxx>
53 #include <simgear/math/SGMatrix.hxx>
56 // Has anyone done anything *really* stupid, like making min and max macros?
64 #include "animation.hxx"
69 class GlobalParticleCallback : public osg::NodeCallback
72 GlobalParticleCallback(const SGPropertyNode* modelRoot)
74 this->modelRoot=modelRoot;
77 virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
79 static const osg::Vec3 &getGravityVector()
84 static const osg::Vec3 &getWindVector()
89 static void setSwitch(const SGPropertyNode* n)
94 static bool getEnabled()
100 static osg::Vec3 gravity;
101 static osg::Vec3 wind;
102 const SGPropertyNode* modelRoot;
103 static SGConstPropertyNode_ptr enabledNode;
109 class Particles : public osg::NodeCallback
114 static osg::Group * appendParticles(const SGPropertyNode* configNode, SGPropertyNode* modelRoot, const osgDB::ReaderWriter::Options* options);
116 virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
118 void setupShooterSpeedData(const SGPropertyNode* configNode,
119 SGPropertyNode* modelRoot)
121 shooterValue = read_value(configNode, modelRoot, "-m",
122 -SGLimitsd::max(), SGLimitsd::max());
124 SG_LOG(SG_GENERAL, SG_ALERT, "shooter property error!\n");
126 shooterExtraRange = configNode->getFloatValue("extrarange",0);
129 void setupCounterData(const SGPropertyNode* configNode,
130 SGPropertyNode* modelRoot)
132 counterValue = read_value(configNode, modelRoot, "-m",
133 -SGLimitsd::max(), SGLimitsd::max());
135 SG_LOG(SG_GENERAL, SG_ALERT, "counter property error!\n");
137 counterExtraRange = configNode->getFloatValue("extrarange",0);
140 void setupCounterCondition(const SGPropertyNode* configNode,
141 SGPropertyNode* modelRoot)
143 counterCond = sgReadCondition(modelRoot, configNode);
146 void setupCounterCondition(float counterStaticValue,
147 float counterStaticExtraRange)
149 this->counterStaticValue = counterStaticValue;
150 this->counterStaticExtraRange = counterStaticExtraRange;
153 void setupStartSizeData(const SGPropertyNode* configNode,
154 SGPropertyNode* modelRoot)
156 startSizeValue = read_value(configNode, modelRoot, "-m",
157 -SGLimitsd::max(), SGLimitsd::max());
160 SG_LOG(SG_GENERAL, SG_ALERT, "startSizeValue error!\n");
164 void setupEndSizeData(const SGPropertyNode* configNode,
165 SGPropertyNode* modelRoot)
167 endSizeValue = read_value(configNode, modelRoot, "-m",
168 -SGLimitsd::max(), SGLimitsd::max());
170 SG_LOG(SG_GENERAL, SG_ALERT, "startSizeValue error!\n");
174 void setupLifeData(const SGPropertyNode* configNode,
175 SGPropertyNode* modelRoot)
177 lifeValue = read_value(configNode, modelRoot, "-m",
178 -SGLimitsd::max(), SGLimitsd::max());
180 SG_LOG(SG_GENERAL, SG_ALERT, "lifeValue error!\n");
184 void setupStaticSizeData(float startSize, float endSize)
186 this->startSize=startSize;
187 this->endSize=endSize;
191 void setGeneralData(osgParticle::RadialShooter* shooter,
192 osgParticle::RandomRateCounter* counter,
193 osgParticle::ParticleSystem* particleSys,
194 osgParticle::FluidProgram* program)
196 this->shooter = shooter;
197 this->counter = counter;
198 this->particleSys = particleSys;
199 this->program = program;
202 void setupProgramGravity(bool useGravity)
204 this->useGravity = useGravity;
207 void setupProgramWind(bool useWind)
209 this->useWind = useWind;
212 //component: r=0, g=1, ... ; color: 0=start color, 1=end color
213 void setupColorComponent(const SGPropertyNode* configNode,
214 SGPropertyNode* modelRoot, int color,
217 SGExpressiond *colorValue = read_value(configNode, modelRoot, "-m",
221 SG_LOG(SG_GENERAL, SG_ALERT, "color property error!\n");
223 colorComponents[(color*4)+component] = colorValue;
224 //number of color components = 4
227 void setupStaticColorComponent(float r1,float g1, float b1, float a1,
228 float r2, float g2, float b2, float a2)
230 staticColorComponents[0] = r1;
231 staticColorComponents[1] = g1;
232 staticColorComponents[2] = b1;
233 staticColorComponents[3] = a1;
234 staticColorComponents[4] = r2;
235 staticColorComponents[5] = g2;
236 staticColorComponents[6] = b2;
237 staticColorComponents[7] = a2;
240 static osg::Group * getCommonRoot();
242 static osg::Geode * getCommonGeode()
244 return commonGeode.get();
247 static osgParticle::ParticleSystemUpdater * getPSU()
253 * Set and get the wind vector for particles in the
254 * atmosphere. This vector is in the Z-up Y-north frame, and the
255 * magnitude is the velocity in meters per second.
257 static void setWindVector(const osg::Vec3& wind) { _wind = wind; }
258 static const osg::Vec3& getWindVector() { return _wind; }
260 float shooterExtraRange;
261 float counterExtraRange;
262 SGSharedPtr<SGExpressiond> shooterValue;
263 SGSharedPtr<SGExpressiond> counterValue;
264 SGSharedPtr<SGExpressiond> colorComponents[8];
265 SGSharedPtr<SGExpressiond> startSizeValue;
266 SGSharedPtr<SGExpressiond> endSizeValue;
267 SGSharedPtr<SGExpressiond> lifeValue;
268 SGSharedPtr<SGCondition> counterCond;
269 float staticColorComponents[8];
272 float counterStaticValue;
273 float counterStaticExtraRange;
274 osg::ref_ptr<osgParticle::RadialShooter> shooter;
275 osg::ref_ptr<osgParticle::RandomRateCounter> counter;
276 osg::ref_ptr<osgParticle::ParticleSystem> particleSys;
277 osg::ref_ptr<osgParticle::FluidProgram> program;
278 osg::ref_ptr<osg::MatrixTransform> particleFrame;
282 static osg::ref_ptr<osgParticle::ParticleSystemUpdater> psu;
283 static osg::ref_ptr<osg::Group> commonRoot;
284 static osg::ref_ptr<osg::Geode> commonGeode;
285 static osg::Vec3 _wind;
292 class CustomModularEmitter : public osgParticle::ModularEmitter, public osg::Observer
296 virtual void objectDeleted (void *)
298 SG_LOG(SG_GENERAL, SG_ALERT, "object deleted!\n");
300 SGParticles::getCommonRoot()->removeChild(this->getParticleSystem()->getParent(0));
301 SGParticles::getPSU()->removeParticleSystem(this->getParticleSystem());
305 // ~CustomModularEmitter()
307 // SG_LOG(SG_GENERAL, SG_ALERT, "object deleted!\n");
309 // SGParticles::getCommonRoot()->removeChild(this->getParticleSystem()->getParent(0));
310 // SGParticles::getPSU()->removeParticleSystem(this->getParticleSystem());