예제 #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,
            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);
        }
예제 #2
0
        internal Manifold Assign(
            VoltWorld world,
            VoltShape shapeA,
            VoltShape shapeB)
        {
            this.world  = world;
            this.ShapeA = shapeA;
            this.ShapeB = shapeB;

            this.Restitution = VoltMath.Sqrt(shapeA.Restitution * shapeB.Restitution);
            this.Friction    = VoltMath.Sqrt(shapeA.Friction * shapeB.Friction);
            this.used        = 0;

            return(this);
        }
예제 #3
0
        /// <summary>
        /// Checks a ray against a circle with a given origin and square radius.
        /// </summary>
        internal static bool CircleRayCast(
            VoltShape shape,
            VoltVector2 shapeOrigin,
            Fix64 sqrRadius,
            ref VoltRayCast ray,
            ref VoltRayResult result)
        {
            VoltVector2 toOrigin = shapeOrigin - ray.origin;

            if (toOrigin.sqrMagnitude < sqrRadius)
            {
                result.SetContained(shape);
                return(true);
            }

            Fix64 slope = VoltVector2.Dot(toOrigin, ray.direction);

            if (slope < Fix64.Zero)
            {
                return(false);
            }

            Fix64 sqrSlope = slope * slope;
            Fix64 d        = sqrRadius + sqrSlope - VoltVector2.Dot(toOrigin, toOrigin);

            if (d < Fix64.Zero)
            {
                return(false);
            }

            Fix64 dist = slope - VoltMath.Sqrt(d);

            if (dist < Fix64.Zero || dist > ray.distance)
            {
                return(false);
            }

            // N.B.: For historical raycasts this normal will be wrong!
            // Must be either transformed back to world or invalidated later.
            VoltVector2 normal = (dist * ray.direction - toOrigin).normalized;

            result.Set(shape, dist, normal);
            return(true);
        }