llviewerpartsim.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /**
  2. * @file llviewerpartsim.h
  3. * @brief LLViewerPart class header file
  4. *
  5. * $LicenseInfo:firstyear=2003&license=viewergpl$
  6. *
  7. * Copyright (c) 2003-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_LLVIEWERPARTSIM_H
  33. #define LL_LLVIEWERPARTSIM_H
  34. #include "llframetimer.h"
  35. #include "llpartdata.h"
  36. #include "llpointer.h"
  37. #include "llviewerpartsource.h"
  38. class LLViewerPart;
  39. class LLViewerRegion;
  40. class LLViewerTexture;
  41. class LLVOPartGroup;
  42. typedef void (*LLVPCallback)(LLViewerPart& part, F32 dt);
  43. ///////////////////
  44. //
  45. // An individual particle
  46. //
  47. class LLViewerPart : public LLPartData
  48. {
  49. public:
  50. LLViewerPart();
  51. ~LLViewerPart();
  52. void init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture* imagep,
  53. LLVPCallback cb);
  54. public:
  55. // Callback function for more complicated behaviors
  56. LLVPCallback mVPCallback;
  57. // Particle source used for this object
  58. LLPointer<LLViewerPartSource> mPartSourcep;
  59. // particle to connect to if this is part of a particle ribbon
  60. LLViewerPart* mParent;
  61. // child particle for clean reference destruction
  62. LLViewerPart* mChild;
  63. // Current particle state (possibly used for rendering)
  64. LLPointer<LLViewerTexture> mImagep;
  65. LLVector3 mPosAgent;
  66. LLVector3 mVelocity;
  67. LLVector3 mAxis;
  68. LLVector3 mAccel;
  69. LLColor4 mColor;
  70. LLVector2 mScale;
  71. F32 mStartGlow;
  72. F32 mEndGlow;
  73. LLColor4U mGlow;
  74. // Particle ID used primarily for moving between groups
  75. U32 mPartID;
  76. // Last time the particle was updated
  77. F32 mLastUpdateTime;
  78. // Offset against current group mSkippedTime
  79. F32 mSkipOffset;
  80. static U32 sNextPartID;
  81. };
  82. class LLViewerPartGroup
  83. {
  84. protected:
  85. LOG_CLASS(LLViewerPartGroup);
  86. public:
  87. LLViewerPartGroup(const LLVector3& center, F32 box_radius, bool hud);
  88. virtual ~LLViewerPartGroup();
  89. void cleanup();
  90. bool addPart(LLViewerPart* part, F32 desired_size = -1.f);
  91. void updateParticles(F32 lastdt);
  92. bool posInGroup(const LLVector3& pos, F32 desired_size = -1.f);
  93. void shift(const LLVector3& offset);
  94. LL_INLINE F32 getBoxRadius() { return mBoxRadius; }
  95. LL_INLINE F32 getBoxSide() { return mBoxSide; }
  96. LL_INLINE const LLVector3& getCenterAgent() const { return mCenterAgent; }
  97. LL_INLINE S32 getCount() const { return mParticles.size(); }
  98. LL_INLINE LLViewerRegion* getRegion() const { return mRegionp; }
  99. void removeParticlesByID(U32 source_id);
  100. public:
  101. LLPointer<LLVOPartGroup> mVOPartGroupp;
  102. typedef std::vector<LLViewerPart*> part_list_t;
  103. part_list_t mParticles;
  104. U32 mID;
  105. F32 mSkippedTime;
  106. bool mUniformParticles;
  107. protected:
  108. bool mHud;
  109. F32 mBoxRadius;
  110. F32 mBoxSide;
  111. LLVector3 mCenterAgent;
  112. LLVector3 mMinObjPos;
  113. LLVector3 mMaxObjPos;
  114. LLViewerRegion* mRegionp;
  115. };
  116. class LLViewerPartSim
  117. {
  118. friend class LLViewerPartGroup;
  119. protected:
  120. LOG_CLASS(LLViewerPartSim);
  121. public:
  122. LLViewerPartSim() = default;
  123. void initClass(); // Called from LLWorld::initClass()
  124. void cleanupClass(); // Called from LLWorld::cleanupClass()
  125. typedef std::vector<LLViewerPartGroup*> group_list_t;
  126. void shift(const LLVector3& offset);
  127. void updateSimulation();
  128. void addPartSource(LLPointer<LLViewerPartSource> sourcep);
  129. void cleanupRegion(LLViewerRegion* regionp);
  130. LL_INLINE F32 getRefRate() { return sParticleAdaptiveRate; }
  131. LL_INLINE F32 getBurstRate() { return sParticleBurstRate; }
  132. void addPart(LLViewerPart* part);
  133. void updatePartBurstRate() ;
  134. void clearParticlesByID(U32 system_id);
  135. void clearParticlesByOwnerID(const LLUUID& task_id);
  136. void clearParticlesByRootObjectID(const LLUUID& object_id);
  137. void removeLastCreatedSource();
  138. // Note: 'max" gets clamped between 0 and 8192
  139. static void setMaxPartCount(S32 max);
  140. LL_INLINE static S32 getMaxPartCount() { return sMaxParticleCount; }
  141. LL_INLINE static void incPartCount(S32 count) { sParticleCount += count; }
  142. LL_INLINE static void decPartCount(S32 count) { sParticleCount -= count; }
  143. LL_INLINE static bool aboveParticleLimit() { return sParticleCount > sMaxParticleCount; }
  144. // Just decides whether this particle should be added or not (for particle
  145. // count capping):
  146. static bool shouldAddPart();
  147. protected:
  148. LLViewerPartGroup* createViewerPartGroup(const LLVector3& pos_agent,
  149. F32 desired_size, bool hud);
  150. LLViewerPartGroup* put(LLViewerPart* part);
  151. #if LL_DEBUG
  152. public:
  153. static void checkParticleCount(U32 size = 0);
  154. static S32 sParticleCount2;
  155. #endif
  156. protected:
  157. group_list_t mViewerPartGroups;
  158. typedef std::vector<LLPointer<LLViewerPartSource> > source_list_t;
  159. source_list_t mViewerPartSources;
  160. LLFrameTimer mSimulationTimer;
  161. static S32 sMaxParticleCount;
  162. static S32 sParticleCount;
  163. static F32 sParticleAdaptiveRate;
  164. static F32 sParticleBurstRate;
  165. static constexpr S32 MAX_PART_COUNT = 8192;
  166. static constexpr F32 PART_THROTTLE_THRESHOLD = 0.9f;
  167. static constexpr F32 PART_THROTTLE_RESCALE =
  168. PART_THROTTLE_THRESHOLD / (1.f - PART_THROTTLE_THRESHOLD);
  169. static constexpr F32 PART_ADAPT_RATE_MULT = 2.f;
  170. static constexpr F32 PART_ADAPT_RATE_MULT_RECIP =
  171. 1.f / PART_ADAPT_RATE_MULT;
  172. };
  173. extern LLViewerPartSim gViewerPartSim;
  174. #endif // LL_LLVIEWERPARTSIM_H