// CCD via the local separating axis method. This seeks progression // by computing the largest time at which separation is maintained. public static void Compute(out b2TOIOutput output, ref b2TOIInput input) { ++b2_toiCalls; output.state = b2ImpactState.e_unknown; output.t = input.tMax; b2DistanceProxy proxyA = input.proxyA; b2DistanceProxy proxyB = input.proxyB; b2Sweep sweepA = input.sweepA; b2Sweep sweepB = input.sweepB; // Large rotations can make the root finder fail, so we normalize the // sweep angles. sweepA.Normalize(); sweepB.Normalize(); float tMax = input.tMax; float totalRadius = proxyA.Radius + proxyB.Radius; float target = Math.Max(b2Settings.b2_linearSlop, totalRadius - 3.0f * b2Settings.b2_linearSlop); float tolerance = 0.25f * b2Settings.b2_linearSlop; Debug.Assert(target > tolerance); float t1 = 0.0f; int k_maxIterations = 20; // TODO_ERIN b2Settings int iter = 0; // Prepare input for distance query. b2SimplexCache cache = _cache; b2DistanceInput distanceInput; distanceInput.proxyA = input.proxyA; distanceInput.proxyB = input.proxyB; distanceInput.useRadii = false; // The outer loop progressively attempts to compute new separating axes. // This loop terminates when an axis is repeated (no progress is made). while (true) { // Get the distance between shapes. We can also use the results // to get a separating axis. sweepA.GetTransform(out distanceInput.transformA, t1); sweepB.GetTransform(out distanceInput.transformB, t1); b2DistanceOutput distanceOutput; b2Simplex.b2Distance(out distanceOutput, ref cache, ref distanceInput); // If the shapes are overlapped, we give up on continuous collision. if (distanceOutput.distance <= 0.0f) { // Failure! output.state = b2ImpactState.e_overlapped; output.t = 0.0f; break; } if (distanceOutput.distance < target + tolerance) { // Victory! output.state = b2ImpactState.e_touching; output.t = t1; break; } // Initialize the separating axis. b2SeparationFunction fcn = new b2SeparationFunction(); fcn.Initialize(ref cache, proxyA, ref sweepA, proxyB, ref sweepB, t1, ref distanceInput.transformA, ref distanceInput.transformB); #if false // Dump the curve seen by the root finder { int N = 100; float dx = 1.0f / N; float xs[N + 1];
// CCD via the local separating axis method. This seeks progression // by computing the largest time at which separation is maintained. public static void Compute(out b2TOIOutput output, ref b2TOIInput input) { ++b2_toiCalls; output.state = b2ImpactState.e_unknown; output.t = input.tMax; b2DistanceProxy proxyA = input.proxyA; b2DistanceProxy proxyB = input.proxyB; b2Sweep sweepA = input.sweepA; b2Sweep sweepB = input.sweepB; // Large rotations can make the root finder fail, so we normalize the // sweep angles. sweepA.Normalize(); sweepB.Normalize(); float tMax = input.tMax; float totalRadius = proxyA.Radius + proxyB.Radius; float target = Math.Max(b2Settings.b2_linearSlop, totalRadius - 3.0f * b2Settings.b2_linearSlop); float tolerance = 0.25f * b2Settings.b2_linearSlop; Debug.Assert(target > tolerance); float t1 = 0.0f; int k_maxIterations = 20; // TODO_ERIN b2Settings int iter = 0; // Prepare input for distance query. b2SimplexCache cache = _cache; b2DistanceInput distanceInput; distanceInput.proxyA = input.proxyA; distanceInput.proxyB = input.proxyB; distanceInput.useRadii = false; // The outer loop progressively attempts to compute new separating axes. // This loop terminates when an axis is repeated (no progress is made). while (true) { // Get the distance between shapes. We can also use the results // to get a separating axis. sweepA.GetTransform(out distanceInput.transformA, t1); sweepB.GetTransform(out distanceInput.transformB, t1); b2DistanceOutput distanceOutput; b2Simplex.b2Distance(out distanceOutput, ref cache, ref distanceInput); // If the shapes are overlapped, we give up on continuous collision. if (distanceOutput.distance <= 0.0f) { // Failure! output.state = b2ImpactState.e_overlapped; output.t = 0.0f; break; } if (distanceOutput.distance < target + tolerance) { // Victory! output.state = b2ImpactState.e_touching; output.t = t1; break; } // Initialize the separating axis. b2SeparationFunction fcn = new b2SeparationFunction(); fcn.Initialize(ref cache, proxyA, ref sweepA, proxyB, ref sweepB, t1, ref distanceInput.transformA, ref distanceInput.transformB); #if false // Dump the curve seen by the root finder { int N = 100; float dx = 1.0f / N; float xs[N+1];