public override void Step(Settings settings) { settings.pause = 1; base.Step(settings); settings.pause = 0; Sweep sweep1 = new Sweep(); sweep1.C0.Set(0.0f, 20.0f); sweep1.A0 = 0.0f; sweep1.C = sweep1.C0; sweep1.A = sweep1.A0; sweep1.T0 = 0.0f; sweep1.LocalCenter = _body1.GetLocalCenter(); Sweep sweep2 = new Sweep(); sweep2.C0.Set(9.6363468f, 28.050615f); sweep2.A0 = 1.6408679f; sweep2.C = sweep2.C0 + new Vec2(-0.075121880f, 0.27358246f); sweep2.A = sweep2.A0 - 10.434675f; sweep2.T0 = 0.0f; sweep2.LocalCenter = _body2.GetLocalCenter(); float toi = Collision.TimeOfImpact(_shape1, sweep1, _shape2, sweep2); OpenGLDebugDraw.DrawString(5, _textLine, "toi = " + toi.ToString()); _textLine += 15; XForm xf2 = new XForm(); sweep2.GetXForm(out xf2, toi); int vertexCount = _shape2.VertexCount; Vec2[] vertices = new Vec2[Box2DX.Common.Settings.MaxPolygonVertices]; Vec2[] localVertices = _shape2.GetVertices(); for (int i = 0; i < vertexCount; ++i) { vertices[i] = Box2DX.Common.Math.Mul(xf2, localVertices[i]); } _debugDraw.DrawPolygon(vertices, vertexCount, new Color(0.5f, 0.7f, 0.9f)); localVertices = _shape2.GetCoreVertices(); for (int i = 0; i < vertexCount; ++i) { vertices[i] = Box2DX.Common.Math.Mul(xf2, localVertices[i]); } _debugDraw.DrawPolygon(vertices, vertexCount, new Color(0.5f, 0.7f, 0.9f)); }
// This algorithm uses conservative advancement to compute the time of // impact (TOI) of two shapes. // Refs: Bullet, Young Kim /// <summary> /// Compute the time when two shapes begin to touch or touch at a closer distance. /// warning the sweeps must have the same time interval. /// </summary> /// <param name="shape1"></param> /// <param name="sweep1"></param> /// <param name="shape2"></param> /// <param name="sweep2"></param> /// <returns> /// The fraction between [0,1] in which the shapes first touch. /// fraction=0 means the shapes begin touching/overlapped, and fraction=1 means the shapes don't touch. /// </returns> #warning: "check params" public static float TimeOfImpact(Shape shape1, Sweep sweep1, Shape shape2, Sweep sweep2) { float r1 = shape1.GetSweepRadius(); float r2 = shape2.GetSweepRadius(); Box2DXDebug.Assert(sweep1.T0 == sweep2.T0); Box2DXDebug.Assert(1.0f - sweep1.T0 > Common.Settings.FLT_EPSILON); float t0 = sweep1.T0; Vec2 v1 = sweep1.C - sweep1.C0; Vec2 v2 = sweep2.C - sweep2.C0; float omega1 = sweep1.A - sweep1.A0; float omega2 = sweep2.A - sweep2.A0; float alpha = 0.0f; Vec2 p1, p2; int k_maxIterations = 20; // TODO_ERIN b2Settings int iter = 0; Vec2 normal = Vec2.Zero; float distance = 0.0f; float targetDistance = 0.0f; for (; ; ) { float t = (1.0f - alpha) * t0 + alpha; XForm xf1, xf2; sweep1.GetXForm(out xf1, t); sweep2.GetXForm(out xf2, t); // Get the distance between shapes. distance = Collision.Distance(out p1, out p2, shape1, xf1, shape2, xf2); if (iter == 0) { // Compute a reasonable target distance to give some breathing room // for conservative advancement. if (distance > 2.0f * Settings.ToiSlop) { targetDistance = 1.5f * Settings.ToiSlop; } else { targetDistance = Common.Math.Max(0.05f * Settings.ToiSlop, distance - 0.5f * Settings.ToiSlop); } } if (distance - targetDistance < 0.05f * Settings.ToiSlop || iter == k_maxIterations) { break; } normal = p2 - p1; normal.Normalize(); // Compute upper bound on remaining movement. float approachVelocityBound = Vec2.Dot(normal, v1 - v2) + Common.Math.Abs(omega1) * r1 + Common.Math.Abs(omega2) * r2; if (Common.Math.Abs(approachVelocityBound) < Common.Settings.FLT_EPSILON) { alpha = 1.0f; break; } // Get the conservative time increment. Don't advance all the way. float dAlpha = (distance - targetDistance) / approachVelocityBound; //float dt = (distance - 0.5f * Settings.LinearSlop) / approachVelocityBound; float newAlpha = alpha + dAlpha; // The shapes may be moving apart or a safe distance apart. if (newAlpha < 0.0f || 1.0f < newAlpha) { alpha = 1.0f; break; } // Ensure significant advancement. if (newAlpha < (1.0f + 100.0f * Common.Settings.FLT_EPSILON) * alpha) { break; } alpha = newAlpha; ++iter; } return alpha; }
public float ComputeTOI(Sweep sweepA, Sweep sweepB) { Collision.Collision.TOIInput input = new Collision.Collision.TOIInput(); input.ProxyA.Set(_fixtureA.GetShape()); input.ProxyB.Set(_fixtureB.GetShape()); input.SweepA = sweepA; input.SweepB = sweepB; input.Tolerance = Settings.LinearSlop; return Collision.Collision.TimeOfImpact(input); }
public float ComputeTOI(Sweep sweepA, Sweep sweepB) { TOIInput input = new TOIInput(); input.SweepA = sweepA; input.SweepB = sweepB; input.SweepRadiusA = _fixtureA.ComputeSweepRadius(sweepA.LocalCenter); input.SweepRadiusB = _fixtureB.ComputeSweepRadius(sweepB.LocalCenter); input.Tolerance = Common.Settings.LinearSlop; return Collision.Collision.TimeOfImpact(input, _fixtureA.Shape, _fixtureB.Shape); }
public override void Step(Settings settings) { base.Step(settings); Sweep sweepA = new Sweep(); sweepA.C0.Set(0.0f, -0.2f); sweepA.A0 = 0.0f; sweepA.C = sweepA.C0; sweepA.A = sweepA.A0; sweepA.T0 = 0.0f; sweepA.LocalCenter.SetZero(); Sweep sweepB = new Sweep(); sweepB.C0.Set(-0.076157160f, 0.16447277f); sweepB.A0 = -9.4497271f; sweepB.C.Set(-0.25650328f, -0.63657403f); sweepB.A = -9.0383911f; sweepB.T0 = 0.0f; sweepB.LocalCenter.SetZero(); Collision.TOIInput input = new Collision.TOIInput(); input.ProxyA.Set(_shapeA); input.ProxyB.Set(_shapeB); input.SweepA = sweepA; input.SweepB = sweepB; input.Tolerance = Box2DX.Common.Settings.LinearSlop; float toi = Collision.TimeOfImpact(input); OpenGLDebugDraw.DrawString(5, _textLine, string.Format("toi = {0}", toi)); _textLine += 15; #warning "get variables from TOI implementation" int _maxToiIters = 0, _maxToiRootIters = 0; OpenGLDebugDraw.DrawString(5, _textLine, string.Format("max toi iters = {1}, max root iters = {1}", _maxToiIters, _maxToiRootIters)); _textLine += 15; Vec2[] vertices = new Vec2[Box2DX.Common.Settings.MaxPolygonVertices]; Transform transformA; sweepA.GetTransform(out transformA, 0.0f); for (int i = 0; i < _shapeA.VertexCount; ++i) { vertices[i] = Math.Mul(transformA, _shapeA.Vertices[i]); } _debugDraw.DrawPolygon(vertices, _shapeA.VertexCount, new Color(0.9f, 0.9f, 0.9f)); Transform transformB; sweepB.GetTransform(out transformB, 0.0f); for (int i = 0; i < _shapeB.VertexCount; ++i) { vertices[i] = Math.Mul(transformB, _shapeB.Vertices[i]); } _debugDraw.DrawPolygon(vertices, _shapeB.VertexCount, new Color(0.5f, 0.9f, 0.5f)); sweepB.GetTransform(out transformB, toi); for (int i = 0; i < _shapeB.VertexCount; ++i) { vertices[i] = Math.Mul(transformB, _shapeB.Vertices[i]); } _debugDraw.DrawPolygon(vertices, _shapeB.VertexCount, new Color(0.5f, 0.7f, 0.9f)); sweepB.GetTransform(out transformB, 1.0f); for (int i = 0; i < _shapeB.VertexCount; ++i) { vertices[i] = Math.Mul(transformB, _shapeB.Vertices[i]); } _debugDraw.DrawPolygon(vertices, _shapeB.VertexCount, new Color(0.9f, 0.5f, 0.5f)); }