/// <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); }
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); }
/// <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); }