ParticleSystemModule.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. //
  2. // ParticleSystemModule.cpp
  3. // libcocos2d Mac
  4. //
  5. // Created by 徐俊杰 on 2020/4/24.
  6. //
  7. #include "rparticle/Modules/ParticleSystemModule.h"
  8. #include "rparticle/Serialize/TransferFunctions/SerializeTransfer.h"
  9. #include "base/CCDirector.h"
  10. #include "rparticle/Utilities/Transform.h"
  11. #include "renderer/CCTexture2D.h"
  12. #define zero ZERO
  13. #define one ONE
  14. #define SetIdentity setIdentity
  15. NS_RRP_BEGIN
  16. RRP_PARTICLEQUAD_VERTEX_INFO RRP_PARTICLEQUAD_VERTEX_INFO::Create(cocos2d::Texture2D *texture, const cocos2d::Rect& pointRect, bool isRotaed, const cocos2d::Vec2& offset, const cocos2d::Vec2& originalSize)
  17. {
  18. // convert to Tex coords
  19. RRP_PARTICLEQUAD_VERTEX_INFO _vertexInfo;
  20. const auto& rect = pointRect;
  21. GLfloat wide = (GLfloat) pointRect.size.width;
  22. GLfloat high = (GLfloat) pointRect.size.height;
  23. float rw = rect.size.width;
  24. float rh = rect.size.height;
  25. if (isRotaed)
  26. std::swap(rw, rh);
  27. if (texture)
  28. {
  29. wide = (GLfloat)texture->getPixelsWide();
  30. high = (GLfloat)texture->getPixelsHigh();
  31. }
  32. #if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
  33. GLfloat left = (rect.origin.x*2+1) / (wide*2);
  34. GLfloat bottom = (rect.origin.y*2+1) / (high*2);
  35. GLfloat right = left + (rw*2-2) / (wide*2);
  36. GLfloat top = bottom + (rh*2-2) / (high*2);
  37. #else
  38. GLfloat left = rect.origin.x / wide;
  39. GLfloat bottom = rect.origin.y / high;
  40. GLfloat right = left + rw / wide;
  41. GLfloat top = bottom + rh / high;
  42. #endif // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
  43. // Important. Texture in cocos2d are inverted, so the Y component should be inverted
  44. std::swap(top, bottom);
  45. // CCASSERT(_texNumber < 100, "纹理数量超过上限");
  46. //
  47. if (isRotaed)
  48. {
  49. _vertexInfo.bl.u = left;
  50. _vertexInfo.bl.v = top;
  51. _vertexInfo.br.u = left;
  52. _vertexInfo.br.v = bottom;
  53. _vertexInfo.tl.u = right;
  54. _vertexInfo.tl.v = top;
  55. _vertexInfo.tr.u = right;
  56. _vertexInfo.tr.v = bottom;
  57. }
  58. else
  59. {
  60. _vertexInfo.bl.u = left;
  61. _vertexInfo.bl.v = bottom;
  62. _vertexInfo.br.u = right;
  63. _vertexInfo.br.v = bottom;
  64. _vertexInfo.tl.u = left;
  65. _vertexInfo.tl.v = top;
  66. _vertexInfo.tr.u = right;
  67. _vertexInfo.tr.v = top;
  68. }
  69. // if (!offset.isZero()){
  70. // // CCLOG("");
  71. // }
  72. float originalSizeX_2 = 2 / originalSize.x; // 宽的一半的倒数
  73. float originalSizeY_2 = 2 / originalSize.y;
  74. float x1 = (pointRect.size.width * 0.5 - offset.x) * originalSizeX_2;
  75. float x2 = (pointRect.size.width * 0.5 + offset.x) * originalSizeX_2;
  76. float aspectRatio = originalSize.y / originalSize.x;
  77. float y1 = (pointRect.size.height * 0.5 - offset.y) * originalSizeY_2 * aspectRatio;
  78. float y2 = (pointRect.size.height * 0.5 + offset.y) * originalSizeY_2 * aspectRatio;
  79. _vertexInfo.centerPercentage.set(x1, x2, y1, y2);
  80. // auto halfScale = Vec2(pointRect.size.width / originalSize.x, pointRect.size.height / originalSize.y) * 0.5f;
  81. // auto offsetScale = Vec2(offset.x / originalSize.x, offset.y / originalSize.y);
  82. //
  83. // _vertexInfo.border.set(halfScale.x - offsetScale.x, halfScale.x + offsetScale.x, halfScale.y - offsetScale.y, halfScale.y + offsetScale.y);
  84. return _vertexInfo;
  85. }
  86. ParticleSystemReadOnlyState::ParticleSystemReadOnlyState()
  87. : lengthInSec (5.0f)
  88. , startDelay (0.0f)
  89. , speed (1.0f)
  90. , randomSeed (0)
  91. , looping (true)
  92. , prewarm (false)
  93. , scalingMode(0)
  94. , playOnAwake (true)
  95. , useLocalSpace (true)
  96. {
  97. }
  98. void ParticleSystemReadOnlyState::CheckConsistency()
  99. {
  100. lengthInSec = std::max(lengthInSec, 0.1f);
  101. lengthInSec = std::min(lengthInSec, 100000.0f); // Very large values can lead to editor locking up due to numerical instability.
  102. startDelay = std::max(startDelay, 0.0f);
  103. speed = std::max(speed, 0.0f);
  104. }
  105. float ParticleSystemReadOnlyState::GetRenderScale() const
  106. {
  107. return scale * CC_CONTENT_SCALE_FACTOR();
  108. }
  109. template<class TransferFunction>
  110. void ParticleSystemReadOnlyState::Transfer (TransferFunction& transfer)
  111. {
  112. TRANSFER (lengthInSec);
  113. TRANSFER (startDelay);
  114. TRANSFER (speed);
  115. TRANSFER (randomSeed);
  116. TRANSFER (looping);
  117. TRANSFER (prewarm);
  118. TRANSFER (playOnAwake);
  119. transfer.Transfer (useLocalSpace, "moveWithTransform");
  120. }
  121. INSTANTIATE_TEMPLATE_TRANSFER(ParticleSystemReadOnlyState)
  122. ParticleSystemState::ParticleSystemState (RParticleSystem* system_)
  123. : system(system_)
  124. , playing (false)
  125. , needRestart (true)
  126. , stopEmitting (false)
  127. , accumulatedDt (0.0f)
  128. , delayT (0.0f)
  129. , t (0.0f)
  130. , maxSize (0.0f)
  131. , isSubEmitter (false)
  132. , recordSubEmits(false)
  133. , cullTime(0.0)
  134. , culled(false)
  135. , numLoops(0)
  136. , invalidateProcedural(false)
  137. , supportsProcedural(true)
  138. , cachedForces(0)
  139. , numCachedForces(0)
  140. , cachedSubDataBirth(0)
  141. , numCachedSubDataBirth(0)
  142. , cachedSubDataCollision(0)
  143. , numCachedSubDataCollision(0)
  144. , cachedSubDataDeath(0)
  145. , numCachedSubDataDeath(0)
  146. , cachedCollisionPlanes(0)
  147. , numCachedCollisionPlanes(0)
  148. , rayBudget(0)
  149. , nextParticleToTrace(0)
  150. {
  151. ClearSubEmitterCommandBuffer();
  152. localToWorld.SetIdentity ();
  153. emitterVelocity = Vector3f::zero;
  154. emitterScale = Vector3f::one;
  155. minMaxAABB = MinMaxAABB (Vector3f::zero, Vector3f::zero);
  156. }
  157. void ParticleSystemState::Tick (const ParticleSystemReadOnlyState& constState, float dt)
  158. {
  159. t += dt;
  160. for(int i = 0; i < subEmitterCommandBuffer.commandCount; i++)
  161. subEmitterCommandBuffer.commands[i].timeAlive += dt;
  162. if (!constState.looping)
  163. t = std::min<float> (t, constState.lengthInSec);
  164. else
  165. if(t > constState.lengthInSec)
  166. {
  167. t -= constState.lengthInSec;
  168. numLoops++;
  169. }
  170. }
  171. void ParticleSystemState::ClearSubEmitterCommandBuffer()
  172. {
  173. if(cachedSubDataBirth)
  174. {
  175. for (int i = 0; i < numCachedSubDataBirth; ++i)
  176. {
  177. (cachedSubDataBirth+i)->~ParticleSystemSubEmitterData();
  178. }
  179. FREE_TEMP_MANUAL(cachedSubDataBirth);
  180. }
  181. if(cachedSubDataCollision)
  182. {
  183. for (int i = 0; i < numCachedSubDataCollision; ++i)
  184. {
  185. (cachedSubDataCollision+i)->~ParticleSystemSubEmitterData();
  186. }
  187. FREE_TEMP_MANUAL(cachedSubDataCollision);
  188. }
  189. if(cachedSubDataDeath)
  190. {
  191. for (int i = 0; i < numCachedSubDataDeath; ++i)
  192. {
  193. (cachedSubDataDeath+i)->~ParticleSystemSubEmitterData();
  194. }
  195. FREE_TEMP_MANUAL(cachedSubDataDeath);
  196. }
  197. if(subEmitterCommandBuffer.commands)
  198. FREE_TEMP_MANUAL(subEmitterCommandBuffer.commands);
  199. cachedSubDataBirth = cachedSubDataCollision = cachedSubDataDeath = 0;
  200. numCachedSubDataBirth = numCachedSubDataCollision = numCachedSubDataDeath = 0;
  201. subEmitterCommandBuffer.commands = 0;
  202. subEmitterCommandBuffer.commandCount = subEmitterCommandBuffer.maxCommandCount = 0;
  203. }
  204. template<class TransferFunction>
  205. void ParticleSystemState::Transfer (TransferFunction& transfer)
  206. {
  207. // TRANSFER_DEBUG (t);
  208. }
  209. INSTANTIATE_TEMPLATE_TRANSFER(ParticleSystemState)
  210. template<class TransferFunction>
  211. void ParticleSystemModule::Transfer (TransferFunction& transfer)
  212. {
  213. transfer.Transfer (m_Enabled, "enabled"); transfer.Align ();
  214. }
  215. INSTANTIATE_TEMPLATE_TRANSFER(ParticleSystemModule)
  216. NS_RRP_END