ForceModule.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. //
  2. // ForceModule.cpp
  3. // libcocos2d Mac
  4. //
  5. // Created by 徐俊杰 on 2020/4/24.
  6. //
  7. #include "rparticle/Modules/ForceModule.h"
  8. //#include "UnityPrefix.h"
  9. //#include "rparticle/Modules/ForceModule.h"
  10. //#include "Runtime/BaseClasses/ObjectDefines.h"
  11. #include "rparticle/Serialize/TransferFunctions/SerializeTransfer.h"
  12. #include "rparticle/ParticleSystemUtils.h"
  13. #include "rparticle/Math/Random/Random.h"
  14. // Vec3
  15. #define zero ZERO
  16. // MinMaxAABB
  17. #define m_Max _max
  18. #define m_Min _min
  19. NS_RRP_BEGIN
  20. template<ParticleSystemCurveEvalMode mode>
  21. void UpdateTpl(const MinMaxCurve& x, const MinMaxCurve& y, const MinMaxCurve& z, const ParticleSystemReadOnlyState& roState, ParticleSystemParticles& ps, const size_t fromIndex, const size_t toIndex, bool transform, const Matrix4x4f& matrix, float dt)
  22. {
  23. for (size_t q = fromIndex; q < toIndex; ++q)
  24. {
  25. Vector3f random;
  26. GenerateRandom3(random, ps.randomSeed[q] + kParticleSystemForceCurveId);
  27. const float time = NormalizedTime(ps, q);
  28. Vector3f f = Vector3f (Evaluate<mode> (x, time, random.x), Evaluate<mode> (y, time, random.y), Evaluate<mode> (z, time, random.z)) * roState.GetRenderScale();
  29. if(transform)
  30. f = matrix.MultiplyVector3 (f);
  31. ps.velocity[q] += f * dt;
  32. }
  33. }
  34. template<bool isOptimized>
  35. void UpdateProceduralTpl(const DualMinMax3DPolyCurves& pos, const DualMinMax3DPolyCurves& vel, ParticleSystemParticles& ps, const Matrix4x4f& matrix, bool transform)
  36. {
  37. const size_t count = ps.array_size();
  38. for (int q=0; q<count; q++)
  39. {
  40. Vector3f random;
  41. GenerateRandom3(random, ps.randomSeed[q] + kParticleSystemForceCurveId);
  42. float time = NormalizedTime(ps, q);
  43. float range = ps.startLifetime[q];
  44. Vector3f delta;
  45. Vector3f velocity;
  46. if(isOptimized)
  47. {
  48. delta = Vector3f (EvaluateDoubleIntegrated(pos.optX, time, random.x), EvaluateDoubleIntegrated(pos.optY, time, random.y), EvaluateDoubleIntegrated(pos.optZ, time, random.z));
  49. velocity = Vector3f (EvaluateIntegrated(vel.optX, time, random.x), EvaluateIntegrated(vel.optY, time, random.y), EvaluateIntegrated(vel.optZ, time, random.z));
  50. }
  51. else
  52. {
  53. delta = Vector3f (EvaluateDoubleIntegrated(pos.x, time, random.x), EvaluateDoubleIntegrated(pos.y, time, random.y), EvaluateDoubleIntegrated(pos.z, time, random.z));
  54. velocity = Vector3f (EvaluateIntegrated(vel.x, time, random.x), EvaluateIntegrated(vel.y, time, random.y), EvaluateIntegrated(vel.z, time, random.z));
  55. }
  56. // Sqr range
  57. delta *= range * range;
  58. velocity *= range;
  59. if(transform)
  60. {
  61. delta = matrix.MultiplyVector3 (delta);
  62. velocity = matrix.MultiplyVector3 (velocity);
  63. }
  64. ps.position[q] += delta;
  65. ps.velocity[q] += velocity;
  66. }
  67. }
  68. ForceModule::ForceModule () : ParticleSystemModule(false)
  69. , m_RandomizePerFrame (false)
  70. , m_InWorldSpace(false)
  71. {}
  72. void ForceModule::Update (const ParticleSystemReadOnlyState& roState, const ParticleSystemState& state, ParticleSystemParticles& ps, const size_t fromIndex, const size_t toIndex, float dt)
  73. {
  74. Matrix4x4f matrix;
  75. bool transform = GetTransformationMatrix(matrix, !roState.useLocalSpace, m_InWorldSpace, state.localToWorld);
  76. if (m_RandomizePerFrame)
  77. {
  78. for (size_t q = fromIndex; q < toIndex; ++q)
  79. {
  80. const float t = NormalizedTime (ps, q);
  81. const float randomX = Random01 (m_Random);
  82. const float randomY = Random01 (m_Random);
  83. const float randomZ = Random01 (m_Random);
  84. Vector3f f (Evaluate (m_X, t, randomX), Evaluate (m_Y, t, randomY), Evaluate (m_Z, t, randomZ));
  85. f * roState.GetRenderScale();
  86. if(transform)
  87. f = matrix.MultiplyVector3 (f);
  88. ps.velocity[q] += f * dt;
  89. }
  90. }
  91. else
  92. {
  93. bool usesScalar = (m_X.minMaxState == kMMCScalar) && (m_Y.minMaxState == kMMCScalar) && (m_Z.minMaxState == kMMCScalar);
  94. bool isOptimized = m_X.IsOptimized() && m_Y.IsOptimized() && m_Z.IsOptimized();
  95. bool usesMinMax = m_X.UsesMinMax() && m_Y.UsesMinMax() && m_Z.UsesMinMax();
  96. if(usesScalar)
  97. UpdateTpl<kEMScalar>(m_X, m_Y, m_Z, roState, ps, fromIndex, toIndex, transform, matrix, dt);
  98. else if(isOptimized && usesMinMax)
  99. UpdateTpl<kEMOptimizedMinMax>(m_X, m_Y, m_Z, roState, ps, fromIndex, toIndex, transform, matrix, dt);
  100. else if(isOptimized)
  101. UpdateTpl<kEMOptimized>(m_X, m_Y, m_Z, roState, ps, fromIndex, toIndex, transform, matrix, dt);
  102. else
  103. UpdateTpl<kEMSlow>(m_X, m_Y, m_Z, roState, ps, fromIndex, toIndex, transform, matrix, dt);
  104. }
  105. }
  106. void ForceModule::UpdateProcedural (const ParticleSystemReadOnlyState& roState, const ParticleSystemState& state, ParticleSystemParticles& ps)
  107. {
  108. Assert(!m_RandomizePerFrame);
  109. Matrix4x4f matrix;
  110. bool transform = GetTransformationMatrix(matrix, !roState.useLocalSpace, m_InWorldSpace, state.localToWorld);
  111. DualMinMax3DPolyCurves posCurves;
  112. DualMinMax3DPolyCurves velCurves;
  113. if(m_X.IsOptimized() && m_Y.IsOptimized() && m_Z.IsOptimized())
  114. {
  115. posCurves.optX = m_X.polyCurves; posCurves.optX.DoubleIntegrate();
  116. posCurves.optY = m_Y.polyCurves; posCurves.optY.DoubleIntegrate();
  117. posCurves.optZ = m_Z.polyCurves; posCurves.optZ.DoubleIntegrate();
  118. velCurves.optX = m_X.polyCurves; velCurves.optX.Integrate();
  119. velCurves.optY = m_Y.polyCurves; velCurves.optY.Integrate();
  120. velCurves.optZ = m_Z.polyCurves; velCurves.optZ.Integrate();
  121. UpdateProceduralTpl<true>(posCurves, velCurves, ps, matrix, transform);
  122. }
  123. else
  124. {
  125. DebugAssert(CurvesSupportProcedural (m_X.editorCurves, m_X.minMaxState));
  126. DebugAssert(CurvesSupportProcedural (m_Y.editorCurves, m_Y.minMaxState));
  127. DebugAssert(CurvesSupportProcedural (m_Z.editorCurves, m_Z.minMaxState));
  128. BuildCurves(posCurves.x, m_X.editorCurves, m_X.GetScalar(), m_X.minMaxState); posCurves.x.DoubleIntegrate();
  129. BuildCurves(posCurves.y, m_Y.editorCurves, m_Y.GetScalar(), m_Y.minMaxState); posCurves.y.DoubleIntegrate();
  130. BuildCurves(posCurves.z, m_Z.editorCurves, m_Z.GetScalar(), m_Z.minMaxState); posCurves.z.DoubleIntegrate();
  131. BuildCurves(velCurves.x, m_X.editorCurves, m_X.GetScalar(), m_X.minMaxState); velCurves.x.Integrate();
  132. BuildCurves(velCurves.y, m_Y.editorCurves, m_Y.GetScalar(), m_Y.minMaxState); velCurves.y.Integrate();
  133. BuildCurves(velCurves.z, m_Z.editorCurves, m_Z.GetScalar(), m_Z.minMaxState); velCurves.z.Integrate();
  134. UpdateProceduralTpl<false>(posCurves, velCurves, ps, matrix, transform);
  135. }
  136. }
  137. void ForceModule::CalculateProceduralBounds(MinMaxAABB& bounds, const Matrix4x4f& localToWorld, float maxLifeTime)
  138. {
  139. Vector2f xRange = m_X.FindMinMaxDoubleIntegrated();
  140. Vector2f yRange = m_Y.FindMinMaxDoubleIntegrated();
  141. Vector2f zRange = m_Z.FindMinMaxDoubleIntegrated();
  142. bounds.m_Min = Vector3f(xRange.x, yRange.x, zRange.x) * maxLifeTime * maxLifeTime;
  143. bounds.m_Max = Vector3f(xRange.y, yRange.y, zRange.y) * maxLifeTime * maxLifeTime;
  144. if(m_InWorldSpace)
  145. {
  146. Matrix4x4f matrix;
  147. Matrix4x4f::Invert_General3D(localToWorld, matrix);
  148. matrix.SetPosition(Vector3f::zero);
  149. MinMaxAABB aabb = bounds;
  150. TransformAABBSlow(aabb, matrix, aabb);
  151. bounds = aabb;
  152. }
  153. }
  154. template<class TransferFunction>
  155. void ForceModule::Transfer (TransferFunction& transfer)
  156. {
  157. ParticleSystemModule::Transfer (transfer);
  158. transfer.Transfer (m_X, "x");
  159. transfer.Transfer (m_Y, "y");
  160. transfer.Transfer (m_Z, "z");
  161. transfer.Transfer (m_InWorldSpace, "inWorldSpace");
  162. transfer.Transfer (m_RandomizePerFrame, "randomizePerFrame"); transfer.Align ();
  163. }
  164. INSTANTIATE_TEMPLATE_TRANSFER(ForceModule)
  165. NS_RRP_END