00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _SG_PARTICLES_HXX
00020 #define _SG_PARTICLES_HXX 1
00021
00022 #include <osg/ref_ptr>
00023 #include <osgParticle/SmokeTrailEffect>
00024 #include <osgParticle/Particle>
00025 #include <osgParticle/ModularEmitter>
00026 #include <osgDB/ReaderWriter>
00027 #include <osgDB/FileNameUtils>
00028 #include <osgDB/FileUtils>
00029 #include <osgDB/ReadFile>
00030 #include <osg/Notify>
00031 #include <osg/Vec3>
00032
00033 namespace osg
00034 {
00035 class Group;
00036 class MatrixTransform;
00037 class Node;
00038 class NodeVisitor;
00039 }
00040
00041 namespace osgParticle
00042 {
00043 class ParticleSystem;
00044 class ParticleSystemUpdater;
00045 }
00046
00047 #include <simgear/scene/util/SGNodeMasks.hxx>
00048 #include <simgear/props/props.hxx>
00049 #include <simgear/props/condition.hxx>
00050 #include <simgear/structure/SGExpression.hxx>
00051 #include <simgear/structure/SGSharedPtr.hxx>
00052 #include <simgear/math/SGQuat.hxx>
00053 #include <simgear/math/SGMatrix.hxx>
00054
00055
00056
00057 #ifdef min
00058 #undef min
00059 #endif
00060 #ifdef max
00061 #undef max
00062 #endif
00063
00064 #include "animation.hxx"
00065
00066 namespace simgear
00067 {
00068
00069 class GlobalParticleCallback : public osg::NodeCallback
00070 {
00071 public:
00072 GlobalParticleCallback(const SGPropertyNode* modelRoot)
00073 {
00074 this->modelRoot=modelRoot;
00075 }
00076
00077 virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
00078
00079 static const osg::Vec3 &getGravityVector()
00080 {
00081 return gravity;
00082 }
00083
00084 static const osg::Vec3 &getWindVector()
00085 {
00086 return wind;
00087 }
00088
00089 static void setSwitch(const SGPropertyNode* n)
00090 {
00091 enabledNode = n;
00092 }
00093
00094 static bool getEnabled()
00095 {
00096 return enabled;
00097 }
00098
00099 private:
00100 static osg::Vec3 gravity;
00101 static osg::Vec3 wind;
00102 const SGPropertyNode* modelRoot;
00103 static SGConstPropertyNode_ptr enabledNode;
00104 static bool enabled;
00105 };
00106
00107
00108
00109 class Particles : public osg::NodeCallback
00110 {
00111 public:
00112 Particles();
00113
00114 static osg::Group * appendParticles(const SGPropertyNode* configNode, SGPropertyNode* modelRoot, const osgDB::ReaderWriter::Options* options);
00115
00116 virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
00117
00118 void setupShooterSpeedData(const SGPropertyNode* configNode,
00119 SGPropertyNode* modelRoot)
00120 {
00121 shooterValue = read_value(configNode, modelRoot, "-m",
00122 -SGLimitsd::max(), SGLimitsd::max());
00123 if(!shooterValue){
00124 SG_LOG(SG_GENERAL, SG_ALERT, "shooter property error!\n");
00125 }
00126 shooterExtraRange = configNode->getFloatValue("extrarange",0);
00127 }
00128
00129 void setupCounterData(const SGPropertyNode* configNode,
00130 SGPropertyNode* modelRoot)
00131 {
00132 counterValue = read_value(configNode, modelRoot, "-m",
00133 -SGLimitsd::max(), SGLimitsd::max());
00134 if(!counterValue){
00135 SG_LOG(SG_GENERAL, SG_ALERT, "counter property error!\n");
00136 }
00137 counterExtraRange = configNode->getFloatValue("extrarange",0);
00138 }
00139
00140 void setupCounterCondition(const SGPropertyNode* configNode,
00141 SGPropertyNode* modelRoot)
00142 {
00143 counterCond = sgReadCondition(modelRoot, configNode);
00144 }
00145
00146 void setupCounterCondition(float counterStaticValue,
00147 float counterStaticExtraRange)
00148 {
00149 this->counterStaticValue = counterStaticValue;
00150 this->counterStaticExtraRange = counterStaticExtraRange;
00151 }
00152
00153 void setupStartSizeData(const SGPropertyNode* configNode,
00154 SGPropertyNode* modelRoot)
00155 {
00156 startSizeValue = read_value(configNode, modelRoot, "-m",
00157 -SGLimitsd::max(), SGLimitsd::max());
00158 if(!startSizeValue)
00159 {
00160 SG_LOG(SG_GENERAL, SG_ALERT, "startSizeValue error!\n");
00161 }
00162 }
00163
00164 void setupEndSizeData(const SGPropertyNode* configNode,
00165 SGPropertyNode* modelRoot)
00166 {
00167 endSizeValue = read_value(configNode, modelRoot, "-m",
00168 -SGLimitsd::max(), SGLimitsd::max());
00169 if(!endSizeValue){
00170 SG_LOG(SG_GENERAL, SG_ALERT, "startSizeValue error!\n");
00171 }
00172 }
00173
00174 void setupLifeData(const SGPropertyNode* configNode,
00175 SGPropertyNode* modelRoot)
00176 {
00177 lifeValue = read_value(configNode, modelRoot, "-m",
00178 -SGLimitsd::max(), SGLimitsd::max());
00179 if(!lifeValue){
00180 SG_LOG(SG_GENERAL, SG_ALERT, "lifeValue error!\n");
00181 }
00182 }
00183
00184 void setupStaticSizeData(float startSize, float endSize)
00185 {
00186 this->startSize=startSize;
00187 this->endSize=endSize;
00188 }
00189
00190
00191 void setGeneralData(osgParticle::RadialShooter* shooter,
00192 osgParticle::RandomRateCounter* counter,
00193 osgParticle::ParticleSystem* particleSys,
00194 osgParticle::FluidProgram* program)
00195 {
00196 this->shooter = shooter;
00197 this->counter = counter;
00198 this->particleSys = particleSys;
00199 this->program = program;
00200 }
00201
00202 void setupProgramGravity(bool useGravity)
00203 {
00204 this->useGravity = useGravity;
00205 }
00206
00207 void setupProgramWind(bool useWind)
00208 {
00209 this->useWind = useWind;
00210 }
00211
00212
00213 void setupColorComponent(const SGPropertyNode* configNode,
00214 SGPropertyNode* modelRoot, int color,
00215 int component)
00216 {
00217 SGExpressiond *colorValue = read_value(configNode, modelRoot, "-m",
00218 -SGLimitsd::max(),
00219 SGLimitsd::max());
00220 if(!colorValue){
00221 SG_LOG(SG_GENERAL, SG_ALERT, "color property error!\n");
00222 }
00223 colorComponents[(color*4)+component] = colorValue;
00224
00225 }
00226
00227 void setupStaticColorComponent(float r1,float g1, float b1, float a1,
00228 float r2, float g2, float b2, float a2)
00229 {
00230 staticColorComponents[0] = r1;
00231 staticColorComponents[1] = g1;
00232 staticColorComponents[2] = b1;
00233 staticColorComponents[3] = a1;
00234 staticColorComponents[4] = r2;
00235 staticColorComponents[5] = g2;
00236 staticColorComponents[6] = b2;
00237 staticColorComponents[7] = a2;
00238 }
00239
00240 static osg::Group * getCommonRoot();
00241
00242 static osg::Geode * getCommonGeode()
00243 {
00244 return commonGeode.get();
00245 }
00246
00247 static osgParticle::ParticleSystemUpdater * getPSU()
00248 {
00249 return psu.get();
00250 }
00251
00257 static void setWindVector(const osg::Vec3& wind) { _wind = wind; }
00258 static const osg::Vec3& getWindVector() { return _wind; }
00259 protected:
00260 float shooterExtraRange;
00261 float counterExtraRange;
00262 SGSharedPtr<SGExpressiond> shooterValue;
00263 SGSharedPtr<SGExpressiond> counterValue;
00264 SGSharedPtr<SGExpressiond> colorComponents[8];
00265 SGSharedPtr<SGExpressiond> startSizeValue;
00266 SGSharedPtr<SGExpressiond> endSizeValue;
00267 SGSharedPtr<SGExpressiond> lifeValue;
00268 SGSharedPtr<SGCondition> counterCond;
00269 float staticColorComponents[8];
00270 float startSize;
00271 float endSize;
00272 float counterStaticValue;
00273 float counterStaticExtraRange;
00274 osg::ref_ptr<osgParticle::RadialShooter> shooter;
00275 osg::ref_ptr<osgParticle::RandomRateCounter> counter;
00276 osg::ref_ptr<osgParticle::ParticleSystem> particleSys;
00277 osg::ref_ptr<osgParticle::FluidProgram> program;
00278 osg::ref_ptr<osg::MatrixTransform> particleFrame;
00279
00280 bool useGravity;
00281 bool useWind;
00282 static osg::ref_ptr<osgParticle::ParticleSystemUpdater> psu;
00283 static osg::ref_ptr<osg::Group> commonRoot;
00284 static osg::ref_ptr<osg::Geode> commonGeode;
00285 static osg::Vec3 _wind;
00286 };
00287 }
00288 #endif
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313