b2ParticleGroup.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * Copyright (c) 2013 Google, Inc.
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software
  12. * in a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. * 2. Altered source versions must be plainly marked as such, and must not be
  15. * misrepresented as being the original software.
  16. * 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include <Box2D/Particle/b2ParticleGroup.h>
  19. #include <Box2D/Particle/b2ParticleSystem.h>
  20. #include <Box2D/Dynamics/b2World.h>
  21. #if LIQUIDFUN_EXTERNAL_LANGUAGE_API
  22. #include <Box2D/Collision/Shapes/b2CircleShape.h>
  23. #endif //LIQUIDFUN_EXTERNAL_LANGUAGE_API
  24. b2ParticleGroup::b2ParticleGroup()
  25. {
  26. m_system = NULL;
  27. m_firstIndex = 0;
  28. m_lastIndex = 0;
  29. m_groupFlags = 0;
  30. m_strength = 1.0f;
  31. m_prev = NULL;
  32. m_next = NULL;
  33. m_timestamp = -1;
  34. m_mass = 0;
  35. m_inertia = 0;
  36. m_center = b2Vec2_zero;
  37. m_linearVelocity = b2Vec2_zero;
  38. m_angularVelocity = 0;
  39. m_transform.SetIdentity();
  40. m_userData = NULL;
  41. }
  42. uint32 b2ParticleGroup::GetAllParticleFlags() const
  43. {
  44. uint32 flags = 0;
  45. for (int32 i = m_firstIndex; i < m_lastIndex; i++)
  46. {
  47. flags |= m_system->m_flagsBuffer.data[i];
  48. }
  49. return flags;
  50. }
  51. void b2ParticleGroup::SetGroupFlags(uint32 flags)
  52. {
  53. b2Assert((flags & b2_particleGroupInternalMask) == 0);
  54. flags |= m_groupFlags & b2_particleGroupInternalMask;
  55. m_system->SetGroupFlags(this, flags);
  56. }
  57. void b2ParticleGroup::UpdateStatistics() const
  58. {
  59. if (m_timestamp != m_system->m_timestamp)
  60. {
  61. float32 m = m_system->GetParticleMass();
  62. m_mass = 0;
  63. m_center.SetZero();
  64. m_linearVelocity.SetZero();
  65. for (int32 i = m_firstIndex; i < m_lastIndex; i++)
  66. {
  67. m_mass += m;
  68. m_center += m * m_system->m_positionBuffer.data[i];
  69. m_linearVelocity += m * m_system->m_velocityBuffer.data[i];
  70. }
  71. if (m_mass > 0)
  72. {
  73. m_center *= 1 / m_mass;
  74. m_linearVelocity *= 1 / m_mass;
  75. }
  76. m_inertia = 0;
  77. m_angularVelocity = 0;
  78. for (int32 i = m_firstIndex; i < m_lastIndex; i++)
  79. {
  80. b2Vec2 p = m_system->m_positionBuffer.data[i] - m_center;
  81. b2Vec2 v = m_system->m_velocityBuffer.data[i] - m_linearVelocity;
  82. m_inertia += m * b2Dot(p, p);
  83. m_angularVelocity += m * b2Cross(p, v);
  84. }
  85. if (m_inertia > 0)
  86. {
  87. m_angularVelocity *= 1 / m_inertia;
  88. }
  89. m_timestamp = m_system->m_timestamp;
  90. }
  91. }
  92. void b2ParticleGroup::ApplyForce(const b2Vec2& force)
  93. {
  94. m_system->ApplyForce(m_firstIndex, m_lastIndex, force);
  95. }
  96. void b2ParticleGroup::ApplyLinearImpulse(const b2Vec2& impulse)
  97. {
  98. m_system->ApplyLinearImpulse(m_firstIndex, m_lastIndex, impulse);
  99. }
  100. void b2ParticleGroup::DestroyParticles(bool callDestructionListener)
  101. {
  102. b2Assert(m_system->m_world->IsLocked() == false);
  103. if (m_system->m_world->IsLocked())
  104. {
  105. return;
  106. }
  107. for (int32 i = m_firstIndex; i < m_lastIndex; i++) {
  108. m_system->DestroyParticle(i, callDestructionListener);
  109. }
  110. }
  111. #if LIQUIDFUN_EXTERNAL_LANGUAGE_API
  112. void b2ParticleGroupDef::FreeShapesMemory() {
  113. if (circleShapes)
  114. {
  115. delete[] circleShapes;
  116. circleShapes = NULL;
  117. }
  118. if (ownShapesArray && shapes)
  119. {
  120. delete[] shapes;
  121. shapes = NULL;
  122. ownShapesArray = false;
  123. }
  124. }
  125. void b2ParticleGroupDef::SetCircleShapesFromVertexList(void* inBuf,
  126. int numShapes,
  127. float radius)
  128. {
  129. float* points = (float*) inBuf;
  130. // Create circle shapes from vertex list and radius
  131. b2CircleShape* pCircleShapes = new b2CircleShape[numShapes];
  132. b2Shape** pShapes = new b2Shape*[numShapes];
  133. for (int i = 0; i < numShapes; ++i) {
  134. pCircleShapes[i].m_radius = radius;
  135. pCircleShapes[i].m_p = b2Vec2(points[i*2], points[i*2+1]);
  136. pShapes[i] = &pCircleShapes[i];
  137. }
  138. // Clean up existing buffers
  139. FreeShapesMemory();
  140. // Assign to newly created buffers
  141. ownShapesArray = true;
  142. circleShapes = pCircleShapes;
  143. shapes = pShapes;
  144. shapeCount = numShapes;
  145. }
  146. #endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API