Exemple #1
0
        /// <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);
        }
Exemple #3
0
 private static Manifold __Circle_Circle(
     VoltWorld world,
     VoltShape sa,
     VoltShape sb)
 {
     return(Circle_Circle(world, (VoltCircle)sa, (VoltCircle)sb));
 }
Exemple #4
0
 private static Manifold __Polygon_Circle(
     VoltWorld world,
     VoltShape sa,
     VoltShape sb)
 {
     return(Circle_Polygon(world, (VoltCircle)sb, (VoltPolygon)sa));
 }
Exemple #5
0
        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);
        }
Exemple #6
0
 private static Manifold __Polygon_Polygon(
     VoltWorld world,
     VoltShape sa,
     VoltShape sb)
 {
     return(Polygon_Polygon(world, (VoltPolygon)sa, (VoltPolygon)sb));
 }
Exemple #7
0
        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));
        }
Exemple #8
0
        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;
 }
Exemple #10
0
 private static Manifold Circle_Circle(
     VoltWorld world,
     VoltCircle circA,
     VoltCircle circB)
 {
     return
         (TestCircles(
              world,
              circA,
              circB,
              circB.worldSpaceOrigin,
              circB.radius));
 }
Exemple #11
0
        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);
        }
Exemple #12
0
        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);
Exemple #14
0
 internal void AssignWorld(VoltWorld world)
 {
     this.World = world;
 }
Exemple #15
0
        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;
        }
Exemple #16
0
        /// <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;
        }
Exemple #17
0
   private static Manifold __Circle_Circle(
 VoltWorld world,
 VoltShape sa, 
 VoltShape sb)
   {
       return Circle_Circle(world, (VoltCircle)sa, (VoltCircle)sb);
   }
Exemple #18
0
        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;
        }
Exemple #19
0
   private static Manifold __Polygon_Circle(
 VoltWorld world,
 VoltShape sa, 
 VoltShape sb)
   {
       return Circle_Polygon(world, (VoltCircle)sb, (VoltPolygon)sa);
   }
Exemple #20
0
   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);
   }
Exemple #21
0
   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);
 }
Exemple #23
0
   private static Manifold Circle_Circle(
 VoltWorld world,
 VoltCircle circA,
 VoltCircle circB)
   {
       return
       TestCircles(
         world,
         circA,
         circB,
         circB.worldSpaceOrigin,
         circB.radius);
   }