ParticleSystemParticle.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. //
  2. // ParticleSystemParticle.cpp
  3. // cocos2d_libs
  4. //
  5. // Created by 徐俊杰 on 2020/4/24.
  6. //
  7. #include "rparticle/ParticleSystemParticle.h"
  8. #include "rparticle/Math/FloatConversion.h"
  9. #define yAxis UNIT_Y
  10. #define zero ZERO
  11. NS_RRP_BEGIN
  12. void InitializeEmitAccumulator(dynamic_array<float>& emitAccumulator, const size_t count)
  13. {
  14. emitAccumulator.resize_uninitialized(count);
  15. memset(emitAccumulator.begin(), 0, count * sizeof(float));
  16. }
  17. ParticleCollisionEvent::ParticleCollisionEvent (const Vector3f& intersection, const Vector3f& normal, const Vector3f& velocity, int colliderInstanceID, int rigidBodyOrColliderInstanceID)
  18. {
  19. m_Intersection = intersection;
  20. m_Normal = normal;
  21. m_Velocity = velocity;
  22. m_ColliderInstanceID = colliderInstanceID;
  23. m_RigidBodyOrColliderInstanceID = rigidBodyOrColliderInstanceID;
  24. }
  25. size_t ParticleSystemParticles::GetParticleSize()
  26. {
  27. // @TODO: How do we guard against elements we remove
  28. return sizeof(ParticleSystemParticle);
  29. }
  30. void ParticleSystemParticles::SetUsesAxisOfRotation()
  31. {
  32. usesAxisOfRotation = true;
  33. const size_t count = position.size();
  34. axisOfRotation.resize_uninitialized(count);
  35. for(int i = 0; i < count; i++)
  36. axisOfRotation[i] = Vector3f::yAxis;
  37. }
  38. void ParticleSystemParticles::SetUsesRotationalSpeed()
  39. {
  40. usesRotationalSpeed = true;
  41. const size_t count = position.size();
  42. rotationalSpeed.resize_uninitialized(count);
  43. for(int i = 0; i < count; i++)
  44. rotationalSpeed[i] = 0.0f;
  45. }
  46. void ParticleSystemParticles::SetUsesCollisionEvents (bool wantUsesCollisionEvents)
  47. {
  48. if (usesCollisionEvents == wantUsesCollisionEvents) return;
  49. usesCollisionEvents = wantUsesCollisionEvents;
  50. if (!usesCollisionEvents)
  51. {
  52. // collisionEvents.Clear ();
  53. }
  54. }
  55. bool ParticleSystemParticles::GetUsesCollisionEvents () const
  56. {
  57. return usesCollisionEvents;
  58. }
  59. void ParticleSystemParticles::SetUsesEmitAccumulator(int numAccumulators)
  60. {
  61. Assert(numAccumulators <= kParticleSystemMaxNumEmitAccumulators);
  62. const size_t count = position.size();
  63. for(int i = numEmitAccumulators; i < numAccumulators; i++)
  64. InitializeEmitAccumulator(emitAccumulator[i], count);
  65. numEmitAccumulators = numAccumulators;
  66. }
  67. void ParticleSystemParticles::CopyFromArrayAOS(ParticleSystemParticle* particles, int size)
  68. {
  69. Assert(usesAxisOfRotation);
  70. Assert(numEmitAccumulators == kParticleSystemMaxNumEmitAccumulators);
  71. for(int i = 0; i < size; i++)
  72. {
  73. (*this).position[i] = particles[i].position;
  74. (*this).velocity[i] = particles[i].velocity;
  75. (*this).animatedVelocity[i] = particles[i].animatedVelocity;
  76. (*this).axisOfRotation[i] = particles[i].axisOfRotation;
  77. (*this).rotation[i] = particles[i].rotation;
  78. if(usesRotationalSpeed)
  79. (*this).rotationalSpeed[i] = particles[i].rotationalSpeed;
  80. (*this).size[i] = particles[i].size;
  81. (*this).color[i] = particles[i].color;
  82. (*this).randomSeed[i] = particles[i].randomSeed;
  83. (*this).lifetime[i] = particles[i].lifetime;
  84. (*this).startLifetime[i] = particles[i].startLifetime;
  85. for(int acc = 0; acc < kParticleSystemMaxNumEmitAccumulators; acc++)
  86. (*this).emitAccumulator[acc][i] = particles[i].emitAccumulator[acc];
  87. }
  88. }
  89. void ParticleSystemParticles::CopyToArrayAOS(ParticleSystemParticle* particles, int size)
  90. {
  91. Assert(usesAxisOfRotation);
  92. Assert(numEmitAccumulators == kParticleSystemMaxNumEmitAccumulators);
  93. for(int i = 0; i < size; i++)
  94. {
  95. particles[i].position = (*this).position[i];
  96. particles[i].velocity = (*this).velocity[i];
  97. particles[i].animatedVelocity = (*this).animatedVelocity[i];
  98. particles[i].axisOfRotation = (*this).axisOfRotation[i];
  99. particles[i].rotation = (*this).rotation[i];
  100. if(usesRotationalSpeed)
  101. particles[i].rotationalSpeed = (*this).rotationalSpeed[i];
  102. particles[i].size = (*this).size[i];
  103. particles[i].color = (*this).color[i];
  104. particles[i].randomSeed = (*this).randomSeed[i];
  105. particles[i].lifetime = (*this).lifetime[i];
  106. particles[i].startLifetime = (*this).startLifetime[i];
  107. for(int acc = 0; acc < kParticleSystemMaxNumEmitAccumulators; acc++)
  108. particles[i].emitAccumulator[acc] = (*this).emitAccumulator[acc][i];
  109. }
  110. }
  111. void ParticleSystemParticles::AddParticle(ParticleSystemParticle* particle)
  112. {
  113. const size_t count = array_size();
  114. array_resize(count+1);
  115. position[count] = particle->position;
  116. velocity[count] = particle->velocity;
  117. animatedVelocity[count] = Vector3f::zero;
  118. lifetime[count] = particle->lifetime;
  119. startLifetime[count] = particle->startLifetime;
  120. size[count] = particle->size;
  121. rotation[count] = particle->rotation;
  122. if(usesRotationalSpeed)
  123. rotationalSpeed[count] = particle->rotationalSpeed;
  124. color[count] = particle->color;
  125. randomSeed[count] = particle->randomSeed;
  126. if(usesAxisOfRotation)
  127. axisOfRotation[count] = particle->axisOfRotation;
  128. for(int acc = 0; acc < numEmitAccumulators; acc++)
  129. emitAccumulator[acc][count] = 0.0f;
  130. }
  131. size_t ParticleSystemParticles::array_size () const
  132. {
  133. return position.size();
  134. }
  135. void ParticleSystemParticles::array_resize (size_t i)
  136. {
  137. position.resize_uninitialized(i);
  138. velocity.resize_uninitialized(i);
  139. animatedVelocity.resize_uninitialized(i);
  140. rotation.resize_uninitialized(i);
  141. if(usesRotationalSpeed)
  142. rotationalSpeed.resize_uninitialized(i);
  143. size.resize_uninitialized(i);
  144. color.resize_uninitialized(i);
  145. randomSeed.resize_uninitialized(i);
  146. lifetime.resize_uninitialized(i);
  147. startLifetime.resize_uninitialized(i);
  148. if(usesAxisOfRotation)
  149. axisOfRotation.resize_uninitialized(i);
  150. for(int acc = 0; acc < numEmitAccumulators; acc++)
  151. emitAccumulator[acc].resize_uninitialized(i);
  152. }
  153. void ParticleSystemParticles::element_swap(size_t i, size_t j)
  154. {
  155. std::swap(position[i], position[j]);
  156. std::swap(velocity[i], velocity[j]);
  157. std::swap(animatedVelocity[i], animatedVelocity[j]);
  158. std::swap(rotation[i], rotation[j]);
  159. if(usesRotationalSpeed)
  160. std::swap(rotationalSpeed[i], rotationalSpeed[j]);
  161. std::swap(size[i], size[j]);
  162. std::swap(color[i], color[j]);
  163. std::swap(randomSeed[i], randomSeed[j]);
  164. std::swap(lifetime[i], lifetime[j]);
  165. std::swap(startLifetime[i], startLifetime[j]);
  166. if(usesAxisOfRotation)
  167. std::swap(axisOfRotation[i], axisOfRotation[j]);
  168. for(int acc = 0; acc < numEmitAccumulators; acc++)
  169. std::swap(emitAccumulator[acc][i], emitAccumulator[acc][j]);
  170. }
  171. void ParticleSystemParticles::element_assign(size_t i, size_t j)
  172. {
  173. position[i] = position[j];
  174. velocity[i] = velocity[j];
  175. animatedVelocity[i] = animatedVelocity[j];
  176. rotation[i] = rotation[j];
  177. if(usesRotationalSpeed)
  178. rotationalSpeed[i] = rotationalSpeed[j];
  179. size[i] = size[j];
  180. color[i] = color[j];
  181. randomSeed[i] = randomSeed[j];
  182. lifetime[i] = lifetime[j];
  183. startLifetime[i] = startLifetime[j];
  184. if(usesAxisOfRotation)
  185. axisOfRotation[i] = axisOfRotation[j];
  186. for(int acc = 0; acc < numEmitAccumulators; acc++)
  187. emitAccumulator[acc][i] = emitAccumulator[acc][j];
  188. }
  189. void ParticleSystemParticles::array_assign_external(void* data, const int numParticles)
  190. {
  191. #define SHURIKEN_INCREMENT_ASSIGN_PTRS(element, type) { beginPtr = endPtr; endPtr += numParticles * sizeof(type); (element).assign_external((type*)beginPtr, (type*)endPtr); }
  192. UInt8* beginPtr = 0;
  193. UInt8* endPtr = (UInt8*)data;
  194. SHURIKEN_INCREMENT_ASSIGN_PTRS(position, Vector3f);
  195. SHURIKEN_INCREMENT_ASSIGN_PTRS(velocity, Vector3f);
  196. SHURIKEN_INCREMENT_ASSIGN_PTRS(animatedVelocity, Vector3f);
  197. SHURIKEN_INCREMENT_ASSIGN_PTRS(rotation, float);
  198. if(usesRotationalSpeed)
  199. SHURIKEN_INCREMENT_ASSIGN_PTRS(rotationalSpeed, float);
  200. SHURIKEN_INCREMENT_ASSIGN_PTRS(size, float);
  201. SHURIKEN_INCREMENT_ASSIGN_PTRS(color, ColorRGBA32);
  202. SHURIKEN_INCREMENT_ASSIGN_PTRS(randomSeed, UInt32);
  203. SHURIKEN_INCREMENT_ASSIGN_PTRS(lifetime, float);
  204. SHURIKEN_INCREMENT_ASSIGN_PTRS(startLifetime, float);
  205. if(usesAxisOfRotation)
  206. SHURIKEN_INCREMENT_ASSIGN_PTRS(axisOfRotation, Vector3f);
  207. for(int acc = 0; acc < numEmitAccumulators; acc++)
  208. SHURIKEN_INCREMENT_ASSIGN_PTRS(emitAccumulator[acc], float);
  209. #undef SHURIKEN_INCREMENT_ASSIGN_PTRS
  210. }
  211. void ParticleSystemParticles::array_merge_preallocated(const ParticleSystemParticles& rhs, const int offset, const bool needAxisOfRotation, const bool needEmitAccumulator)
  212. {
  213. #define SHURIKEN_COPY_DATA(element, type) memcpy(&element[offset], &rhs.element[0], count * sizeof(type))
  214. const size_t count = rhs.array_size();
  215. if(0 == count)
  216. return;
  217. Assert((rhs.array_size() + offset) <= array_size());
  218. SHURIKEN_COPY_DATA(position, Vector3f);
  219. SHURIKEN_COPY_DATA(velocity, Vector3f);
  220. SHURIKEN_COPY_DATA(animatedVelocity, Vector3f);
  221. SHURIKEN_COPY_DATA(rotation, float);
  222. if(usesRotationalSpeed)
  223. SHURIKEN_COPY_DATA(rotationalSpeed, float);
  224. SHURIKEN_COPY_DATA(size, float);
  225. SHURIKEN_COPY_DATA(color, ColorRGBA32);
  226. SHURIKEN_COPY_DATA(randomSeed, UInt32);
  227. SHURIKEN_COPY_DATA(lifetime, float);
  228. SHURIKEN_COPY_DATA(startLifetime, float);
  229. if(needAxisOfRotation)
  230. {
  231. Assert(usesAxisOfRotation && rhs.usesAxisOfRotation);
  232. SHURIKEN_COPY_DATA(axisOfRotation, Vector3f);
  233. }
  234. if(needEmitAccumulator)
  235. {
  236. Assert(numEmitAccumulators && rhs.numEmitAccumulators);
  237. Assert(numEmitAccumulators == rhs.numEmitAccumulators);
  238. for(int acc = 0; acc < numEmitAccumulators; acc++)
  239. SHURIKEN_COPY_DATA(emitAccumulator[acc], float);
  240. }
  241. #undef SHURIKEN_COPY_DATA
  242. }
  243. void ParticleSystemParticles::array_assign(const ParticleSystemParticles& rhs)
  244. {
  245. position.assign(rhs.position.begin(), rhs.position.end());
  246. velocity.assign(rhs.velocity.begin(), rhs.velocity.end());
  247. animatedVelocity.assign(rhs.animatedVelocity.begin(), rhs.animatedVelocity.end());
  248. rotation.assign(rhs.rotation.begin(), rhs.rotation.end());
  249. if(usesRotationalSpeed)
  250. rotationalSpeed.assign(rhs.rotationalSpeed.begin(), rhs.rotationalSpeed.end());
  251. size.assign(rhs.size.begin(), rhs.size.end());
  252. color.assign(rhs.color.begin(), rhs.color.end());
  253. randomSeed.assign(rhs.randomSeed.begin(), rhs.randomSeed.end());
  254. lifetime.assign(rhs.lifetime.begin(), rhs.lifetime.end());
  255. startLifetime.assign(rhs.startLifetime.begin(), rhs.startLifetime.end());
  256. if(usesAxisOfRotation)
  257. axisOfRotation.assign(rhs.axisOfRotation.begin(), rhs.axisOfRotation.end());
  258. for(int acc = 0; acc < numEmitAccumulators; acc++)
  259. emitAccumulator[acc].assign(rhs.emitAccumulator[acc].begin(), rhs.emitAccumulator[acc].end());
  260. }
  261. void ParticleSystemParticles::array_lerp(ParticleSystemParticles& output, const ParticleSystemParticles& a, const ParticleSystemParticles& b, float factor)
  262. {
  263. DebugAssert(a.array_size() == b.array_size()); // else it doesn't really make sense
  264. DebugAssert(a.usesRotationalSpeed == b.usesRotationalSpeed);
  265. const int count = a.array_size();
  266. output.array_resize(count);
  267. // Note: Not all data is interpolated here intentionally, because it doesn't change anything or because it's incorrect
  268. #define SHURIKEN_LERP_DATA(element, type) for(int i = 0; i < count; i++) output.element[i] = Lerp(a.element[i], b.element[i], factor)
  269. SHURIKEN_LERP_DATA(position, Vector3f);
  270. SHURIKEN_LERP_DATA(velocity, Vector3f);
  271. SHURIKEN_LERP_DATA(animatedVelocity, Vector3f);
  272. SHURIKEN_LERP_DATA(rotation, float);
  273. if(a.usesRotationalSpeed)
  274. SHURIKEN_LERP_DATA(rotationalSpeed, float);
  275. SHURIKEN_LERP_DATA(lifetime, float);
  276. #undef SHURIKEN_LERP_DATA
  277. }
  278. ParticleSystemParticlesTempData::ParticleSystemParticlesTempData()
  279. :color(0)
  280. ,size(0)
  281. ,sheetIndex(0)
  282. ,particleCount(0)
  283. {}
  284. void ParticleSystemParticlesTempData::element_swap(size_t i, size_t j)
  285. {
  286. DebugAssert(i <= particleCount);
  287. DebugAssert(j <= particleCount);
  288. std::swap(color[i], color[j]);
  289. std::swap(size[i], size[j]);
  290. if(sheetIndex)
  291. std::swap(sheetIndex[i], sheetIndex[j]);
  292. }
  293. NS_RRP_END