b2EdgeShape.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
  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 "b2EdgeShape.h"
  19. b2EdgeShape::b2EdgeShape(const b2Vec2& v1, const b2Vec2& v2, const b2ShapeDef* def)
  20. : b2Shape(def)
  21. {
  22. b2Assert(def->type == e_edgeShape);
  23. m_type = e_edgeShape;
  24. m_prevEdge = NULL;
  25. m_nextEdge = NULL;
  26. m_v1 = v1;
  27. m_v2 = v2;
  28. m_direction = m_v2 - m_v1;
  29. m_length = m_direction.Normalize();
  30. m_normal.Set(m_direction.y, -m_direction.x);
  31. m_coreV1 = -b2_toiSlop * (m_normal - m_direction) + m_v1;
  32. m_coreV2 = -b2_toiSlop * (m_normal + m_direction) + m_v2;
  33. m_cornerDir1 = m_normal;
  34. m_cornerDir2 = -1.0f * m_normal;
  35. }
  36. void b2EdgeShape::UpdateSweepRadius(const b2Vec2& center)
  37. {
  38. // Update the sweep radius (maximum radius) as measured from
  39. // a local center point.
  40. b2Vec2 d = m_coreV1 - center;
  41. float32 d1 = b2Dot(d,d);
  42. d = m_coreV2 - center;
  43. float32 d2 = b2Dot(d,d);
  44. m_sweepRadius = b2Sqrt(d1 > d2 ? d1 : d2);
  45. }
  46. bool b2EdgeShape::TestPoint(const b2XForm& transform, const b2Vec2& p) const
  47. {
  48. B2_NOT_USED(transform);
  49. B2_NOT_USED(p);
  50. return false;
  51. }
  52. b2SegmentCollide b2EdgeShape::TestSegment(const b2XForm& transform,
  53. float32* lambda,
  54. b2Vec2* normal,
  55. const b2Segment& segment,
  56. float32 maxLambda) const
  57. {
  58. b2Vec2 r = segment.p2 - segment.p1;
  59. b2Vec2 v1 = b2Mul(transform, m_v1);
  60. b2Vec2 d = b2Mul(transform, m_v2) - v1;
  61. b2Vec2 n = b2Cross(d, 1.0f);
  62. const float32 k_slop = 100.0f * B2_FLT_EPSILON;
  63. float32 denom = -b2Dot(r, n);
  64. // Cull back facing collision and ignore parallel segments.
  65. if (denom > k_slop)
  66. {
  67. // Does the segment intersect the infinite line associated with this segment?
  68. b2Vec2 b = segment.p1 - v1;
  69. float32 a = b2Dot(b, n);
  70. if (0.0f <= a && a <= maxLambda * denom)
  71. {
  72. float32 mu2 = -r.x * b.y + r.y * b.x;
  73. // Does the segment intersect this segment?
  74. if (-k_slop * denom <= mu2 && mu2 <= denom * (1.0f + k_slop))
  75. {
  76. a /= denom;
  77. n.Normalize();
  78. *lambda = a;
  79. *normal = n;
  80. return e_hitCollide;
  81. }
  82. }
  83. }
  84. return e_missCollide;
  85. }
  86. void b2EdgeShape::ComputeAABB(b2AABB* aabb, const b2XForm& transform) const
  87. {
  88. b2Vec2 v1 = b2Mul(transform, m_v1);
  89. b2Vec2 v2 = b2Mul(transform, m_v2);
  90. aabb->lowerBound = b2Min(v1, v2);
  91. aabb->upperBound = b2Max(v1, v2);
  92. }
  93. void b2EdgeShape::ComputeSweptAABB(b2AABB* aabb, const b2XForm& transform1, const b2XForm& transform2) const
  94. {
  95. b2Vec2 v1 = b2Mul(transform1, m_v1);
  96. b2Vec2 v2 = b2Mul(transform1, m_v2);
  97. b2Vec2 v3 = b2Mul(transform2, m_v1);
  98. b2Vec2 v4 = b2Mul(transform2, m_v2);
  99. aabb->lowerBound = b2Min(b2Min(b2Min(v1, v2), v3), v4);
  100. aabb->upperBound = b2Max(b2Max(b2Max(v1, v2), v3), v4);
  101. }
  102. void b2EdgeShape::ComputeMass(b2MassData* massData) const
  103. {
  104. massData->mass = 0;
  105. massData->center = m_v1;
  106. // inertia about the local origin
  107. massData->I = 0;
  108. }
  109. b2Vec2 b2EdgeShape::Support(const b2XForm& xf, const b2Vec2& d) const
  110. {
  111. b2Vec2 v1 = b2Mul(xf, m_coreV1);
  112. b2Vec2 v2 = b2Mul(xf, m_coreV2);
  113. return b2Dot(v1, d) > b2Dot(v2, d) ? v1 : v2;
  114. }
  115. void b2EdgeShape::SetPrevEdge(b2EdgeShape* edge, const b2Vec2& core, const b2Vec2& cornerDir, bool convex)
  116. {
  117. m_prevEdge = edge;
  118. m_coreV1 = core;
  119. m_cornerDir1 = cornerDir;
  120. m_cornerConvex1 = convex;
  121. }
  122. void b2EdgeShape::SetNextEdge(b2EdgeShape* edge, const b2Vec2& core, const b2Vec2& cornerDir, bool convex)
  123. {
  124. m_nextEdge = edge;
  125. m_coreV2 = core;
  126. m_cornerDir2 = cornerDir;
  127. m_cornerConvex2 = convex;
  128. }
  129. float32 b2EdgeShape::ComputeSubmergedArea( const b2Vec2& normal,
  130. float32 offset,
  131. const b2XForm& xf,
  132. b2Vec2* c) const
  133. {
  134. //Note that v0 is independant of any details of the specific edge
  135. //We are relying on v0 being consistent between multiple edges of the same body
  136. b2Vec2 v0 = offset * normal;
  137. //b2Vec2 v0 = xf.position + (offset - b2Dot(normal, xf.position)) * normal;
  138. b2Vec2 v1 = b2Mul(xf, m_v1);
  139. b2Vec2 v2 = b2Mul(xf, m_v2);
  140. float32 d1 = b2Dot(normal, v1) - offset;
  141. float32 d2 = b2Dot(normal, v2) - offset;
  142. if(d1>0)
  143. {
  144. if(d2>0)
  145. {
  146. return 0;
  147. }
  148. else
  149. {
  150. v1 = -d2 / (d1 - d2) * v1 + d1 / (d1 - d2) * v2;
  151. }
  152. }
  153. else
  154. {
  155. if(d2>0)
  156. {
  157. v2 = -d2 / (d1 - d2) * v1 + d1 / (d1 - d2) * v2;
  158. }
  159. else
  160. {
  161. //Nothing
  162. }
  163. }
  164. // v0,v1,v2 represents a fully submerged triangle
  165. float32 k_inv3 = 1.0f / 3.0f;
  166. // Area weighted centroid
  167. *c = k_inv3 * (v0 + v1 + v2);
  168. b2Vec2 e1 = v1 - v0;
  169. b2Vec2 e2 = v2 - v0;
  170. return 0.5f * b2Cross(e1, e2);
  171. }