Esempio n. 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);
        }
Esempio n. 2
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);
        }
        /// <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);
        }
Esempio n. 4
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);
        }
Esempio n. 5
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;
        }
Esempio n. 6
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;
        }
Esempio n. 7
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;
        }