00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef NL_PARTICLE_SYSTEM_LOCATED_H
00025 #define NL_PARTICLE_SYSTEM_LOCATED_H
00026
00027 #include <stack>
00028
00029 namespace NL3D
00030 {
00031 const uint32 DefaultMaxLocatedInstance = 1;
00032 }
00033
00034 #include "nel/misc/types_nl.h"
00035 #include "nel/misc/vector.h"
00036 #include "nel/3d/particle_system_process.h"
00037 #include "nel/3d/ps_attrib.h"
00038 #include "nel/3d/ps_lod.h"
00039 #include "nel/3d/ps_spawn_info.h"
00040 #include "nel/misc/stream.h"
00041
00042 #include "nel/misc/object_arena_allocator.h"
00043
00044 namespace NLMISC
00045 {
00046 class CAABBox;
00047 class CMatrix;
00048 class CVector;
00049 }
00050
00051
00052
00053
00054
00055
00056 namespace NL3D
00057 {
00058
00059
00060
00061 template <class T> class CPSAttribMaker;
00062
00063
00064 class CPSLocatedBindable;
00065 class CPSTargetLocatedBindable;
00066 class CPSZone;
00067 class CPSForce;
00068 class IDriver;
00069 class CFontManager;
00070 class CFontGenerator;
00071 class CScene;
00072 class CParticleSystem;
00073
00074
00077 struct CPSCollisionInfo
00078 {
00079 CPSCollisionInfo *Next;
00080 float Dist;
00081 NLMISC::CVector NewPos;
00082 NLMISC::CVector NewSpeed;
00083 CPSZone *CollisionZone;
00084 uint32 Index;
00085 CPSCollisionInfo()
00086 {
00087 Dist = -1.f;
00088 }
00089
00090 void update(const CPSCollisionInfo &other);
00091 };
00092
00093
00104 class CPSLocated : public CParticleSystemProcess
00105 {
00106 public:
00107 PS_FAST_OBJ_ALLOC
00109 CPSLocated();
00110
00112 virtual ~CPSLocated();
00113
00114
00115 virtual bool isLocated() const { NL_PS_FUNC(isLocated); return true; }
00116
00123 bool bind(CPSLocatedBindable *lb);
00124
00129 CPSLocatedBindable *unbind(uint index);
00130
00132 bool isBound(const CPSLocatedBindable *lb) const;
00133
00137 uint getIndexOf(const CPSLocatedBindable *lb) const;
00138
00143 void remove(const CPSLocatedBindable *lb);
00144
00149 virtual void releaseRefTo(const CParticleSystemProcess *other);
00150
00155 virtual void releaseAllRef();
00156
00157
00161 uint32 getNbBoundObjects(void) const { NL_PS_FUNC(getNbBoundObjects); return _LocatedBoundCont.size(); }
00162
00166 const CPSLocatedBindable *getBoundObject(uint32 index) const
00167 {
00168 nlassert(index < _LocatedBoundCont.size());
00169 return _LocatedBoundCont[index];
00170 }
00171
00172
00176 CPSLocatedBindable *getBoundObject(uint32 index)
00177 {
00178 nlassert(index < _LocatedBoundCont.size());
00179 return _LocatedBoundCont[index];
00180 }
00181
00182
00186 void postNewElement(const NLMISC::CVector &pos,
00187 const NLMISC::CVector &speed,
00188 CPSLocated &emitterLocated,
00189 uint32 indexInEmitter,
00190 TPSMatrixMode speedCoordSystem,
00191 TAnimationTime lifeTime);
00192
00208 sint32 newElement(const NLMISC::CVector &pos,
00209 const NLMISC::CVector &speed,
00210 CPSLocated *emitterLocated,
00211 uint32 indexInEmitter,
00212 TPSMatrixMode speedCoordSystem,
00213 bool doEmitOnce = false
00214 );
00215
00216
00221 void deleteElement(uint32 index);
00222
00223
00224 inline TAnimationTime getAgeInSeconds(uint elementIndex) const;
00225
00227 CScene *getScene(void);
00228
00230 void getLODVect(NLMISC::CVector &v, float &offset, TPSMatrixMode matrixMode);
00231
00232
00236 void incrementNbDrawnParticles(uint num);
00237
00238
00245 uint32 getNewElementIndex(void) const { return _Size; }
00246
00247
00253 bool computeBBox(NLMISC::CAABBox &aabbox) const;
00254
00255
00256
00261 void setInitialLife(TAnimationTime lifeTime);
00262
00268 void setLifeScheme(CPSAttribMaker<float> *scheme);
00269
00271 TAnimationTime getInitialLife(void) const { return _InitialLife; }
00272
00274 CPSAttribMaker<float> *getLifeScheme(void) { return _LifeScheme; }
00275 const CPSAttribMaker<float> *getLifeScheme(void) const { return _LifeScheme; }
00276
00277
00281 void setInitialMass(float mass);
00282
00287 void setMassScheme(CPSAttribMaker<float> *scheme);
00288
00290 float getInitialMass(void) const { return _InitialMass; }
00291
00293 CPSAttribMaker<float> *getMassScheme(void) { return _MassScheme; }
00294 const CPSAttribMaker<float> *getMassScheme(void) const { return _MassScheme; }
00295
00296
00297
00303 bool setLastForever();
00305 bool getLastForever(void) const { return _LastForever; }
00306
00308 TPSAttribFloat &getInvMass(void) { return _InvMass; }
00310 const TPSAttribFloat &getInvMass(void) const { return _InvMass; }
00311
00313 TPSAttribVector &getPos(void) { return _Pos; }
00315 const TPSAttribVector &getPos(void) const { return _Pos; }
00316
00318 TPSAttribVector &getSpeed(void) { return _Speed; }
00320 const TPSAttribVector &getSpeed(void) const { return _Speed; }
00321
00323 TPSAttribTime &getTime(void) { return _Time; }
00325 const TPSAttribTime &getTime(void) const { return _Time; }
00326
00328 TPSAttribTime &getTimeIncrement(void) { return _TimeIncrement; }
00330 const TPSAttribTime &getTimeIncrement(void) const { return _TimeIncrement; }
00331
00335 virtual void step(TPSProcessPass pass);
00336
00337
00338 void computeMotion();
00339
00340 void computeNewParticleMotion(uint firstInstanceIndex);
00341
00342 void updateCollisions();
00343
00345 uint32 getSize(void) const
00346 {
00347 return _Size;
00348 }
00349
00353 uint32 getMaxSize(void) const
00354 {
00355 NL_PS_FUNC(getMaxSize)
00356 return _MaxSize;
00357 }
00358
00359
00363 void resize(uint32 newSize);
00364
00366 void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
00367
00369 IDriver *getDriver() const;
00370
00372 float getUserParam(uint numParam) const;
00373
00374
00375
00376 NLMISC_DECLARE_CLASS(CPSLocated);
00377
00379 void setupDriverModelMatrix(void);
00380
00384 NLMISC::CVector computeI(void) const;
00385 NLMISC::CVector computeIWithZAxisAligned(void) const;
00386
00390 NLMISC::CVector computeJ(void) const;
00391
00395 NLMISC::CVector computeK(void) const;
00396 NLMISC::CVector computeKWithZAxisAligned(void) const;
00397
00405 void queryCollisionInfo(void);
00406
00408
00409 void releaseCollisionInfo(void);
00410
00412 bool hasCollisionInfos() const { return _CollisionNextPos != NULL; }
00413
00414
00415 void computeSpawns(uint firstInstanceIndex, bool includeEmitOnce);
00416
00417
00418 void computeForces();
00419
00420
00421 void computeCollisions(uint firstInstanceIndex, const NLMISC::CVector *posBefore, const NLMISC::CVector *posAfter);
00422
00423
00424 static const NLMISC::CMatrix &getConversionMatrix(const CParticleSystem &ps, TPSMatrixMode to, TPSMatrixMode from);
00425
00429 static const NLMISC::CMatrix &getConversionMatrix(const CPSLocated *A, const CPSLocated *B);
00430
00431
00432 const NLMISC::CMatrix &getLocalToWorldMatrix() const;
00433
00434 const NLMISC::CMatrix &getWorldToLocalMatrix() const;
00435
00436
00445 void registerDtorObserver(CPSLocatedBindable *observer);
00446
00447
00451 void unregisterDtorObserver(CPSLocatedBindable *anObserver);
00452
00453
00454
00456 void setName(const std::string &name) { _Name = name; }
00457
00459 std::string getName(void) const { return _Name; }
00460
00461
00463 virtual bool hasParticles(void) const;
00464
00466 virtual bool hasEmitters(void) const;
00467
00473 void forceLODDegradation(bool enable = true) { _LODDegradation = enable; }
00474
00478 bool hasLODDegradation(void) const { return _LODDegradation; }
00479
00480
00482
00483
00485 virtual uint getNumWantedTris() const;
00486
00487
00488 virtual void setMatrixMode(TPSMatrixMode matrixMode);
00489
00491 bool supportParametricMotion(void) const;
00492
00496 void enableParametricMotion(bool enable = true);
00497
00499 bool isParametricMotionEnabled(void) const { return _ParametricMotion;}
00500
00502 virtual void performParametricMotion(TAnimationTime date);
00503
00506 void updateLife();
00508 void removeOldParticles();
00510 void addNewlySpawnedParticles();
00511
00512
00516 void integrateSingle(float startDate, float deltaT, uint numStep,
00517 uint32 indexInLocated,
00518 NLMISC::CVector *destPos,
00519 uint posStride = sizeof(NLMISC::CVector)) const;
00520
00521
00522
00523 inline void computeParametricPos(float date, uint indexInLocated, NLMISC::CVector &dest) const;
00524
00525
00527 void enableTriggerOnDeath(bool enable = true) { _TriggerOnDeath = enable; }
00528
00530 bool isTriggerOnDeathEnabled(void) const { return _TriggerOnDeath; }
00531
00533 void setTriggerEmitterID(uint32 id)
00534 {
00535 nlassert(_TriggerOnDeath);
00536 _TriggerID = id;
00537 }
00538
00540 uint32 getTriggerEmitterID(void) const
00541 {
00542 nlassert(_TriggerOnDeath);
00543 return _TriggerID;
00544 }
00545
00549 float evalMaxDuration() const;
00550
00551
00552 virtual uint getUserMatrixUsageCount() const;
00553
00554
00555 virtual void enumTexs(std::vector<NLMISC::CSmartPtr<ITexture> > &dest, IDriver &drv);
00556
00557
00558 virtual void setZBias(float value);
00559
00560
00561
00562 void checkLife() const;
00563
00564
00565
00566 virtual void onShow(bool shown);
00567
00568 protected:
00569
00570
00571 friend class CPSForce;
00572
00574
00575
00576 uint32 _Size;
00577
00578 uint32 _MaxSize;
00579
00580 uint32 _CollisionInfoNbRef;
00581
00582 TPSAttribVector *_CollisionNextPos;
00583
00584
00585 float _InitialLife;
00586 CPSAttribMaker<float> *_LifeScheme;
00587
00588
00589 float _InitialMass;
00590 CPSAttribMaker<float> *_MassScheme;
00591 bool _LODDegradation : 1;
00592 bool _ParametricMotion : 1;
00593 bool _TriggerOnDeath : 1;
00594 bool _LastForever : 1;
00595 uint32 _TriggerID;
00599 uint16 _NonIntegrableForceNbRefs;
00601 uint16 _NumIntegrableForceWithDifferentBasis;
00602
00603 std::string _Name;
00604
00605 typedef CPSVector<CPSLocatedBindable *>::V TLocatedBoundCont;
00606
00607 TLocatedBoundCont _LocatedBoundCont;
00608
00609
00610 TPSAttribFloat _InvMass;
00611 TPSAttribVector _Pos;
00612 TPSAttribVector _Speed;
00613 TPSAttribTime _Time;
00614 TPSAttribTime _TimeIncrement;
00615 public:
00616
00620 struct CParametricInfo
00621 {
00622 CParametricInfo() {}
00623 CParametricInfo(NLMISC::CVector pos, NLMISC::CVector speed, float date)
00624 : Pos(pos), Speed(speed), Date(date)
00625 {
00626 }
00627 NLMISC::CVector Pos;
00628 NLMISC::CVector Speed;
00629 TAnimationTime Date;
00630 };
00631
00633 typedef CPSAttrib<CParametricInfo> TPSAttribParametricInfo;
00634
00638 CPSAttrib<CParametricInfo> _PInfo;
00639
00640 protected:
00641 typedef CPSVector<CPSLocatedBindable *>::V TDtorObserversVect;
00642 TDtorObserversVect _DtorObserversVect;
00643
00644 typedef CPSVector<CPSForce *>::V TForceVect;
00645 TForceVect _IntegrableForces;
00647 void allocateParametricInfos(void);
00648
00650 void releaseParametricInfos(void);
00651
00653 void notifyMotionTypeChanged(void);
00654
00655
00656 void checkIntegrity() const;
00657
00658 public:
00660 void registerIntegrableForce(CPSForce *f);
00661
00663 void unregisterIntegrableForce(CPSForce *f);
00664
00666 void integrableForceBasisChanged(TPSMatrixMode basis);
00667
00669 void addNonIntegrableForceRef(void);
00670
00672 void releaseNonIntegrableForceRef(void);
00673
00675 TPSAttribParametricInfo &getParametricInfos() { return _PInfo; }
00676
00678 virtual void systemDateChanged();
00679
00680
00681 void resetCollisions(uint numInstances);
00682
00684 void doLODDegradation();
00685
00686 private:
00687
00688
00689
00690 void deleteElement(uint32 index, TAnimationTime timeUntilNextSimStep);
00691
00692 void deleteElementBase(uint32 index);
00693
00694 TAnimationTime computeDateFromCollisionToNextSimStep(uint particleIndex, float particleAgeInSeconds);
00695
00696 sint32 newElement(const CPSSpawnInfo &si, bool doEmitOnce, TAnimationTime ellapsedTime);
00697 public:
00698 static CPSCollisionInfo *_FirstCollision;
00699
00700 static std::vector<CPSCollisionInfo> _Collisions;
00701 };
00702
00703
00704
00706
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 const uint32 PSForce = 0;
00719 const uint32 PSParticle = 1;
00720 const uint32 PSEmitter = 2;
00721 const uint32 PSLight = 3;
00722 const uint32 PSZone = 4;
00723 const uint32 PSSound = 5;
00724
00725
00731 class CPSLocatedBindable : public NLMISC::IStreamable
00732 {
00733 public:
00734 PS_FAST_OBJ_ALLOC
00736
00737
00738 CPSLocatedBindable();
00740 virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
00745 virtual void finalize(void);
00747 virtual ~CPSLocatedBindable();
00749
00750 void setActive(bool active) { _Active = active; }
00751 bool isActive() const { return _Active; }
00756 virtual uint32 getType(void) const = 0;
00761 virtual uint32 getPriority(void) const = 0;
00763 virtual void step(TPSProcessPass pass) = 0;
00773 virtual void notifyTargetRemoved(CPSLocated *ptr);
00774
00778 virtual void releaseRefTo(const CParticleSystemProcess * ) {}
00779
00783 virtual void releaseAllRef();
00784
00785
00786
00787
00788
00789
00790
00791 virtual bool completeBBox(NLMISC::CAABBox &) const { return false;}
00792
00793
00794
00795 virtual bool doesProduceBBox(void) const { return true; }
00797 IDriver *getDriver() const
00798 {
00799 nlassert(_Owner);
00800 nlassert(_Owner->getDriver());
00801 return _Owner->getDriver();
00802 }
00804 CFontGenerator *getFontGenerator(void)
00805 {
00806 nlassert(_Owner);
00807 return _Owner->getFontGenerator();
00808 }
00809
00811 const CFontGenerator *getFontGenerator(void) const
00812 {
00813 nlassert(_Owner);
00814 return _Owner->getFontGenerator();
00815 }
00816
00818 CFontManager *getFontManager(void);
00819
00821 const CFontManager *getFontManager(void) const;
00822
00824 const NLMISC::CMatrix &getSysMat(void) const;
00826 const NLMISC::CMatrix &getLocalToWorldMatrix() const;
00828 const NLMISC::CMatrix &getInvertedSysMat(void) const;
00830 const NLMISC::CMatrix &getViewMat(void) const;
00832 const NLMISC::CMatrix &getInvertedViewMat(void) const;
00834 void setupDriverModelMatrix(void);
00838 inline NLMISC::CVector computeI(void) const { return _Owner->computeI(); }
00839
00840 inline NLMISC::CVector computeIWithZAxisAligned(void) const { return _Owner->computeIWithZAxisAligned(); }
00844 inline NLMISC::CVector computeJ(void) const { return _Owner->computeJ(); }
00848 inline NLMISC::CVector computeK(void) const { return _Owner->computeK(); }
00849 inline NLMISC::CVector computeKWithZAxisAligned(void) const { return _Owner->computeKWithZAxisAligned(); }
00851 CPSLocated *getOwner(void) { return _Owner; }
00853 const CPSLocated *getOwner(void) const { return _Owner; }
00855 void setName(const std::string &name) { _Name = name; }
00857 std::string getName(void) const { return _Name; }
00861 void setLOD(TPSLod lod) { _LOD = lod; }
00863 TPSLod getLOD(void) const { return _LOD; }
00865 virtual bool hasParticles(void) const { return false; }
00867 virtual bool hasEmitters(void) const { return false; }
00871 void setExternID(uint32 id);
00873 uint32 getExternID(void) const { return _ExternID; }
00877 virtual void basisChanged(TPSMatrixMode ) {}
00878
00880 virtual void motionTypeChanged(bool ) {}
00881
00882
00883 virtual bool getUserMatrixUsageCount() const { return 0; }
00884
00885
00886 virtual void enumTexs(std::vector<NLMISC::CSmartPtr<ITexture> > &, IDriver &) {}
00887
00888
00889 virtual void setZBias(float ) {}
00890
00891
00892
00893 virtual void onShow(bool ) {}
00894
00897
00898 protected:
00899 friend class CPSLocated;
00900
00903 virtual void newElement(const CPSEmitterInfo &info) = 0;
00904
00905
00906
00907 virtual void deleteElement(uint32 index) = 0;
00908
00909 virtual void deleteElement(uint32 index, TAnimationTime ) { deleteElement(index); }
00910
00914 virtual void resize(uint32 size) = 0;
00915
00919 virtual void bounceOccured(uint32 , TAnimationTime ) {}
00920
00927 void displayIcon2d(const NLMISC::CVector tab[], uint nbSegs, float scale);
00928
00929
00931 virtual void setOwner(CPSLocated *psl);
00932
00933 protected:
00934 CPSLocated *_Owner;
00935 uint32 _ExternID;
00937 TPSLod _LOD;
00938
00939 std::string _Name;
00940
00941 bool _Active;
00942 public:
00946 virtual void systemDateChanged() {}
00947 };
00948
00949
00950
00951
00956 inline bool operator<(const CPSLocatedBindable &lhs, const CPSLocatedBindable &rhs)
00957 {
00958 return rhs.getPriority() > lhs.getPriority();
00959 }
00960
00961
00962
00963
00964
00965
00966
00967
00972 class CPSTargetLocatedBindable : public CPSLocatedBindable
00973 {
00974 public:
00980 virtual void attachTarget(CPSLocated *ptr);
00984 void detachTarget(CPSLocated *ptr)
00985 {
00986 notifyTargetRemoved(ptr);
00987 }
00992 virtual void releaseRefTo(const CParticleSystemProcess *other);
00997 virtual void releaseAllRef();
00999 uint32 getNbTargets(void) const { return _Targets.size(); }
01001 CPSLocated *getTarget(uint32 index)
01002 {
01003 nlassert(index < _Targets.size());
01004 return _Targets[index];
01005 }
01007 const CPSLocated *getTarget(uint32 index) const
01008 {
01009 nlassert(index < _Targets.size());
01010 return _Targets[index];
01011 }
01018 virtual void releaseTargetRsc(CPSLocated * ) {}
01020 void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
01022 virtual void finalize(void);
01023 virtual ~CPSTargetLocatedBindable();
01024 protected:
01025 friend class CPSLocated;
01029 virtual void notifyTargetRemoved(CPSLocated *ptr);
01030 typedef CPSVector<CPSLocated *>::V TTargetCont;
01031 TTargetCont _Targets;
01032
01033 };
01034
01035
01037
01039
01040
01041 inline const NLMISC::CMatrix &CPSLocated::getConversionMatrix(const CPSLocated *A,const CPSLocated *B)
01042 {
01043 nlassert(A);
01044 nlassert(B);
01045 nlassert(A->_Owner == B->_Owner);
01046 const CParticleSystem *ps = A->_Owner;
01047 nlassert(ps);
01048 return getConversionMatrix(*ps, A->getMatrixMode(), B->getMatrixMode());
01049 }
01050
01051
01052 inline TAnimationTime CPSLocated::getAgeInSeconds(uint elementIndex) const
01053 {
01054 nlassert(elementIndex < _Size);
01055 if (_LastForever) return _Time[elementIndex];
01056 if (_LifeScheme) return _Time[elementIndex] / _TimeIncrement[elementIndex];
01057 return _Time[elementIndex] * _InitialLife;
01058 }
01059
01060
01061 inline void CPSLocated::computeParametricPos(float date, uint indexInLocated, NLMISC::CVector &dest) const
01062 {
01063 integrateSingle(date, 1.f, 1, indexInLocated, &dest);
01064 }
01065
01066
01067
01068 inline const NLMISC::CMatrix &CPSLocatedBindable::getLocalToWorldMatrix() const
01069 {
01070 nlassert(_Owner);
01071 return _Owner->getLocalToWorldMatrix();
01072 }
01073
01074 }
01075
01076
01077 #endif // NL_PARTICLE_SYSTEM_LOCATED_H
01078
01079