public void RigidBody_ForceOnCenterOfMass() { RigidBody body = new RigidBody(Vector3.Zero); body.Awake = true; body.Mass = 1f; Helpers.AssertBodyAtRest(body); body.addForce(Vector3.UnitZ); body.integrate(1f); Assert.AreEqual(Vector3.Zero, body.AngularMomentum); Assert.AreEqual(Vector3.UnitZ, body.LinearMomentum); Assert.AreEqual(new Vector3(0f, 0f, 1f), body.Position); body.addForce(-Vector3.UnitZ * 2f); body.integrate(1f); Assert.AreEqual(Vector3.Zero, body.AngularMomentum); Assert.AreEqual(-Vector3.UnitZ, body.LinearMomentum); Assert.AreEqual(new Vector3(0f, 0f, 0f), body.Position); body = new RigidBody(Vector3.Zero); body.Awake = true; body.Mass = 1f; Helpers.AssertBodyAtRest(body); body.addForce(-Vector3.UnitZ); body.integrate(10f); Assert.AreEqual(new Vector3(0f, 0f, -1000f), body.Position); Assert.AreEqual(Vector3.Zero, body.AngularMomentum); }
void IntegrateBody(RigidBody rigidBody, float duration, int numIterations) { for (int i = 0; i < numIterations; i++) { rigidBody.integrate(duration); } }
public void RigidBody_WorldMatrix() { RigidBody body = new RigidBody(Vector3.Zero); body.Awake = true; body.Mass = 1f; float angle = (float)Math.PI; Quaternion orientation = Quaternion.CreateFromYawPitchRoll(angle, 0f, 0f); body.Orientation = orientation; body.Position = Vector3.Up; Matrix expectedWorld = new Matrix( -1f, 0f, .00000008742278f, 0f, 0f, 1f, 0f, 0f, -.00000008742278f, 0f, -1f, 0f, 0f, 1f, 0f, 1f ); //integrate once for update body.integrate(1f); Assert.AreEqual(expectedWorld, body.World); int total_iterations = 1000000; for (int i = 1; i <= total_iterations; i++) { body.integrate(1); Assert.AreEqual(expectedWorld, body.World, "Iteration: " + i); } Assert.AreEqual(expectedWorld, body.World); }
public void RigidBody_Sleeping() { RigidBody body = new RigidBody(Vector3.Zero); body.Mass = 1f; // it's allowed to move if it thinks it shoud... //starts out awake Assert.AreEqual(true, body.Awake); Helpers.AssertBodyAtRest(body); // Adding a force, wakes it up body.addForce(Vector3.Up); Assert.AreEqual(true, body.Awake); // putting it to sleep before integration should bypass any movement calcs. body.Awake = false; body.integrate(1); Helpers.AssertBodyAtRest(body); }
public void RigidBody_InfiniteMass() { RigidBody body = new RigidBody(Vector3.Zero); body.InverseMass = 0f; Assert.AreEqual(float.MaxValue, body.Mass, "Mass"); Assert.False(body.HasFiniteMass, "HasFiniteMass"); Vector3 force = Vector3.Up; Helpers.AssertBodyAtRest(body, Vector3.Zero); //add force at center of mass body.addForce(force); body.integrate(1); Helpers.AssertBodyAtRest(body); //Now add force at point other than center of mass Vector3 worldCoord = Vector3.Right; body.addForce(force, worldCoord); body.integrate(1); Helpers.AssertBodyAtRest(body); //Now let's show that infinitely massed objects don't respond to torque application Vector3 torque = Vector3.Right; body.addTorque(torque); body.integrate(1); Helpers.AssertBodyAtRest(body); }
public void RigidBody_InertiaTensor() { RigidBody body = new RigidBody(Vector3.Zero); body.Awake = true; //simulating hollow sphere of mass and length float radius = 2f; float mass = 1f; body.Mass = mass; float sphere_coeff = ((1f / 12f) * mass * radius * radius); Matrix inertiaTensor = new Matrix( sphere_coeff, 0f, 0f, 0f, 0f, sphere_coeff, 0f, 0f, 0f, 0f, sphere_coeff, 0f, 0f, 0f, 0f, 1f ); body.InertiaTensor = inertiaTensor; Assert.AreEqual(Matrix.Identity, body.World, "Initial World"); Assert.AreEqual(inertiaTensor, body.InertiaTensor, "Initial Intertia Tensor"); Assert.AreEqual(Matrix.Invert(inertiaTensor), body.InverseInertiaTensor, "Initial InverseInertiaTensor"); //no bleed off body.LinearDamping = 1f; //adding a force once should set it moving, never to stop again body.addForce(Vector3.UnitZ, body.Position + (new Vector3(-radius, 0f, 0f))); //nothing physically happens until integration time Assert.AreEqual(Vector3.Zero, body.Position, "Intitial Position"); Assert.AreEqual(Vector3.Zero, body.AngularMomentum, "Intial Rotation"); Assert.AreEqual(Quaternion.Identity, body.Orientation, "Intial Orientation"); body.integrate(1f); Assert.AreEqual(Vector3.UnitZ * 1f, body.Position, "Computed Position"); Assert.AreEqual(new Vector3(0f, 2f, 0f), body.AngularMomentum, "Computed Rotation"); Quaternion orientation = new Quaternion(0f, 0.707106769f, 0f, 0.707106769f); Assert.AreEqual(orientation.X, body.Orientation.X); Assert.AreEqual(orientation.Y, body.Orientation.Y); Assert.AreEqual(orientation.Z, body.Orientation.Z); Assert.AreEqual(orientation.W, body.Orientation.W); Assert.AreEqual(orientation, body.Orientation, "Computed Orientation"); }