Physics
Physics in XR Blocks is powered by the Rapier physics engine.
Getting started
To use physics in your scene, import the RAPIER physics engine, then pass the RAPIER component into the physics options:
import * as xb from 'xrblocks';
import RAPIER from 'https://cdn.skypack.dev/@dimforge/rapier3d-simd-compat@0.17.0';
const options = new xb.Options();
options.physics.RAPIER = RAPIER;
xb.init(options);
TypeScript Setup
The Rapier physics library comes in several different variants such as @dimforge/rapier3d and @dimforge/rapier3d-simd-compat.
XR Blocks supports the different 3D variants of RAPIER by using a virtual import rapier3d
for types instead of directly importing from one of the specific packages. When using TypeScript, you will need to link the virtual import to your installed version of Rapier. For example, when using @dimforge/rapier3d-simd-compat:
{
"compilerOptions": {
"paths": {
"rapier3d": [
"./node_modules/@dimforge/rapier3d-simd-compat/rapier"
],
}
},
//...
}
Physics
The Physics
controller will initialize RAPIER
, create a RAPIER world, and call world.step
for every physics step.
Is is accessible from xb.core.physics
and has the following properties:
RAPIER
- the globalRAPIER
object.world
- the globalRAPIER.world
object.fps
- the fixed physics update rate.options
- physics options.
Adding physics to objects
In the initPhysics
method, you can create rigid bodies corresponding to your object.
Then in the physicsStep
method, copy the translation and rotation of the rigid body to your object.
For example:
export class Ball extends xb.Script {
//...
initPhysics(physics) {
const RAPIER = physics.RAPIER;
const desc = RAPIER.RigidBodyDesc.dynamic()
.setTranslation(...this.position);
const shape = RAPIER.ColliderDesc.ball(this.radius);
this.body = world.createRigidBody(desc);
this.collider = world.createCollider(shape, this.body);
}
physicsStep() {
this.position.copy(this.body.translation());
this.quaternion.copy(this.body.rotation());
}
}
Physics Options
By default, we uses the following options in PhysicsOptions.js
:
{
fps: 45,
gravity: {x: 0.0, y: -9.81, z: 0.0},
// Have `Physics` automatically call world.step.
worldStep: true,
// Use an event queue when calling world.step.
useEventQueue: false
};