ParticleSystemCurves.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. //
  2. // ParticleSystemCurves.h
  3. // cocos2d_libs
  4. //
  5. // Created by 徐俊杰 on 2020/4/24.
  6. //
  7. #ifndef ParticleSystemCurves_h
  8. #define ParticleSystemCurves_h
  9. //#include "cocos2d.h"
  10. #include "rparticle/Macros/RParticleMacros.h"
  11. #include "rparticle/ParticleSystemParticle.h"
  12. #include "rparticle/PolynomialCurve.h"
  13. #include "rparticle/Math/AnimationCurve.h"
  14. NS_RRP_BEGIN
  15. struct MinMaxCurve;
  16. // Some profile numbers from a run with 250,000 particles evaluating 3 velocity properties each on Intel i7-2600 CPU @ 3.4 GHz
  17. // Scalar: 4.6 ms
  18. // Optimized curve: 7.2 ms
  19. // Random between 2 scalars: 9.5 ms
  20. // Random between 2 curves: 9.5 ms
  21. // Non-optimized curve: 10.0 ms
  22. // Random between 2 non-optimized curves: 12.0 ms
  23. enum ParticleSystemCurveEvalMode
  24. {
  25. kEMScalar,
  26. kEMOptimized,
  27. kEMOptimizedMinMax,
  28. kEMSlow,
  29. };
  30. enum MinMaxCurveState
  31. {
  32. kMMCScalar = 0,
  33. kMMCCurve = 1,
  34. kMMCTwoCurves = 2,
  35. kMMCTwoConstants = 3
  36. };
  37. struct MinMaxOptimizedPolyCurves
  38. {
  39. void Integrate();
  40. void DoubleIntegrate();
  41. Vector2f FindMinMaxIntegrated();
  42. Vector2f FindMinMaxDoubleIntegrated();
  43. OptimizedPolynomialCurve max;
  44. OptimizedPolynomialCurve min;
  45. };
  46. inline float EvaluateIntegrated (const MinMaxOptimizedPolyCurves& curves, float t, float factor)
  47. {
  48. const float v0 = curves.min.EvaluateIntegrated (t);
  49. const float v1 = curves.max.EvaluateIntegrated (t);
  50. return Lerp (v0, v1, factor);
  51. }
  52. inline float EvaluateDoubleIntegrated (const MinMaxOptimizedPolyCurves& curves, float t, float factor)
  53. {
  54. const float v0 = curves.min.EvaluateDoubleIntegrated (t);
  55. const float v1 = curves.max.EvaluateDoubleIntegrated (t);
  56. return Lerp (v0, v1, factor);
  57. }
  58. struct MinMaxPolyCurves
  59. {
  60. void Integrate();
  61. void DoubleIntegrate();
  62. Vector2f FindMinMaxIntegrated();
  63. Vector2f FindMinMaxDoubleIntegrated();
  64. PolynomialCurve max;
  65. PolynomialCurve min;
  66. };
  67. inline float EvaluateIntegrated (const MinMaxPolyCurves& curves, float t, float factor)
  68. {
  69. const float v0 = curves.min.EvaluateIntegrated (t);
  70. const float v1 = curves.max.EvaluateIntegrated (t);
  71. return Lerp (v0, v1, factor);
  72. }
  73. inline float EvaluateDoubleIntegrated (const MinMaxPolyCurves& curves, float t, float factor)
  74. {
  75. const float v0 = curves.min.EvaluateDoubleIntegrated (t);
  76. const float v1 = curves.max.EvaluateDoubleIntegrated (t);
  77. return Lerp (v0, v1, factor);
  78. }
  79. struct MinMaxAnimationCurves
  80. {
  81. bool SupportsProcedural ();
  82. AnimationCurve max;
  83. AnimationCurve min;
  84. };
  85. bool BuildCurves (MinMaxOptimizedPolyCurves& polyCurves, const MinMaxAnimationCurves& editorCurves, float scalar, short minMaxState);
  86. void BuildCurves (MinMaxPolyCurves& polyCurves, const MinMaxAnimationCurves& editorCurves, float scalar, short minMaxState);
  87. bool CurvesSupportProcedural (const MinMaxAnimationCurves& editorCurves, short minMaxState);
  88. struct MinMaxCurve
  89. {
  90. MinMaxOptimizedPolyCurves polyCurves;
  91. private:
  92. float scalar; // Since scalar is baked into the optimized curve we use the setter function to modify it.
  93. public:
  94. short minMaxState; // see enum MinMaxCurveState
  95. bool isOptimizedCurve;
  96. MinMaxAnimationCurves editorCurves;
  97. MinMaxCurve ();
  98. inline float GetScalar() const { return scalar; }
  99. inline void SetScalar(float value) { scalar = value; BuildCurves(polyCurves, editorCurves, scalar, minMaxState); }
  100. inline void SetScalarNoBuild(float value) { scalar = value; }
  101. bool IsOptimized () const { return isOptimizedCurve; }
  102. bool UsesMinMax () const { return (minMaxState == kMMCTwoCurves) || (minMaxState == kMMCTwoConstants); }
  103. void OnSetDataEnd() { isOptimizedCurve = BuildCurves(polyCurves, editorCurves, scalar, minMaxState); }
  104. //TODO: Serialize
  105. /*
  106. DEFINE_GET_TYPESTRING (MinMaxCurve)
  107. */
  108. template<class TransferFunction>
  109. void Transfer (TransferFunction& transfer);
  110. Vector2f FindMinMax() const;
  111. Vector2f FindMinMaxIntegrated() const;
  112. Vector2f FindMinMaxDoubleIntegrated() const;
  113. };
  114. inline float EvaluateSlow (const MinMaxCurve& curve, float t, float factor)
  115. {
  116. const float v = curve.editorCurves.max.Evaluate(t) * curve.GetScalar ();
  117. if (curve.minMaxState == kMMCTwoCurves)
  118. return Lerp (curve.editorCurves.min.Evaluate(t) * curve.GetScalar (), v, factor);
  119. else
  120. return v;
  121. }
  122. template<ParticleSystemCurveEvalMode mode>
  123. inline float Evaluate (const MinMaxCurve& curve, float t, float factor = 1.0F)
  124. {
  125. if(mode == kEMScalar)
  126. {
  127. return curve.GetScalar();
  128. }
  129. if(mode == kEMOptimized)
  130. {
  131. DebugAssert(curve.isOptimizedCurve);
  132. return curve.polyCurves.max.Evaluate (t);
  133. }
  134. else if (mode == kEMOptimizedMinMax)
  135. {
  136. DebugAssert(curve.isOptimizedCurve);
  137. const float v0 = curve.polyCurves.min.Evaluate (t);
  138. const float v1 = curve.polyCurves.max.Evaluate (t);
  139. return Lerp (v0, v1, factor);
  140. }
  141. else if (mode == kEMSlow)
  142. {
  143. return EvaluateSlow (curve, t, factor);
  144. }
  145. }
  146. inline float Evaluate (const MinMaxCurve& curve, float t, float randomValue = 1.0F)
  147. {
  148. if (curve.minMaxState == kMMCScalar)
  149. return curve.GetScalar ();
  150. if (curve.minMaxState == kMMCTwoConstants)
  151. return Lerp ( curve.editorCurves.min.GetKey(0).value * curve.GetScalar (),
  152. curve.editorCurves.max.GetKey(0).value * curve.GetScalar (), randomValue);
  153. DebugAssert(t <= 1.0F && t >= 0.0F);
  154. if (curve.isOptimizedCurve)
  155. return Evaluate<kEMOptimizedMinMax> (curve, t, randomValue);
  156. else
  157. return Evaluate<kEMSlow> (curve, t, randomValue);
  158. }
  159. struct DualMinMax3DPolyCurves
  160. {
  161. MinMaxOptimizedPolyCurves optX;
  162. MinMaxOptimizedPolyCurves optY;
  163. MinMaxOptimizedPolyCurves optZ;
  164. MinMaxPolyCurves x;
  165. MinMaxPolyCurves y;
  166. MinMaxPolyCurves z;
  167. };
  168. NS_RRP_END
  169. #endif /* ParticleSystemCurves_h */