00001 00032 #ifndef LL_LLVIEWERPARTSIM_H 00033 #define LL_LLVIEWERPARTSIM_H 00034 00035 #include "lldarrayptr.h" 00036 #include "llframetimer.h" 00037 #include "llmemory.h" 00038 #include "llpartdata.h" 00039 #include "llviewerpartsource.h" 00040 00041 class LLViewerImage; 00042 class LLViewerPart; 00043 class LLViewerRegion; 00044 class LLViewerImage; 00045 class LLVOPartGroup; 00046 00047 typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt); 00048 00050 // 00051 // An individual particle 00052 // 00053 00054 00055 class LLViewerPart : public LLPartData, public LLRefCount 00056 { 00057 protected: 00058 ~LLViewerPart(); 00059 public: 00060 LLViewerPart(); 00061 00062 void init(LLPointer<LLViewerPartSource> sourcep, LLViewerImage *imagep, LLVPCallback cb); 00063 00064 00065 U32 mPartID; // Particle ID used primarily for moving between groups 00066 F32 mLastUpdateTime; // Last time the particle was updated 00067 F32 mSkipOffset; // Offset against current group mSkippedTime 00068 00069 LLVPCallback mVPCallback; // Callback function for more complicated behaviors 00070 LLPointer<LLViewerPartSource> mPartSourcep; // Particle source used for this object 00071 00072 00073 // Current particle state (possibly used for rendering) 00074 LLPointer<LLViewerImage> mImagep; 00075 LLVector3 mPosAgent; 00076 LLVector3 mVelocity; 00077 LLVector3 mAccel; 00078 LLColor4 mColor; 00079 LLVector2 mScale; 00080 00081 static U32 sNextPartID; 00082 }; 00083 00084 00085 00086 class LLViewerPartGroup 00087 { 00088 public: 00089 LLViewerPartGroup(const LLVector3 ¢er, 00090 const F32 box_radius); 00091 virtual ~LLViewerPartGroup(); 00092 00093 void cleanup(); 00094 00095 BOOL addPart(LLViewerPart* part, const F32 desired_size = -1.f); 00096 00097 void updateParticles(const F32 lastdt); 00098 00099 BOOL posInGroup(const LLVector3 &pos, const F32 desired_size = -1.f); 00100 00101 void shift(const LLVector3 &offset); 00102 00103 typedef std::vector<LLPointer<LLViewerPart> > part_list_t; 00104 part_list_t mParticles; 00105 00106 const LLVector3 &getCenterAgent() const { return mCenterAgent; } 00107 S32 getCount() const { return (S32) mParticles.size(); } 00108 LLViewerRegion *getRegion() const { return mRegionp; } 00109 00110 void removeParticlesByID(const U32 source_id); 00111 00112 LLPointer<LLVOPartGroup> mVOPartGroupp; 00113 00114 BOOL mUniformParticles; 00115 U32 mID; 00116 00117 F32 mSkippedTime; 00118 00119 protected: 00120 LLVector3 mCenterAgent; 00121 F32 mBoxRadius; 00122 LLVector3 mMinObjPos; 00123 LLVector3 mMaxObjPos; 00124 00125 LLViewerRegion *mRegionp; 00126 }; 00127 00128 class LLViewerPartSim : public LLSingleton<LLViewerPartSim> 00129 { 00130 public: 00131 LLViewerPartSim(); 00132 virtual ~LLViewerPartSim(){} 00133 void destroyClass(); 00134 00135 typedef std::vector<LLViewerPartGroup *> group_list_t; 00136 typedef std::vector<LLPointer<LLViewerPartSource> > source_list_t; 00137 00138 void shift(const LLVector3 &offset); 00139 00140 void updateSimulation(); 00141 00142 void addPartSource(LLPointer<LLViewerPartSource> sourcep); 00143 00144 void cleanupRegion(LLViewerRegion *regionp); 00145 00146 BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping) 00147 F32 maxRate() // Return maximum particle generation rate 00148 { 00149 if (sParticleCount >= MAX_PART_COUNT) 00150 { 00151 return 1.f; 00152 } 00153 if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount) 00154 { 00155 return (((F32)sParticleCount/(F32)sMaxParticleCount)-PART_THROTTLE_THRESHOLD)*PART_THROTTLE_RESCALE; 00156 } 00157 return 0.f; 00158 } 00159 F32 getRefRate() { return sParticleAdaptiveRate; } 00160 F32 getBurstRate() {return sParticleBurstRate; } 00161 void addPart(LLViewerPart* part); 00162 void updatePartBurstRate() ; 00163 void clearParticlesByID(const U32 system_id); 00164 void clearParticlesByOwnerID(const LLUUID& task_id); 00165 void removeLastCreatedSource(); 00166 00167 const source_list_t* getParticleSystemList() const { return &mViewerPartSources; } 00168 00169 friend class LLViewerPartGroup; 00170 00171 BOOL aboveParticleLimit() const { return sParticleCount > sMaxParticleCount; } 00172 00173 static void setMaxPartCount(const S32 max_parts) { sMaxParticleCount = max_parts; } 00174 static S32 getMaxPartCount() { return sMaxParticleCount; } 00175 static void incPartCount(const S32 count) { sParticleCount += count; } 00176 static void decPartCount(const S32 count) { sParticleCount -= count; } 00177 00178 U32 mID; 00179 00180 protected: 00181 LLViewerPartGroup *createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size); 00182 LLViewerPartGroup *put(LLViewerPart* part); 00183 00184 group_list_t mViewerPartGroups; 00185 source_list_t mViewerPartSources; 00186 LLFrameTimer mSimulationTimer; 00187 00188 static S32 sMaxParticleCount; 00189 static S32 sParticleCount; 00190 static F32 sParticleAdaptiveRate; 00191 static F32 sParticleBurstRate; 00192 00193 static const S32 MAX_PART_COUNT; 00194 static const F32 PART_THROTTLE_THRESHOLD; 00195 static const F32 PART_THROTTLE_RESCALE; 00196 static const F32 PART_ADAPT_RATE_MULT; 00197 static const F32 PART_ADAPT_RATE_MULT_RECIP; 00198 }; 00199 00200 #endif // LL_LLVIEWERPARTSIM_H