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_H
00027 #define NL_PARTICLE_SYSTEM_H
00028
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/misc/matrix.h"
00031 #include "nel/misc/aabbox.h"
00032 #include "nel/misc/smart_ptr.h"
00033 #include "nel/misc/rgba.h"
00034 #include "nel/3d/animation_time.h"
00035 #include "3d/mot.h"
00036 #include "3d/animated_value.h"
00037 #include "3d/particle_system_process.h"
00038 #include "3d/ps_lod.h"
00039 #include "3d/ps_attrib_maker.h"
00040
00041 #include <map>
00042
00043
00044
00045 namespace NL3D
00046 {
00047
00048 class CParticleSystemShape;
00049 class CPSLocatedBindable;
00050 class CFontGenerator;
00051 class CFontManager;
00052 class CPSCopyHelper;
00053 class CScene;
00054 class CPSLocated;
00055 class IDriver;
00056 struct UPSSoundServer;
00057
00058
00059
00061 const uint MaxPSUserParam = 4;
00062
00063
00083 class CParticleSystem : public NLMISC::CRefCount
00084 {
00085 public:
00086
00087 enum TPass { Anim, SolidRender, BlendRender, ToolRender };
00088 public:
00089
00090
00092
00093
00094 CParticleSystem();
00096 virtual ~CParticleSystem();
00098 void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
00102 void merge(CParticleSystemShape *toMerge);
00103
00104
00105
00106
00107
00109
00110
00111
00113
00114
00122 void enableSharing(bool enabled = true) { _Sharing = enabled; }
00123
00125 bool isSharingEnabled() const { return _Sharing; }
00127
00128
00129
00131
00132
00133 void setDriver(IDriver *driver) { _Driver = driver; }
00134
00136 IDriver *getDriver(void) { return _Driver; }
00138
00139
00141
00142
00145 void setScene(CScene *scene) { _Scene = scene; }
00146
00148 CScene *getScene(void) { return _Scene; }
00150
00151
00152
00154
00155
00156
00164 void setSysMat(const NLMISC::CMatrix &m);
00165
00167 const NLMISC::CMatrix &getSysMat(void) const { return _SysMat; }
00168
00170 const NLMISC::CMatrix &getOldSysMat(void) const { return _SysMat; }
00171
00173 const NLMISC::CMatrix &getInvertedSysMat(void) const { return _InvSysMat; }
00174
00178 void setViewMat(const NLMISC::CMatrix &m);
00179
00181 const NLMISC::CMatrix &getViewMat(void) const { return _ViewMat; }
00182
00184 const NLMISC::CMatrix &getInvertedViewMat(void) const { return _InvertedViewMat; }
00185
00187
00188
00189
00190
00192
00193
00200 virtual void step(TPass pass, TAnimationTime ellapsedTime);
00202
00203
00204
00206 static uint32 NbParticlesDrawn;
00207
00208
00209
00219 void attach(CParticleSystemProcess *process);
00220
00223 CParticleSystemProcess *detach(uint index);
00224
00227 bool isProcess(CParticleSystemProcess *process) const;
00228
00232 uint getIndexOf(const CParticleSystemProcess *process) const;
00233
00238 void remove(CParticleSystemProcess *process);
00239
00241 uint32 getNbProcess(void) const { return _ProcessVect.size(); }
00242
00247 CParticleSystemProcess *getProcess(uint32 index)
00248 {
00249 nlassert(index < _ProcessVect.size());
00250 return _ProcessVect[index];
00251 }
00252
00257 const CParticleSystemProcess *getProcess(uint32 index) const
00258 {
00259 nlassert(index < _ProcessVect.size());
00260 return _ProcessVect[index];
00261 }
00262
00264
00265
00266
00268
00269
00271 TAnimationTime getSystemDate(void) const { return _SystemDate; }
00272
00277 uint64 getDate(void) const
00278 {
00279 return _Date;
00280 }
00282
00283
00284
00293 void setUserParam(uint userParamIndex, float value)
00294 {
00295 nlassert(userParamIndex < MaxPSUserParam);
00296 NLMISC::clamp(value, 0, MaxInputValue);
00297 _UserParam[userParamIndex] = value;
00298 }
00299
00303 float getUserParam(uint userParamIndex) const
00304 {
00305 nlassert(userParamIndex < MaxPSUserParam);
00306 return _UserParam[userParamIndex];
00307 }
00308
00314 void bindGlobalValueToUserParam(const std::string &globalValueName, uint userParamIndex);
00315
00316 std::string getGlobalValueName(uint userParamIndex) const;
00317
00318 static void setGlobalValue(const std::string &name, float value);
00319
00320 static float getGlobalValue(const std::string &name);
00324 static void setGlobalVectorValue(const std::string &name, const NLMISC::CVector &value);
00325
00326 static NLMISC::CVector getGlobalVectorValue(const std::string &name);
00327
00328 class CGlobalVectorValueHandle
00329 {
00330 public:
00331 CGlobalVectorValueHandle() { reset(); }
00332 const NLMISC::CVector &get() const { nlassert(_Value); return *_Value; }
00333 void set(const NLMISC::CVector &value) { nlassert(_Value); *_Value = value; }
00334 const std::string &getName() const { nlassert(_Name); return *_Name; }
00335 bool isValid() const { return _Name != NULL && _Value != NULL; }
00336 void reset() { _Name = NULL; _Value = NULL; }
00338 private:
00339 friend class CParticleSystem;
00340 const std::string *_Name;
00341 NLMISC::CVector *_Value;
00342 };
00343
00344 static CGlobalVectorValueHandle getGlobalVectorValueHandle(const std::string &name);
00346
00347
00348
00349
00350
00352
00358 void setCurrentEditedElement(CPSLocated *loc = NULL , uint32 index = 0, class CPSLocatedBindable *bd = NULL )
00359 {
00360 _CurrEditedElementLocated = loc;
00361 _CurrEditedElementLocatedBindable = bd;
00362 _CurrEditedElementIndex = index;
00363 }
00364
00368 void getCurrentEditedElement(CPSLocated *&loc , uint32 &index, CPSLocatedBindable *&lb)
00369 {
00370 loc = _CurrEditedElementLocated;
00371 index = _CurrEditedElementIndex;
00372 lb = _CurrEditedElementLocatedBindable;
00373 }
00374
00376 void setFontGenerator(CFontGenerator *fg) { _FontGenerator = fg; }
00377
00379 CFontGenerator *getFontGenerator(void) { return _FontGenerator; }
00380
00382 const CFontGenerator *getFontGenerator(void) const { return _FontGenerator; }
00383
00385 void setFontManager(CFontManager *fg) { _FontManager = fg; }
00386
00388 CFontManager *getFontManager(void) { return _FontManager; }
00389
00391 const CFontManager *getFontManager(void) const { return _FontManager; }
00392
00393
00395 void setName(const std::string &s) { _Name = s; }
00396
00398 std::string getName(void) const { return _Name; }
00399
00400
00401
00403
00405
00406
00408 bool hasTransparentObjects(void) const;
00409
00410
00411
00412
00414
00418 void enableAccurateIntegration(bool enable = true) { _AccurateIntegration = enable; }
00419 bool isAccurateIntegrationEnabled(void) const { return _AccurateIntegration; }
00420
00426 void setAccurateIntegrationParams(TAnimationTime threshold,
00427 uint32 maxNbIntegrations,
00428 bool canSlowDown,
00429 bool keepEllapsedTimeForLifeUpdate
00430 )
00431 {
00432 _TimeThreshold = threshold;
00433 _MaxNbIntegrations = maxNbIntegrations;
00434 _CanSlowDown = canSlowDown;
00435 _KeepEllapsedTimeForLifeUpdate = keepEllapsedTimeForLifeUpdate;
00436 }
00437
00441 void getAccurateIntegrationParams(TAnimationTime &threshold,
00442 uint32 &maxNbIntegrations,
00443 bool &canSlowDown,
00444 bool &keepEllapsedTimeForLifeUpdate
00445 )
00446 {
00447 threshold = _TimeThreshold ;
00448 maxNbIntegrations = _MaxNbIntegrations;
00449 canSlowDown = _CanSlowDown;
00450 keepEllapsedTimeForLifeUpdate = _KeepEllapsedTimeForLifeUpdate;
00451 }
00452
00453
00454
00455
00456
00457
00458
00466
00467
00469 void setMaxViewDist(float maxDist)
00470 {
00471 nlassert(maxDist > 0.f);
00472 _MaxViewDist = maxDist;
00473 _InvCurrentViewDist = _InvMaxViewDist = 1.f / maxDist;
00474 }
00475
00477 float getMaxViewDist(void) const { return _MaxViewDist; }
00478
00480 void setLODRatio(float ratio) { nlassert(ratio > 0 && ratio <= 1.f); _LODRatio = ratio; }
00481
00483 float getLODRatio(void) const { return _LODRatio; }
00484
00485
00490 void getLODVect(NLMISC::CVector &v, float &offset, bool systemBasis);
00491
00493 TPSLod getLOD(void) const;
00494
00496 float getOneMinusCurrentLODRatio(void) const { return _OneMinusCurrentLODRatio; }
00497
00503 void enableAutoLOD(bool enabled = true) { _AutoLOD = enabled; }
00504
00506 bool isAutoLODEnabled() const { return _AutoLOD; }
00507
00512 void setupAutoLOD(float startDistPercent, uint8 degradationExponent)
00513 {
00514 nlassert(startDistPercent < 1.f);
00515 nlassert(degradationExponent > 0);
00516 _AutoLODStartDistPercent = startDistPercent;
00517 _AutoLODDegradationExponent = degradationExponent;
00518 }
00519
00520
00521 float getAutoLODStartDistPercent() const { return _AutoLODStartDistPercent; }
00522 uint8 getAutoLODDegradationExponent() const { return _AutoLODDegradationExponent; }
00523
00528 void setAutoLODMode(bool skipParticles) { _AutoLODSkipParticles = skipParticles; }
00529 bool getAutoLODMode() const { return _AutoLODSkipParticles; }
00530
00537 void setColorAttenuationScheme(CPSAttribMaker<NLMISC::CRGBA> *colScheme)
00538 {
00539 delete _ColorAttenuationScheme;
00540 _ColorAttenuationScheme = colScheme;
00541 if (!colScheme)
00542 {
00543 _GlobalColor = NLMISC::CRGBA::White;
00544 }
00545 }
00546
00548 CPSAttribMaker<NLMISC::CRGBA> *getColorAttenuationScheme() { return _ColorAttenuationScheme; }
00549 const CPSAttribMaker<NLMISC::CRGBA> *getColorAttenuationScheme() const { return _ColorAttenuationScheme; }
00550
00554 const NLMISC::CRGBA &getGlobalColor() const { return _GlobalColor; }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 float getWantedNumTris(float dist);
00565
00567 void setNumTris(uint numFaces);
00568
00572 void notifyMaxNumFacesChanged(void);
00573
00575 bool isLoadBalancingEnabled() const { return _EnableLoadBalancing; }
00576
00578 void enableLoadBalancing(bool enabled = true);
00579
00580
00581
00582
00584
00588 void computeBBox(NLMISC::CAABBox &aabbox);
00589
00593 void setAutoComputeBBox(bool enable = true) { _ComputeBBox = enable; }
00594
00595
00597 bool getAutoComputeBBox(void) const { return _ComputeBBox; }
00598
00599
00604 void setPrecomputedBBox(const NLMISC::CAABBox &precompBBox)
00605 {
00606 nlassert(!_ComputeBBox);
00607 _PreComputedBBox = precompBBox;
00608 }
00609
00611 void getLastComputedBBox(NLMISC::CAABBox &dest) { dest = _PreComputedBBox; }
00612
00613
00614
00615
00617
00621 void setDestroyModelWhenOutOfRange(bool enable = true)
00622 {
00623 _DestroyModelWhenOutOfRange = enable;
00624 _PresetBehaviour = UserBehaviour;
00625 }
00626
00628 bool getDestroyModelWhenOutOfRange(void) const { return _DestroyModelWhenOutOfRange; }
00629
00630
00632 enum TDieCondition { none, noMoreParticles, noMoreParticlesAndEmitters };
00633
00634
00641 void setDestroyCondition(TDieCondition dieCondition)
00642 {
00643 _DieCondition = dieCondition;
00644 _PresetBehaviour = UserBehaviour;
00645 }
00646
00648 TDieCondition getDestroyCondition(void) const { return _DieCondition; }
00649
00658 void setDelayBeforeDeathConditionTest(TAnimationTime delay)
00659 {
00660 _DelayBeforeDieTest = delay;
00661 }
00662
00664 TAnimationTime getDelayBeforeDeathConditionTest(void) const { return _DelayBeforeDieTest; }
00665
00671 void destroyWhenOutOfFrustum(bool enable = true)
00672 {
00673 _DestroyWhenOutOfFrustum = enable;
00674 _PresetBehaviour = UserBehaviour;
00675 }
00676
00680 bool doesDestroyWhenOutOfFrustum(void) const { return _DestroyWhenOutOfFrustum; }
00681
00682
00684 bool hasEmitters(void) const;
00685
00687 bool hasParticles(void) const;
00688
00690 enum TAnimType
00691 { AnimVisible = 0,
00692 AnimInCluster,
00693 AnimAlways,
00694 LastValue
00695 };
00696
00700 void performMotionWhenOutOfFrustum(bool enable = true)
00701 {
00702 _AnimType = enable ? AnimInCluster : AnimVisible;
00703 _PresetBehaviour = UserBehaviour;
00704 }
00705
00709 bool doesPerformMotionWhenOutOfFrustum(void) const { return _AnimType == AnimInCluster; }
00710
00712 void setAnimType(TAnimType animType)
00713 {
00714 nlassert(animType < LastValue);
00715 _AnimType = animType;
00716 _PresetBehaviour = UserBehaviour;
00717 }
00718
00720 TAnimType getAnimType() const { return _AnimType; }
00721
00733 enum TPresetBehaviour
00734 {
00735 EnvironmentFX = 0,
00736 RunningEnvironmentFX,
00737
00738
00739
00740
00741 SpellFX,
00742 LoopingSpellFX,
00743 MinorFX,
00744 UserBehaviour,
00745 PresetLast
00746 };
00747
00748 void activatePresetBehaviour(TPresetBehaviour behaviour);
00749
00750 TPresetBehaviour getBehaviourType() const
00751 {
00752 return _PresetBehaviour;
00753 }
00754
00755
00756
00757
00758
00759
00760
00762
00764
00765 {
00766 _SoundServer = soundServer;
00767 }
00768
00770 static UPSSoundServer * getSoundServer(void)
00771 {
00772 return _SoundServer;
00773 }
00774
00776 void stopSound();
00777
00779 void reactivateSound();
00780
00781
00782
00783
00785
00790 void registerLocatedBindableExternID(uint32 id, CPSLocatedBindable *lb);
00791
00793 void unregisterLocatedBindableExternID(CPSLocatedBindable *lb);
00794
00795
00796
00798
00800
00804 CPSLocatedBindable *getLocatedBindableByExternID(uint32 id, uint index);
00805 const CPSLocatedBindable *getLocatedBindableByExternID(uint32 id, uint index) const;
00807 uint getNumID() const;
00809 uint32 getID(uint index) const;
00813 void getIDs(std::vector<uint32> &dest) const;
00814
00815
00816
00817 private:
00818 typedef std::map<std::string, float> TGlobalValuesMap;
00819 typedef std::map<std::string, NLMISC::CVector> TGlobalVectorValuesMap;
00820 private:
00821 friend class CParticleSystemDetailObs;
00823 void stepLocated(TPSProcessPass pass, TAnimationTime et, TAnimationTime realEt);
00824 void updateLODRatio();
00825 void updateColor();
00826
00827 static TGlobalValuesMap _GlobalValuesMap;
00828
00829 static TGlobalVectorValuesMap _GlobalVectorValuesMap;
00830
00831 NLMISC::CAABBox _PreComputedBBox;
00832
00833 IDriver *_Driver;
00834
00835 typedef std::vector< CParticleSystemProcess *> TProcessVect;
00836 TProcessVect _ProcessVect;
00837 CFontGenerator *_FontGenerator;
00838 CFontManager *_FontManager;
00839
00840 NLMISC::CMatrix _ViewMat;
00841
00842
00843 NLMISC::CMatrix _InvertedViewMat;
00844
00845
00846 NLMISC::CMatrix _SysMat;
00847
00848 NLMISC::CMatrix _OldSysMat;
00849
00850 NLMISC::CMatrix _InvSysMat;
00851
00852 NLMISC::CVector _CurrentDeltaPos;
00853
00854 NLMISC::CVector _DeltaPos;
00855
00856
00857 uint64 _Date;
00858
00860 sint64 _LastUpdateDate;
00861
00862
00863 CPSLocated *_CurrEditedElementLocated;
00864
00865 CPSLocatedBindable *_CurrEditedElementLocatedBindable;
00866
00867 uint32 _CurrEditedElementIndex;
00868
00869
00874 CScene *_Scene;
00875
00876
00877
00878 std::string _Name;
00879
00880 TAnimationTime _TimeThreshold;
00881 TAnimationTime _SystemDate;
00882 uint32 _MaxNbIntegrations;
00883
00884
00885 float _LODRatio;
00886 float _OneMinusCurrentLODRatio;
00887 float _MaxViewDist;
00888 float _InvMaxViewDist;
00889 float _InvCurrentViewDist;
00890
00891
00892 TDieCondition _DieCondition;
00893 TAnimationTime _DelayBeforeDieTest;
00894 uint _MaxNumFacesWanted;
00895 TAnimType _AnimType;
00896
00897 static UPSSoundServer *_SoundServer;
00898
00899 float _UserParam[MaxPSUserParam];
00900 const TGlobalValuesMap::value_type **_UserParamGlobalValue;
00901
00902 uint8 _BypassGlobalUserParam;
00903
00904 TPresetBehaviour _PresetBehaviour;
00905
00906 typedef
00907 std::multimap<uint32, CPSLocatedBindable *> TLBMap;
00908 TLBMap _LBMap;
00909
00910 float _AutoLODStartDistPercent;
00911 uint8 _AutoLODDegradationExponent;
00912
00913 CPSAttribMaker<NLMISC::CRGBA> *_ColorAttenuationScheme;
00914 NLMISC::CRGBA _GlobalColor;
00915
00918 bool _ComputeBBox;
00919 bool _BBoxTouched;
00920 bool _AccurateIntegration;
00921 bool _CanSlowDown;
00922 bool _DestroyModelWhenOutOfRange;
00923 bool _DestroyWhenOutOfFrustum;
00924 bool _Sharing;
00925 bool _AutoLOD;
00926 bool _KeepEllapsedTimeForLifeUpdate;
00927 bool _AutoLODSkipParticles;
00928 bool _EnableLoadBalancing;
00929
00931 float _InverseEllapsedTime;
00932 public:
00933
00934 void interpolatePosDelta(NLMISC::CVector &dest, TAnimationTime deltaT);
00935 };
00936
00937
00938
00939
00940
00941
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 }
01003
01004
01005 #endif // NL_PARTICLE_SYSTEM_H
01006
01007