nmlorg.physics

Simple physics

physics.js provides an object-management system completely independent from the renderer. Typically, a physical object (nmlorg.physics.Object) will be created at the same time as a naive position object (nmlorg.threed.world.PositionObject, via world.addObject), then the position object's animate callback will tell the physical object to calculate its motion and then copy the physical object's current position to the position object.

  function animateObject(obj, timeStep) {
    obj.compound(timeStep);
    this.setPosition(obj.position[0], obj.position[1], obj.position[2]);
  }

  for (var i = 0; i < 2; i++) {
    var physicalObject = new nmlorg.physics.Object(x, y, z);
    var positionObject = world.addObject(shape, animateObject, physicalObject);
  }

Each physical object maintains its current position in 3D space along with its current velocity (measured in pixels per second) and a list of zero or more forces that apply to the object. The compound call is responsible for first adjusting the object's velocity based on the active forces, and then updating the object's position based on its velocity. Forces may either be indefinite (such as the simplified force of gravity) or pre-set for a fixed duration (such as the force from a rocket thruster with a fixed amount of fuel). [[At present, there is no way to add a force and have it disabled programmatically. To effect that you would need to re-schedule the force before every call to compound with a fixed duration set to the timeStep.]] If a fixed-duration force expires during the current frame (if its remaining duration is less than timeStep), the frame is divided into a subframe lasting until the force expires, then the remaining time left in the frame, with the correct average velocity applied to the position for each subframe. If two forces expire during the current frame (at different times), the frame is divided into [(0, firstExpiration), (firstExpiration, secondExpiration), (secondExpiration, timeStep)]; and so on.

Forces are registered using addForce(xAccel, yAccel, zAccel, optional duration). To roughly simulate Earth gravity (at the scale of 1 meter = 10 pixels), you can call addEarthGravity.

  function animateObject(obj, timeStep) {
    obj.compound(timeStep);
    this.setPosition(obj.position[0], obj.position[1], obj.position[2]);
  }

  for (var i = 0; i < 2; i++) {
    var physicalObject = new nmlorg.physics.Object(x, y, z);
    var positionObject = world.addObject(shape, animateObject, physicalObject);

    physicalObject.addEarthGravity();
  }
Next: Collision detection and handling