예제 #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,
            TSVector2 overrideBCenter, // For testing vertices in circles
            FP overrideBRadius)
        {
            TSVector2 r      = overrideBCenter - shapeA.worldSpaceOrigin;
            FP        min    = shapeA.radius + overrideBRadius;
            FP        distSq = r.sqrMagnitude;

            if (distSq >= min * min)
            {
                return(null);
            }

            FP dist    = TSMath.Sqrt(distSq);
            FP distInv = 1.0f / dist;

            TSVector2 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
        internal Manifold Assign(
            VoltWorld world,
            VoltShape shapeA,
            VoltShape shapeB)
        {
            this.world  = world;
            this.ShapeA = shapeA;
            this.ShapeB = shapeB;

            this.Restitution = TSMath.Sqrt(shapeA.Restitution * shapeB.Restitution);
            this.Friction    = TSMath.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,
            TSVector2 shapeOrigin,
            FP sqrRadius,
            ref VoltRayCast ray,
            ref VoltRayResult result)
        {
            TSVector2 toOrigin = shapeOrigin - ray.origin;

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

            FP slope = TSVector2.Dot(toOrigin, ray.direction);

            if (slope < 0)
            {
                return(false);
            }

            FP sqrSlope = slope * slope;
            FP d        = sqrRadius + sqrSlope - TSVector2.Dot(toOrigin, toOrigin);

            if (d < 0)
            {
                return(false);
            }

            FP dist = slope - TSMath.Sqrt(d);

            if (dist < 0 || 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.
            TSVector2 normal = (dist * ray.direction - toOrigin).normalized;

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