Joints

A joint in a physics engine is a constraining feature between two bodies. This area has the largest differences between the physics engine both in the joints available and the names used. Not all native joints are available in some plugins.

Playgrounds are available to check out the coding. In the playgrounds the physics' engine used can be changed by selecting which ones to comment out.

See How to Use The Physics' Engines for an overall view of setting up and using the three plugins.

Physical Joint Types

NumberJointNameNotes
Number
1
Joint
Hinge
Name
Hinge
Notes
Single Axis Rotation
Number
2
Joint
Ball and Socket
Name
Ball and Socket
Notes
Multi Axis Rotation
Number
3
Joint
Cone Twist
Name
Cone Twist
Notes
Unrestricted rotation (Twist) on One Axis, Limited Rotation (in Cone) On Others
Number
4
Joint
Wheel
Name
Wheel
Notes
Two Axes Rotation
Number
5
Joint
Slider
Name
Slider
Notes
Single Axis Translation and Rotation
Number
6
Joint
Prismatic
Name
Prismatic
Notes
Single Axis Translation Only
Number
7
Joint
Distance
Name
Distance
Notes
Set Bodies a Fixed Distance Apart
Number
8
Joint
Locked
Name
Locked
Notes
Bodies Act As One Body

Native Joints for Each Physics Engine

The relationship between native joints and physical joints

Cannon.js

Cannon JointPhysical Joint
Cannon Joint
HingeConstraint
Physical Joint
1 Hinge
Cannon Joint
PointToPointConstraint
Physical Joint
2 Ball and Socket
Cannon Joint
DistanceConstraint
Physical Joint
7 Distance
Cannon Joint
Spring
Physical Joint
Not Shown
Cannon Joint
LockConstraint
Physical Joint
8 Locked

Oimo.js

Oimo JointPhysical Joint
Oimo Joint
HingeJoint
Physical Joint
1 Hinge
Oimo Joint
BallAndSocketJoint
Physical Joint
2 Ball and Socket
Oimo Joint
WheelJoint
Physical Joint
4 Wheel
Oimo Joint
SliderJoint
Physical Joint
5 Slider
Oimo Joint
PrismaticJoint
Physical Joint
6 Prismatic
Oimo Joint
DistanceJoint
Physical Joint
7 Distance

Ammo.js

Ammo JointPhysical Joint
Ammo Joint
HingeConstraint
Physical Joint
1 Hinge
Ammo Joint
Point2PointConstraint
Physical Joint
2 Ball and Socket
Ammo Joint
ConeTwistConstraint
Physical Joint
3 Cone Twist
Ammo Joint
SliderConstraint
Physical Joint
5 Slider
Ammo Joint
FixedConstraint
Physical Joint
8 Locked(?)

Babylon.js Joints

The following table lists those joints within Babylon.js and where available their equivalence to each other and their link to the native joints

Babylon.js JointCannon JointOimo JointAmmo JointHelper Class
Babylon.js Joint
HingeJoint
Cannon Joint
HingeConstraint
Oimo Joint
HingJoint
Ammo Joint
HingeConstraint
Helper Class
Yes
Babylon.js Joint
BallAndSocketJoint
Cannon Joint
PointToPointConstraint
Oimo Joint
BallAndSocketJoint
Ammo Joint
Point2PointConstraint
Helper Class
no
Babylon.js Joint
WheelJoint
Cannon Joint
----
Oimo Joint
WheelJoint
Ammo Joint
Point2PointConstraint
Helper Class
Hinge2Joint Only
Babylon.js Joint
SliderJoint
Cannon Joint
----
Oimo Joint
SliderJoint
Ammo Joint
----
Helper Class
No
Babylon.js Joint
PrismaticJoint
Cannon Joint
----
Oimo Joint
PrismaticJoint
Ammo Joint
----
Helper Class
No
Babylon.js Joint
DistanceJoint
Cannon Joint
DistanceConstraint
Oimo Joint
DistanceJoint
Ammo Joint
Point2PointConstraint with Added Constraints
Helper Class
Yes
Babylon.js Joint
LockJoint
Cannon Joint
LockConstraint
Oimo Joint
----
Ammo Joint
----
Helper Class
No
Babylon.js Joint
SpringJoint
Cannon Joint
Spring
Oimo Joint
----
Ammo Joint
----
Helper Class
No

