00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00021
00022
00023 #ifndef H_SPK_MODIFIER
00024 #define H_SPK_MODIFIER
00025
00026 #include "Core/SPK_DEF.h"
00027 #include "Core/SPK_Vector3D.h"
00028 #include "Core/SPK_Registerable.h"
00029 #include "Core/SPK_BufferHandler.h"
00030 #include "Core/SPK_Zone.h"
00031 #include "Core/SPK_Particle.h"
00032
00033
00034 namespace SPK
00035 {
00036 class ModifierGroup;
00037
00042 enum ModifierTrigger
00043 {
00044 ALWAYS = 1 << 0,
00045 INSIDE_ZONE = 1 << 1,
00046 OUTSIDE_ZONE = 1 << 2,
00047 INTERSECT_ZONE = 1 << 3,
00048 ENTER_ZONE = 1 << 4,
00049 EXIT_ZONE = 1 << 5,
00050 };
00051
00064 class SPK_PREFIX Modifier : public Registerable,
00065 public Transformable,
00066 public BufferHandler
00067 {
00068 friend class ModifierGroup;
00069 friend class Group;
00070 friend class Particle;
00071
00072 public :
00073
00075
00077
00086 Modifier(int availableTriggers = ALWAYS,ModifierTrigger trigger = ALWAYS,bool needsIntersection = false,bool needsNormal = false,Zone* zone = NULL);
00087
00089
00091
00093 virtual ~Modifier() {}
00094
00096
00098
00108 void setActive(bool active);
00109
00118 void setZone(Zone* zone,bool full = false);
00119
00129 bool setTrigger(ModifierTrigger trigger);
00130
00139 void setLocalToSystem(bool local);
00140
00142
00144
00150 bool isActive() const;
00151
00156 Zone* getZone() const;
00157
00162 ModifierTrigger getTrigger() const;
00163
00168 int getAvailableTriggers() const;
00169
00174 bool isFullZone() const;
00175
00184 bool isLocalToSystem() const;
00185
00187
00189
00190 virtual Registerable* findByName(const std::string& name);
00191
00192 protected :
00193
00195 static Vector3D intersection;
00196
00198 static Vector3D normal;
00199
00201 bool needsIntersection;
00202
00204 bool needsNormal;
00205
00207 ModifierTrigger trigger;
00208
00210 const int availableTriggers;
00211
00212 virtual void registerChildren(bool registerAll);
00213 virtual void copyChildren(const Registerable& object,bool createBase);
00214 virtual void destroyChildren(bool keepChildren);
00215
00216 virtual void propagateUpdateTransform();
00217
00218 private :
00219
00220 Zone* zone;
00221 bool full;
00222
00223 bool active;
00224 mutable bool savedActive;
00225
00226 bool local;
00227
00228 void beginProcess(Group& group);
00229 void endProcess(Group& group);
00230 void process(Particle& particle,float deltaTime) const;
00231
00233
00235
00245 virtual void modify(Particle& particle,float deltaTime) const = 0;
00246
00259 virtual void modifyWrongSide(Particle& particle,bool inside) const {}
00260 };
00261
00262
00263 inline void Modifier::setActive(bool active)
00264 {
00265 this->active = active;
00266 }
00267
00268 inline void Modifier::setLocalToSystem(bool local)
00269 {
00270 this->local = local;
00271 }
00272
00273 inline bool Modifier::isActive() const
00274 {
00275 return active;
00276 }
00277
00278 inline Zone* Modifier::getZone() const
00279 {
00280 return zone;
00281 }
00282
00283 inline ModifierTrigger Modifier::getTrigger() const
00284 {
00285 return trigger;
00286 }
00287
00288 inline int Modifier::getAvailableTriggers() const
00289 {
00290 return availableTriggers;
00291 }
00292
00293 inline bool Modifier::isFullZone() const
00294 {
00295 return full;
00296 }
00297
00298 inline bool Modifier::isLocalToSystem() const
00299 {
00300 return local;
00301 }
00302
00303 inline void Modifier::propagateUpdateTransform()
00304 {
00305 if (zone != NULL)
00306 zone->updateTransform(this);
00307 }
00308
00309 inline void Modifier::endProcess(Group& group)
00310 {
00311 active = savedActive;
00312 }
00313
00314 inline void Modifier::process(Particle& particle,float deltaTime) const
00315 {
00316 switch(trigger)
00317 {
00318 case ALWAYS :
00319 modify(particle,deltaTime);
00320 break;
00321
00322 case INSIDE_ZONE :
00323 if ((zone == NULL)||(zone->contains(particle.position())))
00324 modify(particle,deltaTime);
00325 else
00326 modifyWrongSide(particle,true);
00327 break;
00328
00329 case OUTSIDE_ZONE :
00330 if (zone == NULL)
00331 return;
00332 if (!zone->contains(particle.position()))
00333 modify(particle,deltaTime);
00334 else
00335 modifyWrongSide(particle,false);
00336 break;
00337
00338 case INTERSECT_ZONE :
00339 if (zone == NULL)
00340 return;
00341 if (zone->intersects(particle.oldPosition(),
00342 particle.position(),
00343 needsIntersection ? &intersection : NULL,
00344 needsNormal ? &normal : NULL))
00345 modify(particle,deltaTime);
00346 break;
00347
00348 case ENTER_ZONE :
00349 if (zone == NULL)
00350 return;
00351 if (zone->contains(particle.oldPosition()))
00352 modifyWrongSide(particle,true);
00353 else if (zone->intersects(particle.oldPosition(),
00354 particle.position(),
00355 needsIntersection ? &intersection : NULL,
00356 needsNormal ? &normal : NULL))
00357 modify(particle,deltaTime);
00358 break;
00359
00360 case EXIT_ZONE :
00361 if (zone == NULL)
00362 return;
00363 if (!zone->contains(particle.oldPosition()))
00364 modifyWrongSide(particle,false);
00365 else if (zone->intersects(particle.oldPosition(),
00366 particle.position(),
00367 needsIntersection ? &intersection : NULL,
00368 needsNormal ? &normal : NULL))
00369 modify(particle,deltaTime);
00370 break;
00371 }
00372 }
00373 }
00374
00375 #endif