JSPM

  • Created
  • Published
  • Downloads 88348
  • Score
    100M100P100Q240051F

Package Exports

  • @react-three/rapier
  • @react-three/rapier/dist/react-three-rapier.cjs.js
  • @react-three/rapier/dist/react-three-rapier.esm.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@react-three/rapier) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

⚠️ Under heavy development. All APIs are subject to change. ⚠️

Usage

import { Box, Torus } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import { Physics, RigidBody } from "@react-three/rapier";

const App = () => {
  return (
    <Canvas>
      <Suspense>
        <Physics>
          <RigidBody colliders={"hull"} restitution={2}>
            <Torus />
          </RigidBody>

          <RigidBody position={[0, -2, 0]} type="kinematicPosition">
            <Box args={[20, 0.5, 20]} />
          </RigidBody>
        </Physics>
      </Suspense>
    </Canvas>
  );
};

Automatic colliders

RigidBodies generate automatic colliders by default for all meshes that it contains. You can control the default collider by setting the colliders prop on a <RigidBody />, or change it globally by setting colliders on <Physics />. Setting colliders={false} disables auto-generation.

Supported values:

Generate ConvexHull colliders for all meshes in a RigidBody by default:

const Scene = () => (
  <Physics colliders="hull">
    <RigidBody>
      <Box />
    </RigidBody>
    <RigidBody position={[0, 10, 0]}>
      <Sphere />
    </RigidBody>
  </Physics>
);

Turn off automatic collider generation globally, but apply auto generation locally:

const Scene = () => (
  <Physics colliders={false}>
    {/* Use an automatic CuboidCollider for all meshes inside this RigidBody */}
    <RigidBody colliders="cuboid">
      <Box />
    </RigidBody>

    {/* Use an automatic BallCollider for all meshes inside this RigidBody */}
    <RigidBody position={[0, 10, 0]} colliders="ball">
      <Sphere />
    </RigidBody>

    {/* Make a compound shape with two custom BallColliders */}
    <RigidBody position={[0, 10, 0]}>
      <Sphere />
      <BallCollider args={0.5} />
      <BallCollider args={0.5} position={[1, 0, 0]} />
    </RigidBody>

    {/* Make a compound shape with two custom BallColliders, an automatic BallCollider,
        Two automatic MeshColliders, based on two different shape strategies */}
    <RigidBody position={[0, 10, 0]} colliders='ball'>
      <MeshCollider type="trimesh">
        <mesh ... />
      </MeshCollider>

      <MeshCollider type="hull">
        <mesh ... />
      </MeshCollider>

      <Sphere />

      <BallCollider args={0.5} />
      <BallCollider args={0.5} position={[1, 0, 0]} />
    </RigidBody>
  </Physics>
);

Objects work inside other transformed objects as well. Simulation runs in world space and is transformed to the objects local space, so that things act as you'd expect.

import { Box } from "@react-three/drei";
import { RigidBody, CuboidCollider } from "@react-three/rapier";

const Scene = () => (
  <group position={[2, 5, 0]} rotation={[0, 0.3, 2]}>
    <RigidBody>
      <Box />
      <CuboidCollider args={[0.5, 0.5, 0.5]} />
    </RigidBody>
  </group>
);

Instanced Meshes

Instanced meshes can also be used and have automatic colliders generated from their mesh.

By wrapping the InstancedMesh in <InstancedRigidBodies />, each instance will be attached to an individual RigidBody.

import { InstancedRigidBodies } from "@react-three/rapier";

const COUNT = 1000;

const Scene = () => {
  const instancedApi = useRef<InstancedRigidBodyApi>(null);

  useEffect(() => {
    // You can access individual instanced by their index
    instancedApi.at(40).applyImpulse({ x: 0, y: 10, z: 0 });

    // Or update all instances as if they were in an array
    instancedApi.forEach((api) => {
      api.applyImpulse({ x: 0, y: 10, z: 0 });
    });
  }, []);

  // We can set the initial positions, and rotations, of the instances by providing an array equal to the instance count
  const positions = Array.from({ length: COUNT }, (_, index) => [index, 0, 0]);

  const rotations = Array.from({ length: COUNT }, (_, index) => [
    Math.random(),
    Math.random(),
    Math.random(),
  ]);

  return (
    <InstancedRigidBodies
      ref={instancedApi}
      positions={positions}
      rotations={rotations}
      colliders="ball"
    >
      <instancedMesh args={[undefined, undefined, COUNT]}>
        <sphereBufferGeometry args={[0.2]} />
        <meshPhysicalGeometry color="blue" />
      </instancedMesh>
    </InstancedRigidBodies>
  );
};

Debug

Use the Debug component to see live representations of all colliders in a scene.

Note: Experimental. Not all shapes are supported. Unsupported shapes are always represented by cubes.

import { Box, Sphere } from "@react-three/drei";
import { RigidBody, Debug } from "@react-three/rapier";

const Scene = () => {
  return (
    <Physics>
      <Debug />

      <RigidBody>
        <Box />
      </RigidBody>
      <RigidBody>
        <Sphere />
      </RigidBody>
    </Physics>
  );
};

Events

You can subscribe collision and state events on the RigidBody.

const RigidBottle = () => {
  const [isAsleep, setIsAsleep] = useState(false);

return (
    <RigidBody
      colliders="hull"
      onSleep={() => setIsAsleep(true)}
      onWake={() => setIsAsleep(false)}
      onCollisionEnter={({manifold}) => {
        console.log('Collision at world position ', manifold.solverContactPoint(0))
      }}
    >
      <Sphere>
        <meshPhysicalMaterial color={isAsleep ? 'white' : 'blue'}>
      </Sphere>
    </RigidBody>
  )
}

Joints

WIP


Roadmap

In order, but also not necessarily:

  • RigidBodies, Colliders
  • Joints
  • Nested objects retain world transforms
  • Nested objects retain correct collider scale
  • Automatic colliders based on rigidbody children
  • Translation and rotational constraints
  • Collision events
  • Colliders outside RigidBodies
  • InstancedMesh support
  • Normalize and improve collision events (add events to single Colliders, InstancedRigidBodies, etc)
  • Docs
  • CodeSandbox examples
  • Helpers, for things like Vehicle, Rope, Player, etc