cannon-es Documentation

repository·master·Indexed 24 days ago

https://github.com/pmndrs/cannon-es

A maintained, type-safe, and tree-shakeable fork of the cannon.js lightweight 3D physics engine written in JavaScript. Designed for modern environments with ESM and CJS builds, it provides features for simulating rigid bodies (Dynamic, Static, and Kinematic), world stepping, raycasting with various intersection modes, and constraints like HingeConstraint. Version 0.20.0.

Tokens
9.3K
Snippets
6
Records
54
Agent score
85%

What's inside cannon-es

  1. Understand Body Types: Dynamic, Kinematic, and Static

    master

    Bodies in cannon-es behave differently based on their mass and type:

    1. Dynamic Bodies: Have a mass greater than 0. They are affected by forces (like gravity) and velocity.
    2. Static Bodies: Have a mass of 0 (or are explicitly set to CANNON.Body.STATIC). They are not affected by forces or velocity and remain fixed in position.
    3. Kinematic Bodies: Are not affected by forces but can have a velocity and move around manually.

    To create a static body, you can either set mass: 0 or use the type property:

    const groundBody = new CANNON.Body({
      type: CANNON.Body.STATIC,
      shape: new CANNON.Plane(),
    })
  2. Sync cannon-es physics with three.js rendering

    master

    cannon-es only computes physics math and does not handle rendering. To visualize bodies, you must manually sync the position and rotation of a three.js mesh with the CANNON.Body every frame.

    1. Create a corresponding mesh in three.js (e.g., THREE.Mesh).
    2. In your animation loop, after calling world.fixedStep(), copy the body's position and quaternion to the mesh.
    // Inside the animation loop
    function animate() {
      requestAnimationFrame(animate)
    
      // 1. Step the physics world
      world.fixedStep()
    
      // 2. Copy physics data to the visual mesh
      sphereMesh.position.copy(sphereBody.position)
      sphereMesh.quaternion.copy(sphereBody.quaternion)
    
      // 3. Render the three.js scene
      renderer.render(scene, camera)
    }
  3. Import cannon-es

    master

    You can import cannon-es using standard ESM imports. If you are using a bundler like Webpack, you can import the entire namespace to take advantage of tree shaking.

    For specific imports:

    import { World } from 'cannon-es'
    
    // ...

    For namespace imports (Webpack compatible):

    import * as CANNON from 'cannon-es'
    
    // ...
    import { World } from 'cannon-es'
    
    // ...
    
    // or
    
    import * as CANNON from 'cannon-es'
    
    // ...
  4. Initialize a physics world with gravity

    master

    To start a simulation, create a new CANNON.World instance. You can configure the global gravity using a CANNON.Vec3. Note that cannon-es uses SI units (meters, kilograms, seconds).

    const world = new CANNON.World({
      gravity: new CANNON.Vec3(0, -9.82, 0), // m/s²
    })
  5. Use the RaycastVehicle class for vehicle simulation

    master

    The RaycastVehicle class is a helper for simulating vehicles by casting rays from wheel positions towards the ground to apply suspension and friction forces. It requires a chassisBody (a Body instance) and allows you to define the vehicle's orientation using axis indices.

    To use it, instantiate the class with a chassis body, add wheels using addWheel(), and then add the vehicle to the physics World using addToWorld(world). This automatically registers a preStep listener to update the vehicle's physics every frame.

    Note on Rendering: During each simulation step, wheel transforms are updated before the chassis. To ensure wheels are rendered at their correct positions, you must call updateWheelTransform(wheelIndex) for each wheel manually before your rendering loop.

  6. Listen to collision events in the World

    master

    The World class extends EventTarget, allowing you to listen for collision events.

    Body Collision

    • collide: Dispatched on a Body when it collides with another body.

    Contact Events

    • beginContact: Dispatched when two bodies start colliding.
    • endContact: Dispatched when two bodies stop colliding.
    • beginShapeContact: Dispatched when two specific shapes start colliding.
    • endShapeContact: Dispatched when two specific shapes stop colliding.

    Event Data Structure:

    • beginContact / endContact events provide bodyA and bodyB properties.
    • beginShapeContact / endShapeContact events provide bodyA, bodyB, shapeA, and shapeB properties.
  7. Understand Body sleep states

    master

    To optimize performance, cannon-es allows bodies to "sleep" when they are not moving significantly.

    Sleep States

    • Body.AWAKE: The body is actively being simulated.
    • Body.SLEEPY: The body's speed is below sleepSpeedLimit but it hasn't been sleepy long enough to fall asleep.
    • Body.SLEEPING: The body has been sleepy for longer than sleepTimeLimit and is now stationary/immovable.

    Controlling Sleep

    • wakeUp(): Manually wakes a sleeping body.
    • sleep(): Manually forces a body into the sleeping state.
    • allowSleep: A boolean property to enable/disable automatic sleeping.
  8. Understand Body types

    master

    The Body.type determines how the object behaves in the physics simulation:

    • Body.DYNAMIC: Fully simulated. Responds to forces and collisions. Must have a finite, non-zero mass. Can collide with all body types.
    • Body.STATIC: Does not move during simulation (behaves as if it has infinite mass). Can be moved manually by setting its position. Velocity is always zero. Does not collide with other static or kinematic bodies.
    • Body.KINEMATIC: Moves according to its velocity but does not respond to forces. Behaves as if it has infinite mass. Can be moved manually. Does not collide with other static or kinematic bodies.
  9. Create and add Rigid Bodies to the world

    master

    Rigid Bodies are the entities simulated in the world. You define them using the CANNON.Body class, specifying a mass and a shape (such as CANNON.Sphere, CANNON.Box, or CANNON.Plane). After creation, you must add them to the world using world.addBody(body).

    const radius = 1 // m
    const sphereBody = new CANNON.Body({
      mass: 5, // kg
      shape: new CANNON.Sphere(radius),
    })
    sphereBody.position.set(0, 10, 0) // m
    world.addBody(sphereBody)
  10. Step the physics simulation forward

    master

    To progress the simulation, you must call a stepping method within your animation loop.

    world.fixedStep() is the preferred method for most use cases. It automatically tracks the time since the last call to ensure the simulation runs at a consistent speed regardless of the device's framerate. By default, it runs at 60fps (1 / 60).

    function animate() {
      requestAnimationFrame(animate)
      world.fixedStep()
    }
    animate()

    Using world.step() (Advanced)

    If you need to manually control the delta time (dt), use world.step(timeStep, dt). This is useful if you want to pass the exact time elapsed since the last frame manually.

    const timeStep = 1 / 60
    let lastCallTime
    function animate() {
      requestAnimationFrame(animate)
    
      const time = performance.now() / 1000
      if (!lastCallTime) {
        world.step(timeStep)
      } else {
        const dt = time - lastCallTime
        world.step(timeStep, dt)
      }
      lastCallTime = time
    }
    animate()
  11. Configure BodyOptions

    master

    When creating a Body, you can pass an options object with the following keys:

    KeyTypeDefaultDescription
    collisionFilterGroupnumber1The collision group the body belongs to.
    collisionFilterMasknumber-1The collision group the body can collide with.
    collisionResponsebooleantrueWhether to produce contact forces when in contact with other bodies.
    positionVec3-World space position.
    velocityVec3-World space velocity.
    massnumber0The mass of the body.
    materialMaterialnullThe physics material defining interactions.
    linearDampingnumber0.01Damping of linear velocity (0 to 1).
    typeBodyType(derived from mass)Body.DYNAMIC, Body.STATIC, or Body.KINEMATIC.
    allowSleepbooleantrueIf true, the body will automatically fall to sleep.
    sleepSpeedLimitnumber0.1Speed threshold below which the body is considered sleepy.
    sleepTimeLimitnumber1Seconds a body must be sleepy before it falls asleep.
    quaternionQuaternion-World space orientation.
    angularVelocityVec3-Angular velocity in world space.
    fixedRotationbooleanfalseIf true, prevents the body from rotating.
    angularDampingnumber0.01Damping of angular velocity (0 to 1).
    linearFactorVec3(1, 1, 1)Limits motion along world axes.
    angularFactorVec3(1, 1, 1)Limits rotation along world axes.
    shapeShape-A single shape to add to the body.
    isTriggerbooleanfalseIf true, the body behaves like a trigger (no collision forces, but events are raised).