Spherical, Revolute, and Prismatic Joint
Learn how to create spherical, revolute, and prismatic joints between objects in Three.js.
Connecting objects with a spherical joint
A spherical joint allows two objects to freely move around one another while keeping the same distance between these objects. This can be used for sphere-joint.js
in the playground below):
Example: Spherical joint
Click the “Run” button to execute the above example:
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') // const CopyWebpackPlugin = require('copy-webpack-plugin') const fs = require('fs').promises // we should search through the directories in examples, and use // the name from the files to generate the HtmlWebpackPlugin settings. module.exports = async () => { return { module: { rules: [ { test: /\.glsl$/i, use: 'raw-loader' } ] }, mode: 'development', entry: { 'chapter-12': './samples/chapters/chapter-12/sphere-joint.js', }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath: '/', }, plugins: [ new HtmlWebpackPlugin(), ], experiments: { asyncWebAssembly: true }, devServer: { allowedHosts: 'all', host: '0.0.0.0', port: '3000', static: [ { directory: path.join(__dirname, 'assets'), publicPath: '/assets' }, { directory: path.join(__dirname, 'dist') } ] }, mode: 'development', } }
As we can see in this example, we’ve connected a large number of spheres to create a chain of spheres. When these spheres hit the cylinder in the middle, they’ll wrap around and slowly glide off this cylinder. We can see that while the orientation between these spheres changes based on their collisions, the absolute distance between the spheres stays the same.
Creating RigidBody
and Collider
So, to set up this example, we’ve created a number of spheres with RigidBody
and Collider
, similar to the previous examples. For each set of two spheres, we also create a joint like this:
const createChain = (beads) => {for (let i = 1; i < beads.length; i++) {const previousBead = beads[i - 1].userData.rigidBodyconst thisBead = beads[i].userData.rigidBodyconst positionPrevious = beads[i - 1].positionconst positionNext = beads[i].positionconst xOffset = Math.abs(positionNext.x - positionPrevious.x)const params = RAPIER.JointData.spherical({ x: 0, y: 0, z: 0 },{ x: xOffset, y: 0, z: 0 })world.createImpulseJoint(params, thisBead, previousBead, true)}}
We can see that we create a joint using RAPIER.JointData.spherical
(lines 8–11). The parameters here define the position of the first object, { x: 0, y: 0, z: 0 }
(line 9), and the relative position of the second object, { x: xOffset, y: 0, z: 0 }
(line 10). We do this for all the objects and add the joints to the Rapier world using ...