ParticleSystemUtils.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //
  2. // ParticleSystemUtils.cpp
  3. // cocos2d_libs
  4. //
  5. // Created by 徐俊杰 on 2020/4/24.
  6. //
  7. #include "rparticle/ParticleSystemUtils.h"
  8. #include "rparticle/Modules/ParticleSystemModule.h"
  9. #include "rparticle/ParticleSystemParticle.h"
  10. #include "rparticle/Modules/ColorModule.h"
  11. #include "rparticle/Modules/ColorByVelocityModule.h"
  12. #include "rparticle/Modules/SizeModule.h"
  13. #include "rparticle/Modules/SizeByVelocityModule.h"
  14. #include "rparticle/Modules/SubEmitterModule.h"
  15. NS_RRP_BEGIN
  16. UInt32 randomSeed = 0x1337;
  17. UInt32 GetGlobalRandomSeed ()
  18. {
  19. return ++randomSeed;
  20. }
  21. void ResetGlobalRandomSeed ()
  22. {
  23. randomSeed = 0x1337;
  24. }
  25. Vector2f CalculateInverseLerpOffsetScale (const Vector2f& range)
  26. {
  27. Assert (range.x < range.y);
  28. float scale = 1.0F / (range.y - range.x);
  29. return Vector2f (scale, -range.x * scale);
  30. }
  31. void CalculatePositionAndVelocity(Vector3f& initialPosition, Vector3f& initialVelocity, const ParticleSystemReadOnlyState& roState, const ParticleSystemState& state, const ParticleSystemParticles& ps, const size_t index)
  32. {
  33. initialPosition = ps.position[index];
  34. initialVelocity = ps.velocity[index] + ps.animatedVelocity[index];
  35. if(roState.useLocalSpace)
  36. {
  37. // If we are in local space, transform to world space to make independent of this emitters transform
  38. // initialPosition = state.localToWorld.MultiplyPoint3(initialPosition);
  39. // initialVelocity = state.localToWorld.MultiplyVector3(initialVelocity);
  40. state.localToWorld.transformPoint(&initialPosition);
  41. state.localToWorld.transformVector(&initialVelocity);
  42. }
  43. }
  44. static void CalculateInheritedProperties(const ParticleSystemReadOnlyState& roState, SubEmitterInheritValues& initialProperties, int properties, const ParticleSystemParticle& particle, RParticleSystem* srcSystem, float normalizedT)
  45. {
  46. if (properties & SubEmitterModule::kInheritColor)
  47. {
  48. initialProperties.color = particle.color;
  49. if (srcSystem->GetColorModule()->GetEnabled())
  50. srcSystem->GetColorModule()->UpdateSingle(particle, initialProperties.color);
  51. if (srcSystem->GetColorBySpeedModule()->GetEnabled())
  52. srcSystem->GetColorBySpeedModule()->UpdateSingle(roState, particle, initialProperties.color);
  53. }
  54. if (properties & SubEmitterModule::kInheritSize)
  55. {
  56. initialProperties.size = particle.size;
  57. if (srcSystem->GetSizeModule()->GetEnabled())
  58. srcSystem->GetSizeModule()->UpdateSingle(particle, true, initialProperties.size);
  59. if (srcSystem->GetSizeBySpeedModule()->GetEnabled())
  60. srcSystem->GetSizeBySpeedModule()->UpdateSingle(roState, particle, true, initialProperties.size);
  61. }
  62. if (properties & SubEmitterModule::kInheritRotation)
  63. {
  64. initialProperties.rotation = particle.rotation;
  65. initialProperties.axisOfRotation = particle.axisOfRotation;
  66. }
  67. if (properties & SubEmitterModule::kInheritLifetime)
  68. {
  69. initialProperties.lifetimeMultiplier = particle.lifetime;
  70. }
  71. if (properties & SubEmitterModule::kInheritDuration)
  72. {
  73. initialProperties.normalizedT = normalizedT;
  74. }
  75. }
  76. void KillParticle(const ParticleSystemReadOnlyState& roState, ParticleSystemState& state, ParticleSystemParticles& ps, size_t index, size_t& particleCount)
  77. {
  78. Assert(particleCount > 0);
  79. for(int i = 0; i < state.numCachedSubDataDeath; i++)
  80. {
  81. ParticleSystemEmissionState emissionState;
  82. RecordEmit(emissionState, state.cachedSubDataDeath[i], roState, state, ps, kParticleSystemSubTypeDeath, i, index, 0.0f, 0.0001f, 1.0f);
  83. }
  84. ps.element_assign (index, particleCount - 1);
  85. --particleCount;
  86. }
  87. void RecordEmit(ParticleSystemEmissionState& emissionState, const ParticleSystemSubEmitterData& subEmitterData, const ParticleSystemReadOnlyState& roState, ParticleSystemState& state, ParticleSystemParticles& ps, ParticleSystemSubType type, int subEmitterIndex, size_t particleIndex, float t, float dt, float length)
  88. {
  89. size_t numContinuous = 0;
  90. Vector3f initialPosition;
  91. Vector3f initialVelocity;
  92. CalculatePositionAndVelocity(initialPosition, initialVelocity, roState, state, ps, particleIndex);
  93. int amountOfParticlesToEmit = RParticleSystem::EmitFromData (roState, emissionState, numContinuous, subEmitterData.emissionData, initialVelocity, t, std::min(t + dt, length), dt, length);
  94. if(amountOfParticlesToEmit)
  95. {
  96. SubEmitterInheritValues inheritValues;
  97. auto subEmitterProperties = subEmitterData.properties;
  98. if (subEmitterProperties)
  99. {
  100. ParticleSystemParticle particle;
  101. //particle.position = ps.position[particleIndex];
  102. //particle.velocity = ps.velocity[particleIndex];
  103. //particle.animatedVelocity = ps.animatedVelocity[particleIndex];
  104. particle.color = ps.color[particleIndex];
  105. particle.size = ps.size[particleIndex] / roState.GetRenderScale();
  106. particle.startLifetime = ps.startLifetime[particleIndex];
  107. particle.lifetime = ps.lifetime[particleIndex];
  108. particle.rotation = ps.rotation[particleIndex];
  109. particle.axisOfRotation = ps.usesAxisOfRotation ? ps.axisOfRotation[particleIndex] : Vector3f::UNIT_Z;
  110. CalculateInheritedProperties(roState, inheritValues, subEmitterProperties, particle, state.system, t);
  111. }
  112. if(!state.recordSubEmits)
  113. RParticleSystem::Emit(*subEmitterData.emitter, SubEmitterEmitCommand(emissionState, initialPosition, initialVelocity, inheritValues, type, subEmitterIndex, amountOfParticlesToEmit, numContinuous, t, dt), kParticleSystemEMStaging);
  114. else if(!state.subEmitterCommandBuffer.IsFull())
  115. state.subEmitterCommandBuffer.AddCommand(emissionState, initialPosition, initialVelocity, inheritValues, type, subEmitterIndex, amountOfParticlesToEmit, numContinuous, t, dt);
  116. }
  117. }
  118. bool GetTransformationMatrix(Matrix4x4f& output, const bool isSystemInWorld, const bool isCurveInWorld, const Matrix4x4f& localToWorld)
  119. {
  120. if(isCurveInWorld != isSystemInWorld)
  121. {
  122. if(isSystemInWorld)
  123. output = localToWorld;
  124. else
  125. // Matrix4x4f::Invert_General3D(localToWorld, output);
  126. output = localToWorld.getInversed();
  127. return true;
  128. }
  129. else
  130. {
  131. // output = Matrix4x4f::identity;
  132. output.setIdentity();
  133. return false;
  134. }
  135. }
  136. bool GetTransformationMatrices(Matrix4x4f& output, Matrix4x4f& outputInverse, const bool isSystemInWorld, const bool isCurveInWorld, const Matrix4x4f& localToWorld)
  137. {
  138. if(isCurveInWorld != isSystemInWorld)
  139. {
  140. if(isSystemInWorld)
  141. {
  142. output = localToWorld;
  143. // Matrix4x4f::Invert_General3D(localToWorld, outputInverse);
  144. outputInverse = localToWorld.getInversed();
  145. }
  146. else
  147. {
  148. // Matrix4x4f::Invert_General3D(localToWorld, output);
  149. output = localToWorld.getInversed();
  150. outputInverse = localToWorld;
  151. }
  152. return true;
  153. }
  154. else
  155. {
  156. // output = Matrix4x4f::identity;
  157. // outputInverse = Matrix4x4f::identity;
  158. output.setIdentity();
  159. outputInverse.setIdentity();
  160. return false;
  161. }
  162. }
  163. NS_RRP_END