Constraints and Joints
Connect physics objects with constraints (Physics V2 replaces joints with PhysicsConstraint):
// Create a hinge constraint (like a door hinge) using Physics V2
// Create a fixed anchor point
const anchor = BABYLON.MeshBuilder.CreateBox("anchor", {size: 0.5}, scene);
anchor.position = new BABYLON.Vector3(0, 5, 0);
const anchorAggregate = new BABYLON.PhysicsAggregate(
anchor, BABYLON.PhysicsShapeType.BOX,
{ mass: 0 }, scene // mass 0 = static
);
// Create a panel to act as a door
const door = BABYLON.MeshBuilder.CreateBox("door", {
width: 0.5, height: 6, depth: 4
}, scene);
door.position = new BABYLON.Vector3(2, 5, 0);
const doorAggregate = new BABYLON.PhysicsAggregate(
door, BABYLON.PhysicsShapeType.BOX,
{ mass: 5, friction: 0.5 }, scene
);
// Create a hinge constraint between anchor and door
const hingeConstraint = new BABYLON.HingeConstraint(
new BABYLON.Vector3(0, 0, 0), // pivot on anchor
new BABYLON.Vector3(-2, 0, 0), // pivot on door
new BABYLON.Vector3(0, 1, 0), // hinge axis on anchor
new BABYLON.Vector3(0, 1, 0), // hinge axis on door
scene
);
anchorAggregate.body.addConstraint(doorAggregate.body, hingeConstraint);Physics V2 constraint types available with Havok:
// Ball-and-socket constraint (allows rotation in all directions)
const ballConstraint = new BABYLON.BallAndSocketConstraint(
new BABYLON.Vector3(0, 0, 0), // pivot on body A
new BABYLON.Vector3(0, 2, 0), // pivot on body B
scene
);
bodyA.addConstraint(bodyB, ballConstraint);
// Distance constraint (maintains fixed distance)
const distConstraint = new BABYLON.DistanceConstraint(
5, // distance to maintain
scene
);
bodyA.addConstraint(bodyB, distConstraint);
// Prismatic constraint (allows movement along one axis)
const prismaticConstraint = new BABYLON.PrismaticConstraint(
new BABYLON.Vector3(0, 0, 0), // pivot on body A
new BABYLON.Vector3(0, 0, 0), // pivot on body B
new BABYLON.Vector3(1, 0, 0), // axis on body A
new BABYLON.Vector3(1, 0, 0), // axis on body B
scene
);
bodyA.addConstraint(bodyB, prismaticConstraint);
// Lock constraint (completely fixes two bodies together)
const lockConstraint = new BABYLON.LockConstraint(
new BABYLON.Vector3(0, 0, 0),
new BABYLON.Vector3(0, 2, 0),
new BABYLON.Vector3(0, 1, 0),
new BABYLON.Vector3(0, 1, 0),
scene
);
bodyA.addConstraint(bodyB, lockConstraint);Create spring-like behavior with Physics V2 constraints:
// Create spring-like behavior using Physics V2 with a 6DoF constraint
// Create anchor point (static)
const springAnchor = BABYLON.MeshBuilder.CreateSphere("anchor", {diameter: 1}, scene);
springAnchor.position.y = 15;
const anchorAgg = new BABYLON.PhysicsAggregate(
springAnchor, BABYLON.PhysicsShapeType.SPHERE,
{ mass: 0 }, scene
);
// Create suspended object (dynamic)
const bob = BABYLON.MeshBuilder.CreateSphere("bob", {diameter: 2}, scene);
bob.position.y = 10;
const bobAgg = new BABYLON.PhysicsAggregate(
bob, BABYLON.PhysicsShapeType.SPHERE,
{ mass: 2, restitution: 0.6 }, scene
);
// Create a 6 degrees of freedom constraint with spring-like limits
const constraint = new BABYLON.Physics6DoFConstraint(
{ pivotA: new BABYLON.Vector3(0, 0, 0), pivotB: new BABYLON.Vector3(0, 5, 0) },
[{ axis: BABYLON.PhysicsConstraintAxis.LINEAR_DISTANCE,
minLimit: 0, maxLimit: 8 }],
scene
);
anchorAgg.body.addConstraint(bobAgg.body, constraint);
// Visualize the spring connection with a line
let springLine = BABYLON.MeshBuilder.CreateLines("springLine", {
points: [springAnchor.position, bob.position],
updatable: true
}, scene);
// Update the line in the render loop
scene.onBeforeRenderObservable.add(() => {
springLine = BABYLON.MeshBuilder.CreateLines("springLine", {
points: [springAnchor.position, bob.position],
instance: springLine
});
});