The method to form a joint and connect one body (main) to a second body (connected) is

var joint = new BABYLON.PhysicsJoint(
BABYLON.PhysicsJoint.TYPE_OF_JOINT,
jointData
);
mainImpostor.addJoint(connectedImpostor, joint);

where the jointData object contains the properties for the joint.

Hinge Joint

For a hinge the only component of any force that produces movement is one perpendicular to the axis of the hinge. It is possible however that a large impulse in another direction can produce a reaction between the two bodies that does produce an impulse component in the perpendicular direction.

The jointData object for a hinge contains the following properties

  • mainAxis: Vector3; the axis for the main body.
  • connectedAxis: Vector3; the axis for the connected body, usually the same as the main axis.
  • mainPivot: Vector3; the pivot point for the main body.
  • connectedPivot: vector3; the pivot point for the connected body, the negative of the connected body's position.

A hinge joint can also be created with a helper class

var joint1 = new BABYLON.HingeJoint(jointData);

PhysicsJoint Playground

  • Hinge As A Sphere 1

Helper Class Playground

  • Hinge As A Sphere 2

Since a hinge gives movement about only one axis it would seem to make sense to replace the representation of the hinge with a cylinder. Doing this, reshaping the box and keeping the sphere mesh imposter as a sphere does produce changes.

In this case, for all the physics' engines whatever the direction of impulse set it is applied in a direction perpendicular to the hinge axis.

PhysicsJoint Playground

  • Hinge As A Cylinder 1

Helper Class Playground

  • Hinge As A Cylinder 2

You can, of course, use a cylinder impostor for the cylinder mesh

PhysicsJoint Playground

  • Hinge As A Cylinder 3 (box and cylinder)

Helper Class Playground

  • Hinge As A Cylinder 4 (box and cylinder)

Ball And Socket Joint

For a ball and socket joint a force can produce rotation about all three axes.

The positioning of the connected body is determined by the connected pivot. The jointData object for a ball and socket contains the following properties

  • mainPivot: Vector3; the pivot point for the main body.
  • connectedPivot: vector3; the pivot point for the connected body, the negative of the connected body's position.

PhysicsJoint Playground

  • Ball and Socket

Wheel Joint

For a wheel the a force produces rotation about two axes.

The jointData object for a hinge contains the following properties

  • mainAxis: Vector3; the first axis.
  • connectedAxis: Vector3; the second axis.
  • mainPivot: Vector3; the pivot point for the main body.
  • connectedPivot: vector3; the pivot point for the connected body, the negative of the connected body's position.

Note In the Oimo.js playgrounds changing the contact point of the force will not produce a spin around the axis perpendicular to the sphere's surface.

PhysicsJoint Playground

  • Oimo.js Wheel Joint Example

The PhysicsJoint called Hinge2Joint can be used as an alternative. Note however that there is no helper call WheelJoint and the helper must be

var joint1 = new BABYLON.Hinge2Joint(jointData);

When this helper class is used with Ammo.js it forms a BallAndSocketJoint not a WheelJoint. So a change of contact point can produce a spin around the axis perpendicular to the sphere's surface when using Ammo.js.

Helper Class Playgrounds

  • Oimo.js Hinge2
  • Ammo.js Hinge2

Slider Joint

Currently Oimo.js only. Any component of force in the direction of the slider axis will move the body along this axis. Any component of force perpendicular to the slider axis will rotate the body around the axis.

The jointData object for a slider contains the following properties

  • mainAxis:Vector3, slider and rotational axis
  • collision: Boolean, true if the main and connected bodies react at collision.

PhysicsJoint Playgrounds

  • Oimo.js Slier Example

Prismatic Joint

Currently Oimo.js only. Only the component of force in the direction of the axis will move the body and the movement will be a translation only along this axis.

The jointData object for a slider contains the following properties

  • mainAxis:Vector3, prismatic axis
  • collision: Boolean, true if the main and connected bodies react at collision.

PhysicsJoint Playgrounds

  • Oimo.js Prismatic Joint

Distance Joint

The jointData object for a distance joint contains the following properties

  • maxDistance: number.

