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()
90 static osg::Vec3 gravity;
91 static osg::Vec3 wind;
92 const SGPropertyNode* modelRoot;
97 class Particles : public osg::NodeCallback
102 static osg::Group * appendParticles(const SGPropertyNode* configNode, SGPropertyNode* modelRoot, const osgDB::ReaderWriter::Options* options);
104 virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
106 void setupShooterSpeedData(const SGPropertyNode* configNode,
107 SGPropertyNode* modelRoot)
109 shooterValue = read_value(configNode, modelRoot, "-m",
110 -SGLimitsd::max(), SGLimitsd::max());
112 SG_LOG(SG_GENERAL, SG_ALERT, "shooter property error!\n");
114 shooterExtraRange = configNode->getFloatValue("extrarange",0);
117 void setupCounterData(const SGPropertyNode* configNode,
118 SGPropertyNode* modelRoot)
120 counterValue = read_value(configNode, modelRoot, "-m",
121 -SGLimitsd::max(), SGLimitsd::max());
123 SG_LOG(SG_GENERAL, SG_ALERT, "counter property error!\n");
125 counterExtraRange = configNode->getFloatValue("extrarange",0);
128 void setupCounterCondition(const SGPropertyNode* configNode,
129 SGPropertyNode* modelRoot)
131 counterCond = sgReadCondition(modelRoot, configNode);
134 void setupCounterCondition(float counterStaticValue,
135 float counterStaticExtraRange)
137 this->counterStaticValue = counterStaticValue;
138 this->counterStaticExtraRange = counterStaticExtraRange;
141 void setupStartSizeData(const SGPropertyNode* configNode,
142 SGPropertyNode* modelRoot)
144 startSizeValue = read_value(configNode, modelRoot, "-m",
145 -SGLimitsd::max(), SGLimitsd::max());
148 SG_LOG(SG_GENERAL, SG_ALERT, "startSizeValue error!\n");
152 void setupEndSizeData(const SGPropertyNode* configNode,
153 SGPropertyNode* modelRoot)
155 endSizeValue = read_value(configNode, modelRoot, "-m",
156 -SGLimitsd::max(), SGLimitsd::max());
158 SG_LOG(SG_GENERAL, SG_ALERT, "startSizeValue error!\n");
162 void setupLifeData(const SGPropertyNode* configNode,
163 SGPropertyNode* modelRoot)
165 lifeValue = read_value(configNode, modelRoot, "-m",
166 -SGLimitsd::max(), SGLimitsd::max());
168 SG_LOG(SG_GENERAL, SG_ALERT, "lifeValue error!\n");
172 void setupStaticSizeData(float startSize, float endSize)
174 this->startSize=startSize;
175 this->endSize=endSize;
179 void setGeneralData(osgParticle::RadialShooter* shooter,
180 osgParticle::RandomRateCounter* counter,
181 osgParticle::ParticleSystem* particleSys,
182 osgParticle::FluidProgram* program)
184 this->shooter = shooter;
185 this->counter = counter;
186 this->particleSys = particleSys;
187 this->program = program;
190 void setupProgramGravity(bool useGravity)
192 this->useGravity = useGravity;
195 void setupProgramWind(bool useWind)
197 this->useWind = useWind;
200 //component: r=0, g=1, ... ; color: 0=start color, 1=end color
201 void setupColorComponent(const SGPropertyNode* configNode,
202 SGPropertyNode* modelRoot, int color,
205 SGExpressiond *colorValue = read_value(configNode, modelRoot, "-m",
209 SG_LOG(SG_GENERAL, SG_ALERT, "color property error!\n");
211 colorComponents[(color*4)+component] = colorValue;
212 //number of color components = 4
215 void setupStaticColorComponent(float r1,float g1, float b1, float a1,
216 float r2, float g2, float b2, float a2)
218 staticColorComponents[0] = r1;
219 staticColorComponents[1] = g1;
220 staticColorComponents[2] = b1;
221 staticColorComponents[3] = a1;
222 staticColorComponents[4] = r2;
223 staticColorComponents[5] = g2;
224 staticColorComponents[6] = b2;
225 staticColorComponents[7] = a2;
228 static osg::Group * getCommonRoot();
230 static osg::Geode * getCommonGeode()
232 return commonGeode.get();
235 static osgParticle::ParticleSystemUpdater * getPSU()
241 * Set and get the wind vector for particles in the
242 * atmosphere. This vector is in the Z-up Y-north frame, and the
243 * magnitude is the velocity in meters per second.
245 static void setWindVector(const osg::Vec3& wind) { _wind = wind; }
246 static const osg::Vec3& getWindVector() { return _wind; }
248 float shooterExtraRange;
249 float counterExtraRange;
250 SGSharedPtr<SGExpressiond> shooterValue;
251 SGSharedPtr<SGExpressiond> counterValue;
252 SGSharedPtr<SGExpressiond> colorComponents[8];
253 SGSharedPtr<SGExpressiond> startSizeValue;
254 SGSharedPtr<SGExpressiond> endSizeValue;
255 SGSharedPtr<SGExpressiond> lifeValue;
256 SGSharedPtr<SGCondition> counterCond;
257 float staticColorComponents[8];
260 float counterStaticValue;
261 float counterStaticExtraRange;
262 osg::ref_ptr<osgParticle::RadialShooter> shooter;
263 osg::ref_ptr<osgParticle::RandomRateCounter> counter;
264 osg::ref_ptr<osgParticle::ParticleSystem> particleSys;
265 osg::ref_ptr<osgParticle::FluidProgram> program;
266 osg::ref_ptr<osg::MatrixTransform> particleFrame;
270 static osg::ref_ptr<osgParticle::ParticleSystemUpdater> psu;
271 static osg::ref_ptr<osg::Group> commonRoot;
272 static osg::ref_ptr<osg::Geode> commonGeode;
273 static osg::Vec3 _wind;
280 class CustomModularEmitter : public osgParticle::ModularEmitter, public osg::Observer
284 virtual void objectDeleted (void *)
286 SG_LOG(SG_GENERAL, SG_ALERT, "object deleted!\n");
288 SGParticles::getCommonRoot()->removeChild(this->getParticleSystem()->getParent(0));
289 SGParticles::getPSU()->removeParticleSystem(this->getParticleSystem());
293 // ~CustomModularEmitter()
295 // SG_LOG(SG_GENERAL, SG_ALERT, "object deleted!\n");
297 // SGParticles::getCommonRoot()->removeChild(this->getParticleSystem()->getParent(0));
298 // SGParticles::getPSU()->removeParticleSystem(this->getParticleSystem());