# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

ps_located.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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" // an attribute template container
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; // the default value for a located container
00068 
00069 
00070 
00073 
00074 struct CPSCollisionInfo
00075 {
00076 
00077         float   TimeSliceRatio; 
00082         // distance to the collisionner along the speed vector
00083         float   dist;   
00084         // new pos and speed, valid if a collision occured
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          // retrieve the frame rate
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; // this is intended only for integrable forces that want to use
00558                                                    // registerIntegrableForce, and removeIntegrableForce
00559 
00561         uint32 _MaxNumFaces;
00562 
00563         std::string _Name;
00564         
00565         // number of frame to skip between motion ...
00566         uint32 _NbFramesToSkip;
00567 
00568         // container of all object that are bound to a located
00569         typedef std::vector< CPSLocatedBindable *> TLocatedBoundCont;
00570 
00571 
00572         // the list of all located
00573         TLocatedBoundCont _LocatedBoundCont;
00574 
00575         // max number of instance in the container
00576         uint32 _MaxSize;
00577 
00578         // current number of instances in the container
00579 
00580         uint32 _Size;
00581 
00582         
00583         //  = true if the located can't die (gravity for instance...)
00584         bool _LastForever;
00585 
00586         // needed atributes for a located
00587 
00588         // a container of masses. the inverse for mass are used in order to speed up forces computation
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;   // the inital pos of emission
00609                 NLMISC::CVector Speed; // the inital direction of emission
00610                 TAnimationTime  Date;  // the initial date of emission
00611         };
00612 
00614         typedef CPSAttrib<CParametricInfo> TPSAttribParametricInfo;
00615 
00619         CPSAttrib<CParametricInfo>  _PInfo;
00620 
00621         protected:
00622 
00626         TPSAttribCollisionInfo *_CollisionInfo;
00627 
00628 
00629 
00630         // nb of users of the _CollisionInfo field
00631         uint32 _CollisionInfoNbRef;
00632 
00633                 
00634         // the life to use, or a scheme that generate it
00635         // if the scheme if null, initial life is used instead
00636         float _InitialLife;
00637         CPSAttribMaker<float> *_LifeScheme;
00638 
00639         // the mass to use, or a scheme that generate it
00640         // if the scheme if null, initial mass is used instead
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 // IMPLEMENTATION OF INLINE METHODS  //
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 // bindable types are not encoded as an enum in order to provide
00766 // easy extensibility
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         * The following is used to complete an aabbox that was computed using the located positions
00835         * You may not need to do anything with that, unless your bindable has a space extents. For exAmple,
00836         * with a particle which has a radius of 2, you must enlarge the bbox to get the correct one.
00837         * The default behaviour does nothing
00838         * \return true if you modified the bbox
00839         */      
00840         virtual bool                    completeBBox(NLMISC::CAABBox &box) const  { return false ;}
00841         /***
00842          * Override the following to say that you don't want to be part of a bbox computation
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         // Name for this bindable
00984         std::string _Name;
00985         //
00986         bool        _Active; // Say if this bindable is active. If not active, the owning system won't try to call 'step' on that object. True by default
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 } // NL3D
01077 
01078 
01079 #endif // NL_PARTICLE_SYSTEM_LOCATED_H
01080 
01081 /* End of particle_system_located.h */