예제 #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);
        }
예제 #2
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,
            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);
        }
예제 #3
0
        /// <summary>
        /// Creates a new circle shape from a world-space origin.
        /// </summary>
        public VoltCircle CreateCircleWorldSpace(
            VoltVector2 worldSpaceOrigin, Fix64 radius, Fix64 density, Fix64 friction, Fix64 restitution)
        {
            VoltCircle circle = (VoltCircle)this.circlePool.Allocate();

            circle.InitializeFromWorldSpace(
                worldSpaceOrigin,
                radius,
                density,
                friction,
                restitution);
            return(circle);
        }
예제 #4
0
 private static Manifold Circle_Circle(
     VoltWorld world,
     VoltCircle circA,
     VoltCircle circB)
 {
     return
         (TestCircles(
              world,
              circA,
              circB,
              circB.worldSpaceOrigin,
              circB.radius));
 }
예제 #5
0
        /// <summary>
        /// Creates a new circle shape from a world-space origin.
        /// </summary>
        public VoltCircle CreateCircleWorldSpace(
            TSVector2 worldSpaceOrigin,
            FP radius,
            FP?density     = null,
            FP?friction    = null,
            FP?restitution = null)
        {
            VoltCircle circle = (VoltCircle)this.circlePool.Allocate();

            circle.InitializeFromWorldSpace(
                worldSpaceOrigin,
                radius,
                density ?? VoltConfig.DEFAULT_DENSITY,
                friction ?? VoltConfig.DEFAULT_FRICTION,
                restitution ?? VoltConfig.DEFAULT_RESTITUTION);
            return(circle);
        }
예제 #6
0
        /// <summary>
        /// Creates a new circle shape from a world-space origin.
        /// </summary>
        public VoltCircle CreateCircleWorldSpace(
            Vector2 worldSpaceOrigin,
            float radius,
            float density     = VoltConfig.DEFAULT_DENSITY,
            float friction    = VoltConfig.DEFAULT_FRICTION,
            float restitution = VoltConfig.DEFAULT_RESTITUTION)
        {
            VoltCircle circle = (VoltCircle)this.circlePool.Allocate();

            circle.InitializeFromWorldSpace(
                worldSpaceOrigin,
                radius,
                density,
                friction,
                restitution);
            return(circle);
        }
예제 #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);
        }