public override void step(TestbedSettings settings) { lock (_stepLock) { base.step(settings); shape.set(m_points, m_count); addTextLine("Press g to generate a new random convex hull"); getDebugDraw().drawPolygon(shape.m_vertices, shape.m_count, color); for (int i = 0; i < m_count; ++i) { getDebugDraw().drawPoint(m_points[i], 2.0f, color2); getDebugDraw().drawString(m_points[i].add(new Vec2(0.05f, 0.05f)), i + "", Color4f.WHITE); } Debug.Assert(shape.validate()); if (m_auto) { generate(); } } }
public override void step(TestbedSettings settings) { base.step(settings); float hz = settings.getSetting(TestbedSettings.Hz).value; if (hz > 0) { m_time += 1/hz; } m_joint.setMotorSpeed(0.05f*MathUtils.cos(m_time)*MathUtils.PI); }
public override void step(TestbedSettings settings) { float hz = settings.getSetting(TestbedSettings.Hz).value; if (m_go && hz > 0.0f) { m_time += 1.0f/hz; } linearOffset.x = 6.0f*MathUtils.sin(2.0f*m_time); linearOffset.y = 8.0f + 4.0f*MathUtils.sin(1.0f*m_time); float angularOffset = 4.0f*m_time; m_joint.setLinearOffset(linearOffset); m_joint.setAngularOffset(angularOffset); getDebugDraw().drawPoint(linearOffset, 4.0f, color); base.step(settings); addTextLine("Keys: (s) pause"); }
public override void step(TestbedSettings settings) { base.step(settings); addTextLine("Keys: (f) toggle friction, (m) toggle motor"); float torque = m_joint1.getMotorTorque(1); addTextLine(string.Format("Friction: {0}, Motor Force = {1:F0}, ", m_joint2.isMotorEnabled(), torque) .ToString()); }
public override void step(TestbedSettings settings) { base.step(settings); float ratio, value; ratio = m_joint4.getRatio(); value = m_joint1.getJointAngle() + ratio*m_joint2.getJointAngle(); addTextLine("theta1 + " + ratio + " * theta2 = " + value); ratio = m_joint5.getRatio(); value = m_joint2.getJointAngle() + ratio*m_joint3.getJointTranslation(); addTextLine("theta2 + " + ratio + " * delta = " + value); }
public override void step(TestbedSettings settings) { base.step(settings); addTextLine("Use 'wasd' to move, 'e' and 's' drift."); if (getModel().getKeys()['w']) { Vec2 f = m_body.getWorldVector(new Vec2(0.0f, -30.0f)); Vec2 p = m_body.getWorldPoint(m_body.getLocalCenter().add(new Vec2(0.0f, 2.0f))); m_body.applyForce(f, p); } else if (getModel().getKeys()['q']) { Vec2 f = m_body.getWorldVector(new Vec2(0.0f, -30.0f)); Vec2 p = m_body.getWorldPoint(m_body.getLocalCenter().add(new Vec2(-.2f, 0f))); m_body.applyForce(f, p); } else if (getModel().getKeys()['e']) { Vec2 f = m_body.getWorldVector(new Vec2(0.0f, -30.0f)); Vec2 p = m_body.getWorldPoint(m_body.getLocalCenter().add(new Vec2(.2f, 0f))); m_body.applyForce(f, p); } else if (getModel().getKeys()['s']) { Vec2 f = m_body.getWorldVector(new Vec2(0.0f, 30.0f)); Vec2 p = m_body.getWorldCenter(); m_body.applyForce(f, p); } if (getModel().getKeys()['a']) { m_body.applyTorque(20.0f); } if (getModel().getKeys()['d']) { m_body.applyTorque(-20.0f); } }
public override void step(TestbedSettings settings) { // TODO Auto-generated method stub base.step(settings); // Traverse the contact results. Apply a force on shapes // that overlap the sensor. for (int i = 0; i < _e_count; ++i) { if (m_touching[i].tf == false) { continue; } Body body = m_bodies[i]; Body ground = m_sensor.getBody(); CircleShape circle = (CircleShape) m_sensor.getShape(); Vec2 center = ground.getWorldPoint(circle.m_p); Vec2 position = body.getPosition(); Vec2 d = center.sub(position); if (d.lengthSquared() < Settings.EPSILON*Settings.EPSILON) { continue; } d.normalize(); d.mulLocal(100f); Vec2 F = d; body.applyForce(F, position); } }
public override void step(TestbedSettings settings) { base.step(settings); addTextLine("Limits " + (m_joint.isLimitEnabled() ? "on" : "off") + ", Motor " + (m_joint.isMotorEnabled() ? "on " : "off ") + (isLeft ? "left" : "right")); addTextLine("Keys: (l) limits, (m) motor, (a) left, (d) right"); }
public override void step(TestbedSettings settings) { base.step(settings); addTextLine("Keys: left = a, brake = s, right = d, toggle motor = m"); }
public override void step(TestbedSettings settings) { bool advanceRay = settings.pause == false || settings.singleStep; base.step(settings); addTextLine("Press 1-6 to drop stuff, m to change the mode"); addTextLine("Polygon 1 is filtered"); addTextLine("Mode = " + m_mode); float L = 11.0f; point1.set(0.0f, 10.0f); d.set(L*MathUtils.cos(m_angle), L*MathUtils.sin(m_angle)); point2.set(point1); point2.addLocal(d); if (m_mode == Mode.e_closest) { ccallback.init(); getWorld().raycast(ccallback, point1, point2); if (ccallback.m_hit) { getDebugDraw().drawPoint(ccallback.m_point, 5.0f, new Color4f(0.4f, 0.9f, 0.4f)); getDebugDraw().drawSegment(point1, ccallback.m_point, new Color4f(0.8f, 0.8f, 0.8f)); pooledHead.set(ccallback.m_normal); pooledHead.mulLocal(.5f); pooledHead.addLocal(ccallback.m_point); getDebugDraw().drawSegment(ccallback.m_point, pooledHead, new Color4f(0.9f, 0.9f, 0.4f)); } else { getDebugDraw().drawSegment(point1, point2, new Color4f(0.8f, 0.8f, 0.8f)); } } else if (m_mode == Mode.e_any) { acallback.init(); getWorld().raycast(acallback, point1, point2); if (acallback.m_hit) { getDebugDraw().drawPoint(acallback.m_point, 5.0f, new Color4f(0.4f, 0.9f, 0.4f)); getDebugDraw().drawSegment(point1, acallback.m_point, new Color4f(0.8f, 0.8f, 0.8f)); pooledHead.set(acallback.m_normal); pooledHead.mulLocal(.5f); pooledHead.addLocal(acallback.m_point); getDebugDraw().drawSegment(acallback.m_point, pooledHead, new Color4f(0.9f, 0.9f, 0.4f)); } else { getDebugDraw().drawSegment(point1, point2, new Color4f(0.8f, 0.8f, 0.8f)); } } else if (m_mode == Mode.e_multiple) { mcallback.init(); getWorld().raycast(mcallback, point1, point2); getDebugDraw().drawSegment(point1, point2, new Color4f(0.8f, 0.8f, 0.8f)); for (int i = 0; i < mcallback.m_count; ++i) { Vec2 p = mcallback.m_points[i]; Vec2 n = mcallback.m_normals[i]; getDebugDraw().drawPoint(p, 5.0f, new Color4f(0.4f, 0.9f, 0.4f)); getDebugDraw().drawSegment(point1, p, new Color4f(0.8f, 0.8f, 0.8f)); pooledHead.set(n); pooledHead.mulLocal(.5f); pooledHead.addLocal(p); getDebugDraw().drawSegment(p, pooledHead, new Color4f(0.9f, 0.9f, 0.4f)); } } if (advanceRay) { m_angle += 0.25f*MathUtils.PI/180.0f; } }
public override void step(TestbedSettings settings) { base.step(settings); addTextLine("Press: (c) create a shape, (d) destroy a shape."); }
public override void step(TestbedSettings settings) { base.step(settings); addTextLine("This demonstrates a soft distance joint."); addTextLine("Press: (b) to delete a body, (j) to delete a joint"); }
public override void step(TestbedSettings settings) { if (nextShape != null) { m_body.destroyFixture(currFixture); currFixture = m_body.createFixture(nextShape, 1f); nextShape = null; } // if (stepCount == 12){ // stepCount += 0; // } what is this? base.step(settings); if (Distance.GJK_CALLS > 0) { addTextLine(string.Format("gjk calls = {0}, ave gjk iters = {1:F1}, max gjk iters = {2}", Distance.GJK_CALLS, Distance.GJK_ITERS*(1f/Distance.GJK_CALLS), Distance.GJK_MAX_ITERS)); } if (TimeOfImpact.toiCalls > 0) { int toiCalls = TimeOfImpact.toiCalls; int toiIters = TimeOfImpact.toiIters; int toiMaxIters = TimeOfImpact.toiMaxIters; int toiRootIters = TimeOfImpact.toiRootIters; int toiMaxRootIters = TimeOfImpact.toiMaxRootIters; addTextLine(string.Format("toi calls = {0}, ave toi iters = %3.1f, max toi iters = {2}", toiCalls, toiIters*1f/toiCalls, toiMaxIters)); addTextLine(string.Format("ave toi root iters = {0:F1}, max toi root iters = {1}", toiRootIters *(1f/toiCalls), toiMaxRootIters)); } addTextLine("Press 'c' to change launch shape"); if (getStepCount()%60 == 0) { launch(); } }
public override void step(TestbedSettings settings) { base.step(settings); float ratio = m_joint1.getRatio(); float L = m_joint1.getLength1() + ratio*m_joint1.getLength2(); addTextLine("L1 + " + ratio + " * L2 = " + L); if (L >= 36) { addTextLine("Pulley is taught"); } }
public override void step(TestbedSettings settings) { base.step(settings); if (Distance.GJK_CALLS > 0) { addTextLine(String.Format("gjk calls = {0}, ave gjk iters = {1:F1}, max gjk iters = {2}", Distance.GJK_CALLS, Distance.GJK_ITERS*1.0/(Distance.GJK_CALLS), Distance.GJK_MAX_ITERS)); } if (TimeOfImpact.toiCalls > 0) { addTextLine(String.Format("toi calls = {0}, ave toi iters = {1:F1}, max toi iters = {2}", TimeOfImpact.toiCalls, TimeOfImpact.toiIters*1f/(TimeOfImpact.toiCalls), TimeOfImpact.toiMaxRootIters)); addTextLine(String.Format("ave toi root iters = {0:F1}, max toi root iters = {1}", TimeOfImpact.toiRootIters*1f/(TimeOfImpact.toiCalls), TimeOfImpact.toiMaxRootIters.ToString())); } if (getStepCount()%60 == 0) { launch(); } }
public override void step(TestbedSettings settings) { // TODO Auto-generated method stub base.step(settings); addTextLine("Press 's' to stop, and '1' - '5' to change speeds"); }
public override void step(TestbedSettings settings) { base.step(settings); addTextLine("Press ',' to launch bullet."); }
public override void step(TestbedSettings settings) { base.step(settings); addTextLine("Keys: (L) liquid, (E) elastic, (S) spring"); addTextLine("(F) rigid, (W) wall, (V) viscous, (T) tensile"); addTextLine("(Z) erase, (X) move"); }
public override void step(TestbedSettings settings) { base.step(settings); Vec2 p = circle.getTransform().p; Vec2 v = circle.getLinearVelocity(); if ((p.x < -10.0f && v.x < 0.0f) || (p.x > 10.0f && v.x > 0.0f)) { v.x = -v.x; circle.setLinearVelocity(v); } int[] flagsBuffer = m_world.getParticleFlagsBuffer(); for (int i = 0; i < m_world.getParticleCount(); i++) { flagsBuffer[i] = flags; } addTextLine("'a' Clear"); addTextLine("'e' Elastic " + ((flags & ParticleType.b2_elasticParticle) != 0)); addTextLine("'q' Powder " + ((flags & ParticleType.b2_powderParticle) != 0)); addTextLine("'t' Tensile " + ((flags & ParticleType.b2_tensileParticle) != 0)); addTextLine("'v' Viscous " + ((flags & ParticleType.b2_viscousParticle) != 0)); }
public override void step(TestbedSettings settings) { base.step(settings); addTextLine("Keys: (d) dynamic, (s) static, (k) kinematic"); // Drive the kinematic body. if (m_platform.getType() == BodyType.KINEMATIC) { Vec2 p = m_platform.getTransform().p; Vec2 v = m_platform.getLinearVelocity(); if ((p.x < -10.0f && v.x < 0.0f) || (p.x > 10.0f && v.x > 0.0f)) { v.x = -v.x; m_platform.setLinearVelocity(v); } } }
public override void step(TestbedSettings settings) { bool advanceRay = settings.pause == false || settings.singleStep; base.step(settings); addTextLine("Press 1-5 to drop stuff"); float L = 25.0f; Vec2 point1 = new Vec2(0.0f, 10.0f); Vec2 d = new Vec2(L*MathUtils.cos(m_angle), -L*MathUtils.abs(MathUtils.sin(m_angle))); Vec2 point2 = point1.add(d); callback.m_fixture = null; getWorld().raycast(callback, point1, point2); if (callback.m_fixture != null) { getDebugDraw().drawPoint(callback.m_point, 5.0f, new Color4f(0.4f, 0.9f, 0.4f)); getDebugDraw().drawSegment(point1, callback.m_point, new Color4f(0.8f, 0.8f, 0.8f)); callback.m_normal.mul(.5f); callback.m_normal.addLocal(callback.m_point); Vec2 head = callback.m_normal; getDebugDraw().drawSegment(callback.m_point, head, new Color4f(0.9f, 0.9f, 0.4f)); } else { getDebugDraw().drawSegment(point1, point2, new Color4f(0.8f, 0.8f, 0.8f)); } if (advanceRay) { m_angle += 0.25f*MathUtils.PI/180.0f; } }
public override void step(TestbedSettings settings) { base.step(settings); input.proxyA.set(m_polygonA, 0); input.proxyB.set(m_polygonB, 0); input.transformA.set(m_transformA); input.transformB.set(m_transformB); input.useRadii = true; cache.count = 0; getWorld().getPool().getDistance().distance(output, cache, input); addTextLine("distance = " + output.distance); addTextLine("iterations = " + output.iterations); { for (int i = 0; i < m_polygonA.m_count; ++i) { Transform.mulToOutUnsafe(m_transformA, m_polygonA.m_vertices[i], ref v[i]); } getDebugDraw().drawPolygon(v, m_polygonA.m_count, color); for (int i = 0; i < m_polygonB.m_count; ++i) { Transform.mulToOutUnsafe(m_transformB, m_polygonB.m_vertices[i], ref v[i]); } getDebugDraw().drawPolygon(v, m_polygonB.m_count, color); } Vec2 x1 = output.pointA; Vec2 x2 = output.pointB; getDebugDraw().drawPoint(x1, 4.0f, c1); getDebugDraw().drawPoint(x2, 4.0f, c2); }
public override void step(TestbedSettings settings) { base.step(settings); for (Body b = getWorld().getBodyList(); b != null; b = b.getNext()) { if (b.getType() != BodyType.DYNAMIC) { continue; } Vec2 p = b.getPosition(); if (p.x <= -10.0f || 10.0f <= p.x || p.y <= 0.0f || 20.0f <= p.y) { p.x += 0.0f; } } addTextLine("Press 'c' to create a circle"); }
public override void step(TestbedSettings settings) { base.step(settings); // We are going to destroy some bodies according to contact // points. We must buffer the bodies that should be destroyed // because they may belong to multiple contact points. HashSet<Body> nuke = new HashSet<Body>(); // Traverse the contact results. Destroy bodies that // are touching heavier bodies. for (int i = 0; i < getPointCount(); ++i) { ContactPoint point = points[i]; Body body1 = point.fixtureA.getBody(); Body body2 = point.fixtureB.getBody(); float mass1 = body1.getMass(); float mass2 = body2.getMass(); if (mass1 > 0.0f && mass2 > 0.0f) { if (mass2 > mass1) { nuke.Add(body1); } else { nuke.Add(body2); } } } // Sort the nuke array to group duplicates. // Arrays.sort(nuke); // Destroy the bodies, skipping duplicates. foreach (Body b in nuke) { if (b != getBomb()) { getWorld().destroyBody(b); } } }
public override void step(TestbedSettings settings) { base.step(settings); addTextLine("Keys: (l) limits, (m) motors, (s) speed"); float force = m_joint.getMotorForce(1); addTextLine("Motor Force = " + force); }
public virtual void step(TestbedSettings settings) { float hz = settings.getSetting(TestbedSettings.Hz).value; float timeStep = hz > 0f ? 1f/hz : 0; if (settings.singleStep && !settings.pause) { settings.pause = true; } DebugDraw debugDraw = model.getDebugDraw(); m_textLine = 20; if (title != null) { debugDraw.drawString(camera.getTransform().getExtents().x, 15, title, Color4f.WHITE); m_textLine += TEXT_LINE_SPACE; } if (settings.pause) { if (settings.singleStep) { settings.singleStep = false; } else { timeStep = 0; } debugDraw.drawString(5, m_textLine, "****PAUSED****", Color4f.WHITE); m_textLine += TEXT_LINE_SPACE; } DebugDrawFlags flags = 0; flags |= settings.getSetting(TestbedSettings.DrawShapes).enabled ? DebugDrawFlags.Shapes : 0; flags |= settings.getSetting(TestbedSettings.DrawJoints).enabled ? DebugDrawFlags.Joints : 0; flags |= settings.getSetting(TestbedSettings.DrawAABBs).enabled ? DebugDrawFlags.AABB : 0; flags |= settings.getSetting(TestbedSettings.DrawCOMs).enabled ? DebugDrawFlags.CenterOfMass : 0; flags |= settings.getSetting(TestbedSettings.DrawTree).enabled ? DebugDrawFlags.DynamicTree : 0; flags |= settings.getSetting(TestbedSettings.DrawWireframe).enabled ? DebugDrawFlags.Wireframe : 0; debugDraw.setFlags(flags); m_world.setAllowSleep(settings.getSetting(TestbedSettings.AllowSleep).enabled); m_world.setWarmStarting(settings.getSetting(TestbedSettings.WarmStarting).enabled); m_world.setSubStepping(settings.getSetting(TestbedSettings.SubStepping).enabled); m_world.setContinuousPhysics(settings.getSetting(TestbedSettings.ContinuousCollision).enabled); pointCount = 0; m_world.step(timeStep, settings.getSetting(TestbedSettings.VelocityIterations).value, settings.getSetting(TestbedSettings.PositionIterations).value); m_world.drawDebugData(); if (timeStep > 0f) { ++stepCount; } debugDraw.drawString(5, m_textLine, "Engine Info", color4); m_textLine += TEXT_LINE_SPACE; debugDraw.drawString(5, m_textLine, "Framerate: " + (int) model.getCalculatedFps(), Color4f.WHITE); m_textLine += TEXT_LINE_SPACE; if (settings.getSetting(TestbedSettings.DrawStats).enabled) { int particleCount = m_world.getParticleCount(); int groupCount = m_world.getParticleGroupCount(); debugDraw.drawString( 5, m_textLine, "bodies/contacts/joints/proxies/particles/groups = " + m_world.getBodyCount() + "/" + m_world.getContactCount() + "/" + m_world.getJointCount() + "/" + m_world.getProxyCount() + "/" + particleCount + "/" + groupCount, Color4f.WHITE); m_textLine += TEXT_LINE_SPACE; debugDraw.drawString(5, m_textLine, "World mouse position: " + mouseWorld.ToString(), Color4f.WHITE); m_textLine += TEXT_LINE_SPACE; statsList.Clear(); Dynamics.Profile profile = getWorld().getProfile(); profile.toDebugStrings(statsList); foreach (string s in statsList) { debugDraw.drawString(5, m_textLine, s, Color4f.WHITE); m_textLine += TEXT_LINE_SPACE; } m_textLine += TEXT_SECTION_SPACE; } if (settings.getSetting(TestbedSettings.DrawHelp).enabled) { debugDraw.drawString(5, m_textLine, "Help", color4); m_textLine += TEXT_LINE_SPACE; List<string> help = model.getImplSpecificHelp(); foreach (string s in help) { debugDraw.drawString(5, m_textLine, s, Color4f.WHITE); m_textLine += TEXT_LINE_SPACE; } m_textLine += TEXT_SECTION_SPACE; } if (textList.Count != 0) { debugDraw.drawString(5, m_textLine, "Test Info", color4); m_textLine += TEXT_LINE_SPACE; foreach (string s in textList) { debugDraw.drawString(5, m_textLine, s, Color4f.WHITE); m_textLine += TEXT_LINE_SPACE; } textList.Clear(); } if (mouseTracing && mouseJoint == null) { float delay = 0.1f; acceleration.x = 2/delay*(1/delay*(mouseWorld.x - mouseTracerPosition.x) - mouseTracerVelocity.x); acceleration.y = 2/delay*(1/delay*(mouseWorld.y - mouseTracerPosition.y) - mouseTracerVelocity.y); mouseTracerVelocity.x += timeStep*acceleration.x; mouseTracerVelocity.y += timeStep*acceleration.y; mouseTracerPosition.x += timeStep*mouseTracerVelocity.x; mouseTracerPosition.y += timeStep*mouseTracerVelocity.y; pshape.m_p.set(mouseTracerPosition); pshape.m_radius = 2; pcallback.init(m_world, pshape, mouseTracerVelocity); pshape.computeAABB(paabb, identity, 0); m_world.queryAABB(pcallback, paabb); } if (mouseJoint != null) { mouseJoint.getAnchorB(ref p1); Vec2 p2 = mouseJoint.getTarget(); debugDraw.drawSegment(p1, p2, mouseColor); } if (bombSpawning) { debugDraw.drawSegment(bombSpawnPoint, bombMousePoint, Color4f.WHITE); } if (settings.getSetting(TestbedSettings.DrawContactPoints).enabled) { float k_impulseScale = 0.1f; float axisScale = 0.3f; for (int i = 0; i < pointCount; i++) { ContactPoint point = points[i]; if (point.state == Collision.Collision.PointState.ADD_STATE) { debugDraw.drawPoint(point.position, 10f, color1); } else if (point.state == Collision.Collision.PointState.PERSIST_STATE) { debugDraw.drawPoint(point.position, 5f, color2); } if (settings.getSetting(TestbedSettings.DrawContactNormals).enabled) { p1.set(point.position); p2.set(point.normal); p2.mulLocal(axisScale); p2.addLocal(p1); debugDraw.drawSegment(p1, p2, color3); } else if (settings.getSetting(TestbedSettings.DrawContactImpulses).enabled) { p1.set(point.position); p2.set(point.normal); p2.mulLocal(k_impulseScale); p2.mulLocal(point.normalImpulse); p2.addLocal(p1); debugDraw.drawSegment(p1, p2, color5); } if (settings.getSetting(TestbedSettings.DrawFrictionImpulses).enabled) { Vec2.crossToOutUnsafe(point.normal, 1, ref tangent); p1.set(point.position); p2.set(tangent); p2.mulLocal(k_impulseScale); p2.mulLocal(point.tangentImpulse); p2.addLocal(p1); debugDraw.drawSegment(p1, p2, color5); } } } }
/** * @see org.jbox2d.testbed.framework.TestbedTest#step(org.jbox2d.testbed.framework.TestbedSettings) */ public override void step(TestbedSettings settings) { base.step(settings); PolyShapesCallback callback = new PolyShapesCallback(getWorld().getPool()); callback.m_circle.m_radius = 2.0f; callback.m_circle.m_p.set(0.0f, 2.1f); callback.m_transform.setIdentity(); callback.debugDraw = getDebugDraw(); AABB aabb = new AABB(); callback.m_circle.computeAABB(aabb, callback.m_transform, 0); getWorld().queryAABB(callback, aabb); Color4f color = new Color4f(0.4f, 0.7f, 0.8f); getDebugDraw().drawCircle(callback.m_circle.m_p, callback.m_circle.m_radius, color); addTextLine("Press 1-5 to drop stuff"); addTextLine("Press 'a' to (de)activate some bodies"); addTextLine("Press 'd' to destroy a body"); addTextLine("Up to 30 bodies in the target circle are highlighted"); }
public override void step(TestbedSettings settings) { Vec2 v = m_character.getLinearVelocity(); v.x = -5f; base.step(settings); addTextLine("This tests various character collision shapes"); addTextLine("Limitation: square and hexagon can snag on aligned boxes."); addTextLine("Feature: edge chains have smooth collision inside and out."); }
public override void step(TestbedSettings settings) { base.step(settings); if (m_break) { Break(); m_broke = true; m_break = false; } // Cache velocities to improve movement on breakage. if (m_broke == false) { m_velocity.set(m_body1.getLinearVelocity()); m_angularVelocity = m_body1.getAngularVelocity(); } }
public override void step(TestbedSettings settings) { lock (_stepLock) { base.step(settings); addTextLine("Keys: left = a, brake = s, right = d, hz down = q, hz up = e"); addTextLine("frequency = " + m_hz + " hz, damping ratio = " + m_zeta); getCamera().setCamera(m_car.getPosition()); } }