Implementing Motorized Hinges in Ammo.js
This article explains how to effectively implement motorized hinges
in web-based 3D applications using native ammo.js constraints. You will
learn how to set up a btHingeConstraint, configure its
angular motor parameters, define rotational limits, and dynamically
control the motor’s velocity and impulse to simulate realistic
mechanical joints like doors, robotic arms, or steering mechanisms.
Setting Up the btHingeConstraint
To create a motorized hinge, you must first establish a connection
between two rigid bodies (or one rigid body and a static anchor point)
using the btHingeConstraint. This constraint restricts the
relative movement of the bodies to a single rotational axis.
// Define the pivot points and axes of rotation for both bodies
const pivotInA = new Ammo.btVector3(0, 0, 0);
const pivotInB = new Ammo.btVector3(0, 0, 0);
const axisInA = new Ammo.btVector3(0, 1, 0); // Rotate around Y-axis
const axisInB = new Ammo.btVector3(0, 1, 0);
// Create the hinge constraint
const hinge = new Ammo.btHingeConstraint(
rigidBodyA,
rigidBodyB,
pivotInA,
pivotInB,
axisInA,
axisInB,
false
);
// Add the constraint to the physics world
physicsWorld.addConstraint(hinge, true);Activating and Configuring the Motor
By default, a hinge constraint acts as a free-spinning joint. To motorize it, you must explicitly enable the angular motor and define both its target velocity and the maximum impulse (torque) the motor can exert to reach that speed.
const enableMotor = true;
const targetVelocity = 1.5; // Radians per second
const maxMotorImpulse = 10.0; // Maximum torque applied to achieve target velocity
hinge.enableAngularMotor(enableMotor, targetVelocity, maxMotorImpulse);If the maxMotorImpulse is too low, the motor will
struggle to move heavy objects or resist external forces. If it is too
high, the movement may become jerky or unstable.
Setting Rotational Limits
To prevent the motorized hinge from spinning infinitely, you can
define limits using the setLimit function. This is critical
for objects like doors or swinging joints that should only rotate within
a specific angular range.
const lowLimit = -Math.PI / 4; // -45 degrees in radians
const highLimit = Math.PI / 4; // 45 degrees in radians
const softness = 0.9;
const biasFactor = 0.3;
const relaxationFactor = 1.0;
hinge.setLimit(lowLimit, highLimit, softness, biasFactor, relaxationFactor);When limits are set, the motor will automatically stop applying force once the joint reaches the boundaries of the defined range.
Dynamically Controlling the Motor
You can adjust the motor’s target velocity and maximum force in real-time within your application’s render or physics loop. This allows you to react to user input, such as steering a vehicle or opening/closing a door.
// Function to update the hinge behavior dynamically
function controlHinge(targetSpeed, power) {
// Enable the motor with new parameters
hinge.enableAngularMotor(true, targetSpeed, power);
}To reverse the motor direction, simply pass a negative value for the
target velocity. To disable the motor and let the joint swing freely
again, call hinge.enableAngularMotor(false, 0, 0).