/// <summary> /// Workhorse for circle-circle collisions, compares origin distance /// to the sum of the two circles' radii, returns a Manifold. /// </summary> /// private static Manifold TestCircles( VoltWorld world, VoltCircle shapeA, VoltShape shapeB, Vector2 overrideBCenter, // For testing vertices in circles float overrideBRadius) { Vector2 r = overrideBCenter - shapeA.worldSpaceOrigin; float min = shapeA.radius + overrideBRadius; float distSq = r.sqrMagnitude; if (distSq >= min * min) { return(null); } float dist = Mathf.Sqrt(distSq); float distInv = 1.0f / dist; Vector2 pos = shapeA.worldSpaceOrigin + (0.5f + distInv * (shapeA.radius - min / 2.0f)) * r; // Build the collision Manifold Manifold manifold = world.AllocateManifold().Assign(world, shapeA, shapeB); manifold.AddContact(pos, distInv * r, dist - min); return(manifold); }
/// <summary> /// Workhorse for circle-circle collisions, compares origin distance /// to the sum of the two circles' radii, returns a Manifold. /// </summary> /// private static Manifold TestCircles( VoltWorld world, VoltCircle shapeA, VoltShape shapeB, VoltVector2 overrideBCenter, // For testing vertices in circles Fix64 overrideBRadius) { VoltVector2 r = overrideBCenter - shapeA.worldSpaceOrigin; Fix64 min = shapeA.radius + overrideBRadius; Fix64 distSq = r.sqrMagnitude; if (distSq >= min * min) { return(null); } Fix64 dist = VoltMath.Sqrt(distSq); // 최소값을 지정하여 divide by zero 방지 Fix64 distInv = Fix64.One / VoltMath.Max(dist, min / (Fix64)10); VoltVector2 pos = shapeA.worldSpaceOrigin + (Fix64.One / (Fix64)2 + distInv * (shapeA.radius - min / (Fix64)2)) * r; // Build the collision Manifold Manifold manifold = world.AllocateManifold().Assign(world, shapeA, shapeB); manifold.AddContact(pos, distInv * r, dist - min); return(manifold); }
private static Manifold __Circle_Circle( VoltWorld world, VoltShape sa, VoltShape sb) { return(Circle_Circle(world, (VoltCircle)sa, (VoltCircle)sb)); }
private static Manifold __Polygon_Circle( VoltWorld world, VoltShape sa, VoltShape sb) { return(Circle_Polygon(world, (VoltCircle)sb, (VoltPolygon)sa)); }
private static Manifold Polygon_Polygon( VoltWorld world, VoltPolygon polyA, VoltPolygon polyB) { Axis a1, a2; if (Collision.FindMinSepAxis(polyA, polyB, out a1) == false) { return(null); } if (Collision.FindMinSepAxis(polyB, polyA, out a2) == false) { return(null); } // We will use poly1's axis, so we may need to swap if (a2.Width > a1.Width) { VoltUtil.Swap(ref polyA, ref polyB); VoltUtil.Swap(ref a1, ref a2); } // Build the collision Manifold Manifold manifold = world.AllocateManifold().Assign(world, polyA, polyB); Collision.FindVerts(polyA, polyB, a1.Normal, a1.Width, manifold); return(manifold); }
private static Manifold __Polygon_Polygon( VoltWorld world, VoltShape sa, VoltShape sb) { return(Polygon_Polygon(world, (VoltPolygon)sa, (VoltPolygon)sb)); }
internal static Manifold Dispatch( VoltWorld world, VoltShape sa, VoltShape sb) { Test test = Collision.tests[(int)sa.Type, (int)sb.Type]; return(test(world, sa, sb)); }
private void Reset() { this.ShapeA = null; this.ShapeB = null; this.Restitution = 0.0f; this.Friction = 0.0f; this.ClearContacts(); this.world = null; }
public override VoltShape PrepareShape(VoltWorld world) { Vector2[] vertices = new Vector2[this.points.Length]; for (int i = 0; i < this.points.Length; i++) vertices[i] = this.points[i].position; this.shape = world.CreatePolygonWorldSpace( vertices, this.density); return this.shape; }
private static Manifold Circle_Circle( VoltWorld world, VoltCircle circA, VoltCircle circB) { return (TestCircles( world, circA, circB, circB.worldSpaceOrigin, circB.radius)); }
internal Manifold Assign( VoltWorld world, VoltShape shapeA, VoltShape shapeB) { this.world = world; this.ShapeA = shapeA; this.ShapeB = shapeB; this.Restitution = Mathf.Sqrt(shapeA.Restitution * shapeB.Restitution); this.Friction = Mathf.Sqrt(shapeA.Friction * shapeB.Friction); this.used = 0; return(this); }
private static Manifold Circle_Polygon( VoltWorld world, VoltCircle circ, VoltPolygon poly) { // Get the axis on the polygon closest to the circle's origin float penetration; int index = Collision.FindAxisMaxPenetration( circ.worldSpaceOrigin, circ.radius, poly, out penetration); if (index < 0) { return(null); } Vector2 a, b; poly.GetEdge(index, out a, out b); Axis axis = poly.GetWorldAxis(index); // If the circle is past one of the two vertices, check it like // a circle-circle intersection where the vertex has radius 0 float d = VoltMath.Cross(axis.Normal, circ.worldSpaceOrigin); if (d > VoltMath.Cross(axis.Normal, a)) { return(Collision.TestCircles(world, circ, poly, a, 0.0f)); } if (d < VoltMath.Cross(axis.Normal, b)) { return(Collision.TestCircles(world, circ, poly, b, 0.0f)); } // Build the collision Manifold Manifold manifold = world.AllocateManifold().Assign(world, circ, poly); Vector2 pos = circ.worldSpaceOrigin - (circ.radius + penetration / 2) * axis.Normal; manifold.AddContact(pos, -axis.Normal, penetration); return(manifold); }
public abstract VoltShape PrepareShape(VoltWorld world);
internal void AssignWorld(VoltWorld world) { this.World = world; }
private static Manifold Polygon_Polygon( VoltWorld world, VoltPolygon polyA, VoltPolygon polyB) { Axis a1, a2; if (Collision.FindMinSepAxis(polyA, polyB, out a1) == false) return null; if (Collision.FindMinSepAxis(polyB, polyA, out a2) == false) return null; // We will use poly1's axis, so we may need to swap if (a2.Width > a1.Width) { VoltUtil.Swap(ref polyA, ref polyB); VoltUtil.Swap(ref a1, ref a2); } // Build the collision Manifold Manifold manifold = world.AllocateManifold().Assign(world, polyA, polyB); Collision.FindVerts(polyA, polyB, a1.Normal, a1.Width, manifold); return manifold; }
/// <summary> /// Workhorse for circle-circle collisions, compares origin distance /// to the sum of the two circles' radii, returns a Manifold. /// </summary> /// private static Manifold TestCircles( VoltWorld world, VoltCircle shapeA, VoltShape shapeB, Vector2 overrideBCenter, // For testing vertices in circles float overrideBRadius) { Vector2 r = overrideBCenter - shapeA.worldSpaceOrigin; float min = shapeA.radius + overrideBRadius; float distSq = r.sqrMagnitude; if (distSq >= min * min) return null; float dist = Mathf.Sqrt(distSq); float distInv = 1.0f / dist; Vector2 pos = shapeA.worldSpaceOrigin + (0.5f + distInv * (shapeA.radius - min / 2.0f)) * r; // Build the collision Manifold Manifold manifold = world.AllocateManifold().Assign(world, shapeA, shapeB); manifold.AddContact(pos, distInv * r, dist - min); return manifold; }
private static Manifold __Circle_Circle( VoltWorld world, VoltShape sa, VoltShape sb) { return Circle_Circle(world, (VoltCircle)sa, (VoltCircle)sb); }
private static Manifold Circle_Polygon( VoltWorld world, VoltCircle circ, VoltPolygon poly) { // Get the axis on the polygon closest to the circle's origin float penetration; int index = Collision.FindAxisMaxPenetration( circ.worldSpaceOrigin, circ.radius, poly, out penetration); if (index < 0) return null; Vector2 a, b; poly.GetEdge(index, out a, out b); Axis axis = poly.GetWorldAxis(index); // If the circle is past one of the two vertices, check it like // a circle-circle intersection where the vertex has radius 0 float d = VoltMath.Cross(axis.Normal, circ.worldSpaceOrigin); if (d > VoltMath.Cross(axis.Normal, a)) return Collision.TestCircles(world, circ, poly, a, 0.0f); if (d < VoltMath.Cross(axis.Normal, b)) return Collision.TestCircles(world, circ, poly, b, 0.0f); // Build the collision Manifold Manifold manifold = world.AllocateManifold().Assign(world, circ, poly); Vector2 pos = circ.worldSpaceOrigin - (circ.radius + penetration / 2) * axis.Normal; manifold.AddContact(pos, -axis.Normal, penetration); return manifold; }
private static Manifold __Polygon_Circle( VoltWorld world, VoltShape sa, VoltShape sb) { return Circle_Polygon(world, (VoltCircle)sb, (VoltPolygon)sa); }
internal static Manifold Dispatch( VoltWorld world, VoltShape sa, VoltShape sb) { Test test = Collision.tests[(int)sa.Type, (int)sb.Type]; return test(world, sa, sb); }
private static Manifold __Polygon_Polygon( VoltWorld world, VoltShape sa, VoltShape sb) { return Polygon_Polygon(world, (VoltPolygon)sa, (VoltPolygon)sb); }
void Awake() { VolatileWorld.instance = this; this.World = new VoltWorld(this.historyLength); }
private static Manifold Circle_Circle( VoltWorld world, VoltCircle circA, VoltCircle circB) { return TestCircles( world, circA, circB, circB.worldSpaceOrigin, circB.radius); }