// 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];
Exemple #2
0
		// 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];