/// Call this to draw shapes and other debug draw data. public void DrawDebugData() { if (m_debugDraw == null) { return; } Draw.DrawFlags flags = m_debugDraw.GetFlags(); if (flags.HasFlag(Draw.DrawFlags.e_shapeBit)) { foreach (Body b in m_bodyList) { Transform xf = b.GetTransform(); foreach (Fixture f in b.GetFixtureList()) { if (b.IsActive() == false) { DrawShape(f, xf, Color.FromArgb(128, 128, 75)); } else if (b.GetBodyType() == BodyType._staticBody) { DrawShape(f, xf, Color.FromArgb(128, 225, 128)); } else if (b.GetBodyType() == BodyType._kinematicBody) { DrawShape(f, xf, Color.FromArgb(128, 128, 225)); } else if (b.IsAwake() == false) { DrawShape(f, xf, Color.FromArgb(150, 150, 150)); } else { DrawShape(f, xf, Color.FromArgb(225, 175, 175)); } } } } if (flags.HasFlag(Draw.DrawFlags.e_jointBit)) { foreach (Joint j in m_jointList) { DrawJoint(j); } } if (flags.HasFlag(Draw.DrawFlags.e_pairBit)) { Color color = Color.FromArgb(75, 225, 225); foreach (Contact c in m_contactManager.m_contactList) { //Fixture fixtureA = c.FixtureA; //Fixture fixtureB = c.FixtureB; //Vec2 cA = fixtureA.GetAABB().GetCenter(); //Vec2 cB = fixtureB.GetAABB().GetCenter(); //m_debugDraw.DrawSegment(cA, cB, color); } } if (flags.HasFlag(Draw.DrawFlags.e_aabbBit)) { Color color = Color.FromArgb(225, 75, 225); BroadPhase bp = m_contactManager.m_broadPhase; foreach (Body b in m_bodyList) { if (b.IsActive() == false) { continue; } foreach (Fixture f in b.GetFixtureList()) { for (int i = 0; i < f.m_proxies.Count(); ++i) { FixtureProxy proxy = f.m_proxies[i]; AABB aabb = bp.GetFatAABB(proxy.proxyId); Vec2[] vs = new Vec2[4]; vs[0].Set(aabb.lowerBound.X, aabb.lowerBound.Y); vs[1].Set(aabb.upperBound.X, aabb.lowerBound.Y); vs[2].Set(aabb.upperBound.X, aabb.upperBound.Y); vs[3].Set(aabb.lowerBound.X, aabb.upperBound.Y); m_debugDraw.DrawPolygon(vs, 4, color); } } } } if (flags.HasFlag(Draw.DrawFlags.e_centerOfMassBit)) { foreach (Body b in m_bodyList) { Transform xf = b.GetTransform(); xf.p = b.GetWorldCenter(); m_debugDraw.DrawTransform(xf); } } }
public virtual void Step(TestSettings settings) { float timeStep = settings.hz > 0.0f ? 1.0f / settings.hz : 0.0f; if (settings.pause) { if (settings.singleStep) { settings.singleStep = false; } else { timeStep = 0.0f; } m_debugDraw.DrawString("****PAUSED****"); } Draw.DrawFlags flags = 0; flags |= settings.drawShapes ? Draw.DrawFlags.e_shapeBit : 0; flags |= settings.drawJoints ? Draw.DrawFlags.e_jointBit : 0; flags |= settings.drawAABBs ? Draw.DrawFlags.e_aabbBit : 0; flags |= settings.drawCOMs ? Draw.DrawFlags.e_centerOfMassBit : 0; m_debugDraw.SetFlags(flags); m_world.SetAllowSleeping(settings.enableSleep); m_world.SetWarmStarting(settings.enableWarmStarting); m_world.SetContinuousPhysics(settings.enableContinuous); m_world.SetSubStepping(settings.enableSubStepping); m_pointCount = 0; m_world.Step(timeStep, settings.velocityIterations, settings.positionIterations); m_world.DrawDebugData(); if (timeStep > 0.0f) { ++m_stepCount; } if (settings.drawStats) { int bodyCount = m_world.GetBodyCount(); int contactCount = m_world.GetContactCount(); int jointCount = m_world.GetJointCount(); m_debugDraw.DrawString("bodies/contacts/joints = {0}/{1}/{2}", bodyCount, contactCount, jointCount); int proxyCount = m_world.GetProxyCount(); int height = m_world.GetTreeHeight(); int balance = m_world.GetTreeBalance(); float quality = m_world.GetTreeQuality(); m_debugDraw.DrawString("proxies/height/balance/quality = {0}/{1}/{2}/{3}", proxyCount, height, balance, quality); } // Track maximum profile times { Profile p = m_world.GetProfile(); m_maxProfile.step = Math.Max(m_maxProfile.step, p.step); m_maxProfile.collide = Math.Max(m_maxProfile.collide, p.collide); m_maxProfile.solve = Math.Max(m_maxProfile.solve, p.solve); m_maxProfile.solveInit = Math.Max(m_maxProfile.solveInit, p.solveInit); m_maxProfile.solveVelocity = Math.Max(m_maxProfile.solveVelocity, p.solveVelocity); m_maxProfile.solvePosition = Math.Max(m_maxProfile.solvePosition, p.solvePosition); m_maxProfile.solveTOI = Math.Max(m_maxProfile.solveTOI, p.solveTOI); m_maxProfile.broadphase = Math.Max(m_maxProfile.broadphase, p.broadphase); m_totalProfile.step += p.step; m_totalProfile.collide += p.collide; m_totalProfile.solve += p.solve; m_totalProfile.solveInit += p.solveInit; m_totalProfile.solveVelocity += p.solveVelocity; m_totalProfile.solvePosition += p.solvePosition; m_totalProfile.solveTOI += p.solveTOI; m_totalProfile.broadphase += p.broadphase; } if (settings.drawProfile) { Profile p = m_world.GetProfile(); Profile aveProfile = new Profile(); if (m_stepCount > 0) { float scale = 1.0f / m_stepCount; aveProfile.step = scale * m_totalProfile.step; aveProfile.collide = scale * m_totalProfile.collide; aveProfile.solve = scale * m_totalProfile.solve; aveProfile.solveInit = scale * m_totalProfile.solveInit; aveProfile.solveVelocity = scale * m_totalProfile.solveVelocity; aveProfile.solvePosition = scale * m_totalProfile.solvePosition; aveProfile.solveTOI = scale * m_totalProfile.solveTOI; aveProfile.broadphase = scale * m_totalProfile.broadphase; } m_debugDraw.DrawString("step [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.step, aveProfile.step, m_maxProfile.step); m_debugDraw.DrawString("collide [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.collide, aveProfile.collide, m_maxProfile.collide); m_debugDraw.DrawString("solve [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solve, aveProfile.solve, m_maxProfile.solve); m_debugDraw.DrawString("solve init [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveInit, aveProfile.solveInit, m_maxProfile.solveInit); m_debugDraw.DrawString("solve velocity [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveVelocity, aveProfile.solveVelocity, m_maxProfile.solveVelocity); m_debugDraw.DrawString("solve position [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solvePosition, aveProfile.solvePosition, m_maxProfile.solvePosition); m_debugDraw.DrawString("solveTOI [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveTOI, aveProfile.solveTOI, m_maxProfile.solveTOI); m_debugDraw.DrawString("broad-phase [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.broadphase, aveProfile.broadphase, m_maxProfile.broadphase); } if (m_mouseJoint != null) { Vec2 p1 = m_mouseJoint.GetAnchorB(); Vec2 p2 = m_mouseJoint.GetTarget(); Color c = Color.FromArgb(0, 255, 0); m_debugDraw.DrawPoint(p1, 4.0f, c); m_debugDraw.DrawPoint(p2, 4.0f, c); c = Color.FromArgb(204, 204, 204); m_debugDraw.DrawSegment(p1, p2, c); } if (m_bombSpawning) { Color c = Color.FromArgb(0, 0, 255); m_debugDraw.DrawPoint(m_bombSpawnPoint, 4.0f, c); c = Color.FromArgb(200, 200, 200); m_debugDraw.DrawSegment(m_mouseWorld, m_bombSpawnPoint, c); } if (settings.drawContactPoints) { const float k_impulseScale = 0.1f; const float k_axisScale = 0.3f; for (int i = 0; i < m_pointCount; ++i) { ContactPoint point = m_points[i]; if (point.state == PointState._addState) { // Add m_debugDraw.DrawPoint(point.position, 10.0f, Color.FromArgb(75, 242, 75)); } else if (point.state == PointState._persistState) { // Persist m_debugDraw.DrawPoint(point.position, 5.0f, Color.FromArgb(75, 75, 242)); } if (settings.drawContactNormals) { Vec2 p1 = point.position; Vec2 p2 = p1 + k_axisScale * point.normal; m_debugDraw.DrawSegment(p1, p2, Color.FromArgb(242, 242, 242)); } else if (settings.drawContactImpulse) { Vec2 p1 = point.position; Vec2 p2 = p1 + k_impulseScale * point.normalImpulse * point.normal; m_debugDraw.DrawSegment(p1, p2, Color.FromArgb(242, 242, 75)); } if (settings.drawFrictionImpulse) { Vec2 tangent = Utilities.Cross(point.normal, 1.0f); Vec2 p1 = point.position; Vec2 p2 = p1 + k_impulseScale * point.tangentImpulse * tangent; m_debugDraw.DrawSegment(p1, p2, Color.FromArgb(242, 242, 75)); } } } }