00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_PARTICLE_SYSTEM_LOCATED_H
00027 #define NL_PARTICLE_SYSTEM_LOCATED_H
00028
00029 #include <stack>
00030
00031 #include "nel/misc/types_nl.h"
00032 #include "nel/misc/vector.h"
00033 #include "3d/particle_system_process.h"
00034 #include "3d/ps_attrib.h"
00035 #include "3d/ps_lod.h"
00036 #include "nel/misc/stream.h"
00037
00038 namespace NLMISC
00039 {
00040 class CAABBox;
00041 class CMatrix;
00042 }
00043
00044
00045
00046
00047
00048
00049 namespace NL3D
00050 {
00051
00052
00053
00054 template <class T> class CPSAttribMaker;
00055
00056
00057 class CPSLocatedBindable;
00058 class CPSTargetLocatedBindable;
00059 class CPSZone;
00060 class CPSForce;
00061 class IDriver;
00062 class CFontManager;
00063 class CFontGenerator;
00064 class CScene;
00065
00066
00067 const uint32 DefaultMaxLocatedInstance = 1;
00068
00069
00070
00073
00074 struct CPSCollisionInfo
00075 {
00076
00077 float TimeSliceRatio;
00082
00083 float dist;
00084
00085 NLMISC::CVector newPos, newSpeed;
00086
00091 CPSZone *collisionZone;
00092
00093 CPSCollisionInfo()
00094 {
00095 reset();
00096 }
00097 void reset(void)
00098 {
00099 dist = -1;
00100 TimeSliceRatio = 1.0f;
00101 }
00102
00103 void serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00104 {
00105 f.serialVersion(1);
00106 f.serial(dist, newPos, newSpeed);
00107 }
00108 };
00109
00110
00112 typedef CPSAttrib<CPSCollisionInfo> TPSAttribCollisionInfo;
00113
00114
00115
00116
00117
00128 class CPSLocated : public CParticleSystemProcess
00129 {
00130 public:
00132 CPSLocated();
00133
00135
00136 virtual ~CPSLocated();
00137
00142 void bind(CPSLocatedBindable *lb);
00143
00148 CPSLocatedBindable *unbind(uint index);
00149
00151 bool isBound(const CPSLocatedBindable *lb) const;
00152
00156 uint getIndexOf(const CPSLocatedBindable *lb) const;
00157
00162 void remove(const CPSLocatedBindable *lb);
00163
00168 virtual void releaseRefTo(const CParticleSystemProcess *other);
00169
00174 virtual void releaseAllRef();
00175
00176
00180 uint32 getNbBoundObjects(void) const { return _LocatedBoundCont.size(); }
00181
00185 const CPSLocatedBindable *getBoundObject(uint32 index) const
00186 {
00187 nlassert(index < _LocatedBoundCont.size());
00188 return _LocatedBoundCont[index];
00189 }
00190
00191
00195 CPSLocatedBindable *getBoundObject(uint32 index)
00196 {
00197 nlassert(index < _LocatedBoundCont.size());
00198 return _LocatedBoundCont[index];
00199 }
00200
00201
00217 sint32 newElement(const NLMISC::CVector &pos = NLMISC::CVector::Null,
00218 const NLMISC::CVector &speed = NLMISC::CVector::Null,
00219 CPSLocated *emitterLocated = NULL,
00220 uint32 indexInEmitter = 0,
00221 bool basisConversionForSpeed = true,
00222 TAnimationTime ellapsedTime = 0.f);
00223
00224
00230 void deleteElement(uint32 index);
00231
00232
00234 CScene *getScene(void);
00235
00237 void getLODVect(NLMISC::CVector &v, float &offset, bool systemBasis);
00238
00239
00243 void incrementNbDrawnParticles(uint num);
00244
00245
00252 uint32 getNewElementIndex(void) const { return _Size; }
00253
00254
00260 bool computeBBox(NLMISC::CAABBox &aabbox) const;
00261
00262
00263
00268 void setInitialLife(TAnimationTime lifeTime);
00269
00275 void setLifeScheme(CPSAttribMaker<float> *scheme);
00276
00278 TAnimationTime getInitialLife(void) const { return _InitialLife; }
00279
00281 CPSAttribMaker<float> *getLifeScheme(void) { return _LifeScheme; }
00282 const CPSAttribMaker<float> *getLifeScheme(void) const { return _LifeScheme; }
00283
00284
00288 void setInitialMass(float mass);
00289
00294 void setMassScheme(CPSAttribMaker<float> *scheme);
00295
00297 float getInitialMass(void) const { return _InitialMass; }
00298
00300 CPSAttribMaker<float> *getMassScheme(void) { return _MassScheme; }
00301 const CPSAttribMaker<float> *getMassScheme(void) const { return _MassScheme; }
00302
00303
00304
00306 void setLastForever(void)
00307 {
00308 _LastForever = true;
00309 }
00311 bool getLastForever(void) const { return _LastForever; }
00312
00314 TPSAttribFloat &getInvMass(void) { return _InvMass; }
00316 const TPSAttribFloat &getInvMass(void) const { return _InvMass; }
00317
00319 TPSAttribVector &getPos(void) { return _Pos; }
00321 const TPSAttribVector &getPos(void) const { return _Pos; }
00322
00324 TPSAttribVector &getSpeed(void) { return _Speed; }
00326 const TPSAttribVector &getSpeed(void) const { return _Speed; }
00327
00329 TPSAttribTime &getTime(void) { return _Time; }
00331 const TPSAttribTime &getTime(void) const { return _Time; }
00332
00334 TPSAttribTime &getTimeIncrement(void) { return _TimeIncrement; }
00336 const TPSAttribTime &getTimeIncrement(void) const { return _TimeIncrement; }
00337
00341 virtual void step(TPSProcessPass pass, TAnimationTime ellapsedTime, TAnimationTime realEt);
00342
00343
00344
00346 uint32 getSize(void) const
00347 {
00348 return _Size;
00349 }
00350
00354 uint32 getMaxSize(void) const
00355 {
00356 return _MaxSize;
00357 }
00358
00364 void setFrameRate(uint32 nbFramesToSkip = 0) { _NbFramesToSkip = nbFramesToSkip; }
00365
00366
00367 uint32 getFrameRate(void) const { return _NbFramesToSkip; }
00368
00369
00373 void resize(uint32 newSize);
00374
00376 void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
00377
00379 IDriver *getDriver() const;
00380
00382 float getUserParam(uint numParam) const;
00383
00384
00385
00386 NLMISC_DECLARE_CLASS(CPSLocated);
00387
00389 void setupDriverModelMatrix(void) ;
00390
00394 NLMISC::CVector computeI(void) const ;
00395
00399 NLMISC::CVector computeJ(void) const ;
00400
00404 NLMISC::CVector computeK(void) const ;
00405
00413 void queryCollisionInfo(void);
00414
00416
00417 void releaseCollisionInfo(void);
00418
00420 bool hasCollisionInfos() const { return _CollisionInfo != NULL; }
00421
00423 TPSAttribCollisionInfo &getCollisionInfo(void)
00424 {
00425 nlassert(_CollisionInfo);
00426 return *_CollisionInfo;
00427 }
00428
00430 const TPSAttribCollisionInfo &getCollisionInfo(void) const
00431 {
00432 nlassert(_CollisionInfo);
00433 return *_CollisionInfo;
00434 }
00435
00436
00442 inline void collisionUpdate(const CPSCollisionInfo &ci, uint32 index);
00443
00447 static const NLMISC::CMatrix &getConversionMatrix(const CPSLocated *A, const CPSLocated *B);
00448
00449
00450
00451
00460 void registerDtorObserver(CPSLocatedBindable *observer);
00461
00462
00466 void unregisterDtorObserver(CPSLocatedBindable *anObserver);
00467
00468
00469
00471 void setName(const std::string &name) { _Name = name; }
00472
00474 std::string getName(void) const { return _Name; }
00475
00476
00478 virtual bool hasParticles(void) const;
00479
00481 virtual bool hasEmitters(void) const;
00482
00488 void forceLODDegradation(bool enable = true) { _LODDegradation = enable; }
00489
00493 bool hasLODDegradation(void) const { return _LODDegradation; }
00494
00495
00497 void notifyMaxNumFacesChanged(void);
00498
00500 virtual uint querryMaxWantedNumFaces(void);
00501
00505 virtual void setSystemBasis(bool sysBasis = true);
00506
00508 bool supportParametricMotion(void) const;
00509
00513 void enableParametricMotion(bool enable = true);
00514
00516 bool isParametricMotionEnabled(void) const { return _ParametricMotion;}
00517
00519 virtual void performParametricMotion(TAnimationTime date, TAnimationTime ellapsedTime, TAnimationTime realEllapsedTime);
00520
00522 virtual void updateLife(TAnimationTime ellapsedTime);
00523
00527 void integrateSingle(float startDate, float deltaT, uint numStep,
00528 uint32 indexInLocated,
00529 NLMISC::CVector *destPos,
00530 uint posStride = sizeof(NLMISC::CVector));
00531
00533 void enableTriggerOnDeath(bool enable = true) { _TriggerOnDeath = enable; }
00534
00536 bool isTriggerOnDeathEnabled(void) const { return _TriggerOnDeath; }
00537
00539 void setTriggerEmitterID(uint32 id)
00540 {
00541 nlassert(_TriggerOnDeath);
00542 _TriggerID = id;
00543 }
00544
00546 uint32 getTriggerEmitterID(void) const
00547 {
00548 nlassert(_TriggerOnDeath);
00549 return _TriggerID;
00550 }
00551
00552
00553
00554 protected:
00555
00556
00557 friend class CPSForce;
00558
00559
00561 uint32 _MaxNumFaces;
00562
00563 std::string _Name;
00564
00565
00566 uint32 _NbFramesToSkip;
00567
00568
00569 typedef std::vector< CPSLocatedBindable *> TLocatedBoundCont;
00570
00571
00572
00573 TLocatedBoundCont _LocatedBoundCont;
00574
00575
00576 uint32 _MaxSize;
00577
00578
00579
00580 uint32 _Size;
00581
00582
00583
00584 bool _LastForever;
00585
00586
00587
00588
00589 TPSAttribFloat _InvMass;
00590 TPSAttribVector _Pos ;
00591 TPSAttribVector _Speed;
00592 TPSAttribTime _Time ;
00593 TPSAttribTime _TimeIncrement ;
00594
00595
00596 public:;
00597
00601 struct CParametricInfo
00602 {
00603 CParametricInfo() {}
00604 CParametricInfo(NLMISC::CVector pos, NLMISC::CVector speed, float date)
00605 : Pos(pos), Speed(speed), Date(date)
00606 {
00607 }
00608 NLMISC::CVector Pos;
00609 NLMISC::CVector Speed;
00610 TAnimationTime Date;
00611 };
00612
00614 typedef CPSAttrib<CParametricInfo> TPSAttribParametricInfo;
00615
00619 CPSAttrib<CParametricInfo> _PInfo;
00620
00621 protected:
00622
00626 TPSAttribCollisionInfo *_CollisionInfo;
00627
00628
00629
00630
00631 uint32 _CollisionInfoNbRef;
00632
00633
00634
00635
00636 float _InitialLife;
00637 CPSAttribMaker<float> *_LifeScheme;
00638
00639
00640
00641 float _InitialMass;
00642 CPSAttribMaker<float> *_MassScheme;
00643
00644
00645
00646
00648 struct CPostNewElementRequestInfo
00649 {
00650 NLMISC::CVector _Pos;
00651 NLMISC::CVector _Speed;
00652 void serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00653 {
00654 f.serial(_Pos, _Speed);
00655 }
00656 CPostNewElementRequestInfo(const NLMISC::CVector &pos = NLMISC::CVector::Null, const NLMISC::CVector &speed = NLMISC::CVector::Null) : _Pos(pos), _Speed(speed) {}
00657 };
00658
00659 typedef std::stack<CPostNewElementRequestInfo> TNewElementRequestStack;
00660
00662 TNewElementRequestStack _RequestStack;
00663
00665 void updateNewElementRequestStack(void);
00666
00667
00676 bool _UpdateLock;
00677
00684 void postNewElement(const NLMISC::CVector &pos = NLMISC::CVector::Null
00685 , const NLMISC::CVector &speed = NLMISC::CVector::Null);
00686
00687
00689 void resetCollisionInfo(void);
00690
00691 typedef std::vector<CPSLocatedBindable *> TDtorObserversVect;
00692 TDtorObserversVect _DtorObserversVect;
00693
00695 bool _LODDegradation;
00696
00700 uint16 _NonIntegrableForceNbRefs;
00702 uint16 _NumIntegrableForceWithDifferentBasis;
00704 typedef std::vector<CPSForce *> TForceVect;
00705 TForceVect _IntegrableForces;
00706 bool _TriggerOnDeath;
00707 uint32 _TriggerID;
00708
00710 bool _ParametricMotion;
00711
00713 void allocateParametricInfos(void);
00714
00716 void releaseParametricInfos(void);
00717
00719 void notifyMotionTypeChanged(void);
00720 public:
00722 void registerIntegrableForce(CPSForce *f);
00723
00725 void unregisterIntegrableForce(CPSForce *f);
00726
00728 void integrableForceBasisChanged(bool basis);
00729
00731 void addNonIntegrableForceRef(void);
00732
00734 void releaseNonIntegrableForceRef(void);
00735
00737 TPSAttribParametricInfo &getParametricInfos() { return _PInfo; }
00738 };
00739
00740
00741
00743
00745
00746 inline void CPSLocated::collisionUpdate(const CPSCollisionInfo &ci, uint32 index)
00747 {
00748 nlassert(_CollisionInfo);
00749 CPSCollisionInfo &firstCi = (*_CollisionInfo)[index];
00750 if (firstCi.dist == -1 || ci.dist < firstCi.dist)
00751 {
00752 firstCi = ci;
00753 }
00754 }
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 const uint32 PSForce = 0 ;
00769 const uint32 PSParticle = 1;
00770 const uint32 PSEmitter = 2;
00771 const uint32 PSLight = 3;
00772 const uint32 PSZone = 4;
00773 const uint32 PSSound = 5;
00774
00775
00781 class CPSLocatedBindable : public NLMISC::IStreamable
00782 {
00783 public:
00785
00786
00787 CPSLocatedBindable();
00789 virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
00794 virtual void finalize(void) {}
00796 virtual ~CPSLocatedBindable();
00798
00799 void setActive(bool active) { _Active = active; }
00800 bool isActive() const { return _Active; }
00805 virtual uint32 getType(void) const = 0;
00810 virtual uint32 getPriority(void) const = 0;
00812 virtual void step(TPSProcessPass pass, TAnimationTime ellapsedTime, TAnimationTime realEt) = 0;
00822 virtual void notifyTargetRemoved(CPSLocated *ptr);
00823
00827 virtual void releaseRefTo(const CParticleSystemProcess *other) {}
00828
00832 virtual void releaseAllRef();
00833
00834
00835
00836
00837
00838
00839
00840 virtual bool completeBBox(NLMISC::CAABBox &box) const { return false ;}
00841
00842
00843
00844 virtual bool doesProduceBBox(void) const { return true; }
00846 IDriver *getDriver() const
00847 {
00848 nlassert(_Owner);
00849 nlassert(_Owner->getDriver());
00850 return _Owner->getDriver();
00851 }
00853 CFontGenerator *getFontGenerator(void)
00854 {
00855 nlassert(_Owner);
00856 return _Owner->getFontGenerator();
00857 }
00858
00860 const CFontGenerator *getFontGenerator(void) const
00861 {
00862 nlassert(_Owner);
00863 return _Owner->getFontGenerator();
00864 }
00865
00867 CFontManager *getFontManager(void);
00868
00870 const CFontManager *getFontManager(void) const;
00871
00873 const NLMISC::CMatrix &getSysMat(void) const;
00875 const NLMISC::CMatrix &getInvertedSysMat(void) const;
00879 const NLMISC::CMatrix &getLocatedMat(void) const;
00883 const NLMISC::CMatrix &getInvertedLocatedMat(void) const;
00885 const NLMISC::CMatrix &getViewMat(void) const;
00887 const NLMISC::CMatrix &getInvertedViewMat(void) const;
00889 void setupDriverModelMatrix(void);
00893 inline NLMISC::CVector computeI(void) const { return _Owner->computeI(); }
00894
00898 inline NLMISC::CVector computeJ(void) const { return _Owner->computeJ(); }
00902 inline NLMISC::CVector computeK(void) const { return _Owner->computeK(); }
00904 CPSLocated *getOwner(void) { return _Owner; }
00906 const CPSLocated *getOwner(void) const { return _Owner; }
00908 void setName(const std::string &name) { _Name = name; }
00910 std::string getName(void) const { return _Name; }
00914 void setLOD(TPSLod lod) { _LOD = lod; }
00916 TPSLod getLOD(void) const { return _LOD; }
00918 virtual bool hasParticles(void) const { return false; }
00920 virtual bool hasEmitters(void) const { return false; }
00924 void setExternID(uint32 id);
00926 uint32 getExternID(void) const { return _ExternID; }
00930 virtual void basisChanged(bool systemBasis) {}
00931
00933 virtual void motionTypeChanged(bool parametric) {}
00934
00937
00938 protected:
00939 friend class CPSLocated;
00940
00943 virtual void newElement(CPSLocated *emitterLocated, uint32 emitterIndex) = 0;
00944
00945
00952 virtual void deleteElement(uint32 index) = 0;
00953
00957 virtual void resize(uint32 size) = 0;
00958
00959
00960
00964 virtual void bounceOccured(uint32 index) {}
00965
00972 void displayIcon2d(const NLMISC::CVector tab[], uint nbSegs, float scale);
00973
00974
00976 virtual void setOwner(CPSLocated *psl);
00977
00978 protected:
00979 CPSLocated *_Owner;
00980 uint32 _ExternID;
00982 TPSLod _LOD;
00983
00984 std::string _Name;
00985
00986 bool _Active;
00987 };
00988
00989
00990
00991
00996 inline bool operator<(const CPSLocatedBindable &lhs, const CPSLocatedBindable &rhs)
00997 {
00998 return rhs.getPriority() > lhs.getPriority();
00999 }
01000
01001
01002
01003
01004
01005
01006
01007
01012 class CPSTargetLocatedBindable : public CPSLocatedBindable
01013 {
01014 public:
01020 virtual void attachTarget(CPSLocated *ptr);
01024 void detachTarget(CPSLocated *ptr)
01025 {
01026 notifyTargetRemoved(ptr);
01027 }
01032 virtual void releaseRefTo(const CParticleSystemProcess *other);
01037 virtual void releaseAllRef();
01039 uint32 getNbTargets(void) const { return _Targets.size(); }
01041 CPSLocated *getTarget(uint32 index)
01042 {
01043 nlassert(index < _Targets.size());
01044 return _Targets[index];
01045 }
01047 const CPSLocated *getTarget(uint32 index) const
01048 {
01049 nlassert(index < _Targets.size());
01050 return _Targets[index];
01051 }
01058 virtual void releaseTargetRsc(CPSLocated *target) {};
01060 void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
01062 virtual void finalize(void);
01063 virtual ~CPSTargetLocatedBindable();
01064 protected:
01068 virtual void notifyTargetRemoved(CPSLocated *ptr);
01069 typedef std::vector<CPSLocated *> TTargetCont;
01070 TTargetCont _Targets;
01071
01072 };
01073
01074
01075
01076 }
01077
01078
01079 #endif // NL_PARTICLE_SYSTEM_LOCATED_H
01080
01081