PhysicsJoint Playgrounds

  • Distance Joint 1

Helper Class Playgrounds

  • Distance Joint 2

LockJoint

Cannon.js only. The two connected bodies act as one body.

PhysicsJoint Playgrounds

  • Cannon.js Lock Joint Example

Spring

Cannon,js Only. The jointData object for a spring contains the following properties

  • length: number.
  • stiffness: number.
  • damping: number.

PhysicsJoint Playgrounds

  • Cannon.js Spring Joint Example

Motors

A motor requires a target speed (angular velocity) and the maximum force (torque) that can be applied by the motor. It is possible to set a torque that is insufficient for it to reach the target speed. Depending on the shape and mass of the body the torque has to overcome the moment of inertia of the body. A too low value for the torque will make the body struggle and stutter to reach the target speed. Even attempting to simulate a virtual motor in zero gravity with no friction and a zero mass for the axel joint turning a cylinder can make determining an appropriate value for the torque difficult. Since moment of inertia, which determines torque, also depends on the volume of the body it is a good idea to keep linear dimensions around 10 or less though it is probably worth experimenting to get obtain what you need. Adding gravity, friction and further bodies, that the motored body has to move, makes it even more difficult. Sometimes in your project all you will want is for the motor to turn. This can be achieved by just setting the target speed (the motor will be over torqued by default), as in

joint.setMotor(speed);

At other times it will be important to set a value for the torque that limits the motor operation, you can do this with

joint.setMotor(speed, force);

The table below shows the joints that a motor can be added to.

Babylon.js JointCannon MotorOimo MotorAmmo Motor
Babylon.js Joint
BABYLON.PhysicsJoint.HingeJoint
Cannon Motor
Yes
Oimo Motor
Yes
Ammo Motor
Yes
Babylon.js Joint
BABYLON.PhysicsJoint.WheelJoint
Cannon Motor
No
Oimo Motor
Yes
Ammo Motor
No
Babylon.js Joint
BABYLON.PhysicsJoint.Hinge2Joint
Cannon Motor
No
Oimo Motor
Yes
Ammo Motor
No
Babylon.js Joint
BABYLON.PhysicsJoint.SliderJoint
Cannon Motor
No
Oimo Motor
Yes
Ammo Motor
No

To add a motor to one of these joints simply replace PhysicsJoint with MotorEnabledJoint and set the motor on the joint.

var joint = new BABYLON.PhysicsJoint(
BABYLON.PhysicsJoint.TYPE_OF_JOINT,
jointData
);
mainImpostor.addJoint(connectedImpostor, joint);

becomes

var joint = new BABYLON.MotorEnabledJoint(BABYLON.PhysicsJoint.TYPE_OF_JOINT, jointData);
mainImpostor.addJoint(connectedImpostor, joint);
joint.setMotor(target speed, maximum torque)

The helper classes for HingeJoint and Hinge2Joint are already motorised and only setMotor is needed.

Playground Examples

Hinge Motor Speed Only

MotorEnabledJoint Playground

  • Hinge Motor 1

Helper Class Playground

  • Hinge Motor 2

Hinge Motor Speed and Torque (Force)

Different engines use differing scales for the torque and a little trial and error is often necessary to determine the required effect.

  • For Cannon.js try starting with torque values between 1/100 to 1/10 of the total mass value;
  • For Ammo.js try starting with torque values between 1/100 and 1/10 of total mass value;
  • For Oimo.js try starting with torque values about 1 to 10 times the total mass value.

In the hinge motor playgrounds below there are two wheels you can try out different torque values for each wheel to see how they vary. Note that they are in zero gravity, with zero friction and the axel has zero mass. In other situations torque values may need a larger factor than those given above.

MotorEnabledJoint Playground

  • Hinge Motor 3

Helper Class Playground

  • Hinge Motor 4

Wheel (Hinge2) Motor

MotorEnabledJoint Playgrounds

  • Oimo.js Wheel Z Axis
  • Oimo.js Wheel Y Axis
  • Oimo.js Wheel X Axis

Slider Motor

The motor rotates the body around the slider axis.

MotorEnabledJoint Playground

  • Oimo.js Slider X Axis

Further reading