/FarseerPhysics-r78100/SourceFiles/Collision/Shapes/LoopShape.cs

# · C# · 179 lines · 97 code · 20 blank · 62 comment · 7 complexity · 4dc96aa71276f6dee2e714778631ceae MD5 · raw file

  1. /*
  2. * Farseer Physics Engine based on Box2D.XNA port:
  3. * Copyright (c) 2010 Ian Qvist
  4. *
  5. * Box2D.XNA port of Box2D:
  6. * Copyright (c) 2009 Brandon Furtwangler, Nathan Furtwangler
  7. *
  8. * Original source Box2D:
  9. * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
  10. *
  11. * This software is provided 'as-is', without any express or implied
  12. * warranty. In no event will the authors be held liable for any damages
  13. * arising from the use of this software.
  14. * Permission is granted to anyone to use this software for any purpose,
  15. * including commercial applications, and to alter it and redistribute it
  16. * freely, subject to the following restrictions:
  17. * 1. The origin of this software must not be misrepresented; you must not
  18. * claim that you wrote the original software. If you use this software
  19. * in a product, an acknowledgment in the product documentation would be
  20. * appreciated but is not required.
  21. * 2. Altered source versions must be plainly marked as such, and must not be
  22. * misrepresented as being the original software.
  23. * 3. This notice may not be removed or altered from any source distribution.
  24. */
  25. using System.Diagnostics;
  26. using FarseerPhysics.Common;
  27. using Microsoft.Xna.Framework;
  28. namespace FarseerPhysics.Collision.Shapes
  29. {
  30. /// <summary>
  31. /// A loop Shape is a free form sequence of line segments that form a circular list.
  32. /// The loop may cross upon itself, but this is not recommended for smooth collision.
  33. /// The loop has double sided collision, so you can use inside and outside collision.
  34. /// Therefore, you may use any winding order.
  35. /// </summary>
  36. public class LoopShape : Shape
  37. {
  38. private static EdgeShape _edgeShape = new EdgeShape();
  39. /// <summary>
  40. /// The vertices. These are not owned/freed by the loop Shape.
  41. /// </summary>
  42. public Vertices Vertices;
  43. private LoopShape()
  44. {
  45. ShapeType = ShapeType.Loop;
  46. Radius = Settings.PolygonRadius;
  47. }
  48. public LoopShape(Vertices vertices)
  49. : this()
  50. {
  51. if (Settings.ConserveMemory)
  52. Vertices = vertices;
  53. else
  54. // Copy vertices.
  55. Vertices = new Vertices(vertices);
  56. }
  57. public override Shape Clone()
  58. {
  59. LoopShape loop = new LoopShape();
  60. loop.Radius = Radius;
  61. loop.Vertices = Vertices;
  62. loop._density = _density;
  63. loop.MassData = MassData;
  64. return loop;
  65. }
  66. public override int ChildCount
  67. {
  68. get { return Vertices.Count; }
  69. }
  70. /// <summary>
  71. /// Get a child edge.
  72. /// </summary>
  73. /// <param name="edge">The edge.</param>
  74. /// <param name="index">The index.</param>
  75. public void GetChildEdge(ref EdgeShape edge, int index)
  76. {
  77. Debug.Assert(2 <= Vertices.Count);
  78. Debug.Assert(0 <= index && index < Vertices.Count);
  79. edge.ShapeType = ShapeType.Edge;
  80. edge.Radius = Radius;
  81. edge.HasVertex0 = true;
  82. edge.HasVertex3 = true;
  83. int i0 = index - 1 >= 0 ? index - 1 : Vertices.Count - 1;
  84. int i1 = index;
  85. int i2 = index + 1 < Vertices.Count ? index + 1 : 0;
  86. int i3 = index + 2;
  87. while (i3 >= Vertices.Count)
  88. {
  89. i3 -= Vertices.Count;
  90. }
  91. edge.Vertex0 = Vertices[i0];
  92. edge.Vertex1 = Vertices[i1];
  93. edge.Vertex2 = Vertices[i2];
  94. edge.Vertex3 = Vertices[i3];
  95. }
  96. /// <summary>
  97. /// Test a point for containment in this shape. This only works for convex shapes.
  98. /// </summary>
  99. /// <param name="transform">The shape world transform.</param>
  100. /// <param name="point">a point in world coordinates.</param>
  101. /// <returns>True if the point is inside the shape</returns>
  102. public override bool TestPoint(ref Transform transform, ref Vector2 point)
  103. {
  104. return false;
  105. }
  106. /// <summary>
  107. /// Cast a ray against a child shape.
  108. /// </summary>
  109. /// <param name="output">The ray-cast results.</param>
  110. /// <param name="input">The ray-cast input parameters.</param>
  111. /// <param name="transform">The transform to be applied to the shape.</param>
  112. /// <param name="childIndex">The child shape index.</param>
  113. /// <returns>True if the ray-cast hits the shape</returns>
  114. public override bool RayCast(out RayCastOutput output, ref RayCastInput input,
  115. ref Transform transform, int childIndex)
  116. {
  117. Debug.Assert(childIndex < Vertices.Count);
  118. int i1 = childIndex;
  119. int i2 = childIndex + 1;
  120. if (i2 == Vertices.Count)
  121. {
  122. i2 = 0;
  123. }
  124. _edgeShape.Vertex1 = Vertices[i1];
  125. _edgeShape.Vertex2 = Vertices[i2];
  126. return _edgeShape.RayCast(out output, ref input, ref transform, 0);
  127. }
  128. /// <summary>
  129. /// Given a transform, compute the associated axis aligned bounding box for a child shape.
  130. /// </summary>
  131. /// <param name="aabb">The aabb results.</param>
  132. /// <param name="transform">The world transform of the shape.</param>
  133. /// <param name="childIndex">The child shape index.</param>
  134. public override void ComputeAABB(out AABB aabb, ref Transform transform, int childIndex)
  135. {
  136. Debug.Assert(childIndex < Vertices.Count);
  137. aabb = new AABB();
  138. int i1 = childIndex;
  139. int i2 = childIndex + 1;
  140. if (i2 == Vertices.Count)
  141. {
  142. i2 = 0;
  143. }
  144. Vector2 v1 = MathUtils.Multiply(ref transform, Vertices[i1]);
  145. Vector2 v2 = MathUtils.Multiply(ref transform, Vertices[i2]);
  146. aabb.LowerBound = Vector2.Min(v1, v2);
  147. aabb.UpperBound = Vector2.Max(v1, v2);
  148. }
  149. /// <summary>
  150. /// Chains have zero mass.
  151. /// </summary>
  152. public override void ComputeProperties()
  153. {
  154. MassData.Mass = 0.0f;
  155. MassData.Center = Vector2.Zero;
  156. MassData.Inertia = 0.0f;
  157. }
  158. }
  159. }