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(); }