MCPcopy
hub / github.com/pmndrs/use-cannon

github.com/pmndrs/use-cannon @v4.9.0 sqlite

repository ↗ · DeepWiki ↗ · release v4.9.0 ↗
1,160 symbols 3,959 edges 57 files 0 documented · 0%
README

Build Status Version Downloads Discord Shield

Imgur

yarn add @react-three/cannon

React hooks for cannon-es. Use this in combination with react-three-fiber.

  • [x] Doesn't block the main thread, runs in a web worker
  • [x] Supports instancing out of the box
  • [x] Least amount of friction you'll ever experience with a physics rig ... 🙈

Demos

Check out all of our examples at https://cannon.pmnd.rs

The code for the examples lives in ./examples

How it works

  1. Get all the imports that you need.
import { Physics, useBox, ... } from '@react-three/cannon'
  1. Create a physics world.
<Physics>{/* Physics related objects in here please */}</Physics>
  1. Pick a shape that suits your objects contact surface, it could be a box, plane, sphere, etc. Give it a mass, too.
const [ref, api] = useBox(() => ({ mass: 1 }))
  1. Take your object, it could be a mesh, line, gltf, anything, and tie it to the reference you have just received. Et voilà, it will now be affected by gravity and other objects inside the physics world.
<mesh ref={ref} geometry={...} material={...} />
  1. You can interact with it by using the api, which lets you apply positions, rotations, velocities, forces and impulses.
useFrame(({ clock }) => api.position.set(Math.sin(clock.getElapsedTime()) * 5, 0, 0))
  1. You can use the body api to subscribe to properties to get updates on each frame.
const velocity = useRef([0, 0, 0])
useEffect(() => {
  const unsubscribe = api.velocity.subscribe((v) => (velocity.current = v))
  return unsubscribe
}, [])

Simple example

Let's make a cube falling onto a plane. You can play with a sandbox here.

import { Canvas } from '@react-three/fiber'
import { Physics, usePlane, useBox } from '@react-three/cannon'

function Plane(props) {
  const [ref] = usePlane(() => ({ rotation: [-Math.PI / 2, 0, 0], ...props }))
  return (
    <mesh ref={ref}>
      <planeGeometry args={[100, 100]} />
    </mesh>
  )
}

function Cube(props) {
  const [ref] = useBox(() => ({ mass: 1, position: [0, 5, 0], ...props }))
  return (
    <mesh ref={ref}>
      <boxGeometry />
    </mesh>
  )
}

ReactDOM.render(
  <Canvas>
    <Physics>
      <Plane />
      <Cube />
    </Physics>
  </Canvas>,
  document.getElementById('root'),
)

Debug

You can debug your scene using the cannon-es-debugger. This will show you how cannon "sees" your scene. Do not use this in production as it will pull in cannon-es a second time!

import { Physics, Debug } from '@react-three/cannon'

ReactDOM.render(
  <Canvas>
    <Physics>
      <Debug color="black" scale={1.1}>
        {/* children */}
      </Debug>
    </Physics>
  </Canvas>,
  document.getElementById('root'),
)

Api

Exports

function Physics({
  allowSleep = false,
  axisIndex = 0,
  broadphase = 'Naive',
  defaultContactMaterial = { contactEquationStiffness: 1e6 },
  gravity = [0, -9.81, 0],
  isPaused = false,
  iterations = 5,
  maxSubSteps = 10,
  quatNormalizeFast = false,
  quatNormalizeSkip = 0,
  shouldInvalidate = true,
  // Maximum amount of physics objects inside your scene
  // Lower this value to save memory, increase if 1000 isn't enough
  size = 1000,
  solver = 'GS',
  stepSize = 1 / 60,
  tolerance = 0.001,
}: React.PropsWithChildren<ProviderProps>): JSX.Element

function Debug({ color = 'black', scale = 1 }: DebugProps): JSX.Element

function usePlane(
  fn: GetByIndex<PlaneProps>,
  fwdRef?: React.Ref<THREE.Object3D>,
  deps?: React.DependencyList,
): Api

function useBox(
  fn: GetByIndex<BoxProps>,
  fwdRef?: React.Ref<THREE.Object3D>,
  deps?: React.DependencyList,
): Api

function useCylinder(
  fn: GetByIndex<CylinderProps>,
  fwdRef?: React.Ref<THREE.Object3D>,
  deps?: React.DependencyList,
): Api

function useHeightfield(
  fn: GetByIndex<HeightfieldProps>,
  fwdRef?: React.Ref<THREE.Object3D>,
  deps?: React.DependencyList,
): Api

function useParticle(
  fn: GetByIndex<ParticleProps>,
  fwdRef?: React.Ref<THREE.Object3D>,
  deps?: React.DependencyList,
): Api

function useSphere(
  fn: GetByIndex<SphereProps>,
  fwdRef?: React.Ref<THREE.Object3D>,
  deps?: React.DependencyList,
): Api

function useTrimesh(
  fn: GetByIndex<TrimeshProps>,
  fwdRef?: React.Ref<THREE.Object3D>,
  deps?: React.DependencyList,
): Api

function useConvexPolyhedron(
  fn: GetByIndex<ConvexPolyhedronProps>,
  fwdRef?: React.Ref<THREE.Object3D>,
  deps?: React.DependencyList,
): Api

function useCompoundBody(
  fn: GetByIndex<CompoundBodyProps>,
  fwdRef?: React.Ref<THREE.Object3D>,
  deps?: React.DependencyList,
): Api

function useRaycastVehicle(
  fn: () => RaycastVehicleProps,
  fwdRef?: React.Ref<THREE.Object3D>,
  deps: React.DependencyList[] = [],
): [React.RefObject<THREE.Object3D>, RaycastVehiclePublicApi]

function usePointToPointConstraint(
  bodyA: React.Ref<THREE.Object3D>,
  bodyB: React.Ref<THREE.Object3D>,
  optns: PointToPointConstraintOpts,
  deps: React.DependencyList = [],
): ConstraintApi

function useConeTwistConstraint(
  bodyA: React.Ref<THREE.Object3D>,
  bodyB: React.Ref<THREE.Object3D>,
  optns: ConeTwistConstraintOpts,
  deps: React.DependencyList = [],
): ConstraintApi

function useDistanceConstraint(
  bodyA: React.Ref<THREE.Object3D>,
  bodyB: React.Ref<THREE.Object3D>,
  optns: DistanceConstraintOpts,
  deps: React.DependencyList = [],
): ConstraintApi

function useHingeConstraint(
  bodyA: React.Ref<THREE.Object3D>,
  bodyB: React.Ref<THREE.Object3D>,
  optns: HingeConstraintOpts,
  deps: React.DependencyList = [],
): ConstraintApi

function useLockConstraint(
  bodyA: React.Ref<THREE.Object3D>,
  bodyB: React.Ref<THREE.Object3D>,
  optns: LockConstraintOpts,
  deps: React.DependencyList = [],
): ConstraintApi

function useSpring(
  bodyA: React.Ref<THREE.Object3D>,
  bodyB: React.Ref<THREE.Object3D>,
  optns: SpringOptns,
  deps: React.DependencyList = [],
): void

function useRaycastClosest(
  options: RayOptions,
  callback: (e: RayhitEvent) => void,
  deps: React.DependencyList = [],
): void

function useRaycastAny(
  options: RayOptions,
  callback: (e: RayhitEvent) => void,
  deps: React.DependencyList = [],
): void

function useRaycastAll(
  options: RayOptions,
  callback: (e: RayhitEvent) => void,
  deps: React.DependencyList = [],
): void

function useContactMaterial(
  materialA: MaterialOptions,
  materialB: MaterialOptions,
  options: ContactMaterialOptions,
  deps: React.DependencyList = [],
): void

Returned api

type WorkerApi = {
  [K in AtomicName]: AtomicApi<K>
} & {
  [K in VectorName]: VectorApi
} & {
  applyForce: (force: Triplet, worldPoint: Triplet) => void
  applyImpulse: (impulse: Triplet, worldPoint: Triplet) => void
  applyLocalForce: (force: Triplet, localPoint: Triplet) => void
  applyLocalImpulse: (impulse: Triplet, localPoint: Triplet) => void
  applyTorque: (torque: Triplet) => void
  quaternion: QuaternionApi
  rotation: VectorApi
  sleep: () => void
  wakeUp: () => void
}

interface PublicApi extends WorkerApi {
  at: (index: number) => WorkerApi
}

type Api = [React.RefObject<THREE.Object3D>, PublicApi]

type AtomicName =
  | 'allowSleep'
  | 'angularDamping'
  | 'collisionFilterGroup'
  | 'collisionFilterMask'
  | 'collisionResponse'
  | 'fixedRotation'
  | 'isTrigger'
  | 'linearDamping'
  | 'mass'
  | 'material'
  | 'sleepSpeedLimit'
  | 'sleepTimeLimit'
  | 'userData'

type AtomicApi<K extends AtomicName> = {
  set: (value: AtomicProps[K]) => void
  subscribe: (callback: (value: AtomicProps[K]) => void) => () => void
}

type QuaternionApi = {
  set: (x: number, y: number, z: number, w: number) => void
  copy: ({ w, x, y, z }: Quaternion) => void
  subscribe: (callback: (value: Quad) => void) => () => void
}

type VectorName = 'angularFactor' | 'angularVelocity' | 'linearFactor' | 'position' | 'velocity'

type VectorApi = {
  set: (x: number, y: number, z: number) => void
  copy: ({ x, y, z }: Vector3 | Euler) => void
  subscribe: (callback: (value: Triplet) => void) => () => void
}

type ConstraintApi = [
  React.RefObject<THREE.Object3D>,
  React.RefObject<THREE.Object3D>,
  {
    enable: () => void
    disable: () => void
  },
]

type HingeConstraintApi = [
  React.RefObject<THREE.Object3D>,
  React.RefObject<THREE.Object3D>,
  {
    enable: () => void
    disable: () => void
    enableMotor: () => void
    disableMotor: () => void
    setMotorSpeed: (value: number) => void
    setMotorMaxForce: (value: number) => void
  },
]

type SpringApi = [
  React.RefObject<THREE.Object3D>,
  React.RefObject<THREE.Object3D>,
  {
    setStiffness: (value: number) => void
    setRestLength: (value: number) => void
    setDamping: (value: number) => void
  },
]

interface RaycastVehiclePublicApi {
  applyEngineForce: (value: number, wheelIndex: number) => void
  setBrake: (brake: number, wheelIndex: number) => void
  setSteeringValue: (value: number, wheelIndex: number) => void
  sliding: {
    subscribe: (callback: (sliding: boolean) => void) => void
  }
}

Props

```typescript type InitProps = { allowSleep?: boolean axisIndex?: 0 | 1 | 2 broadphase?: Broadphase defaultContactMaterial?: ContactMaterialOptions gravity?: Triplet iterations?: number quatNormalizeFast?: boolean quatNormalizeSkip?: number solver?: Solver tolerance?: number }

type ProviderProps = InitProps & { isPaused?: boolean maxSubSteps?: number shouldInvalidate?: boolean size?: number stepSize?: number }

type AtomicProps = { allowSleep: boolean angularDamping: number collisionFilterGroup: number collisionFilterMask: number collisionResponse: number fixedRotation: boolean isTrigger: boolean linearDamping: number mass: number material: MaterialOptions sleepSpeedLimit: number sleepTimeLimit: number userData: {} }

type Broadphase = 'Naive' | 'SAP' type Triplet = [x: number, y: number, z: number] type Quad = [x: number, y: number, z: number, w: number]

type VectorProps = Record

type BodyProps = Partial & Partial & { args?: T onCollide?: (e: CollideEvent) => void onCollideBegin?: (e: CollideBeginEvent) => void onCollideEnd?: (e: CollideEndEvent) => void quaternion?: Quad rotation?: Triplet type?: 'Dynamic' | 'Static' | 'Kinematic' }

type Event = RayhitEvent | CollideEvent | CollideBeginEvent | CollideEndEvent type CollideEvent = { op: string type: 'collide' body: THREE.Object3D target: THREE.Object3D contact: { // the world position of the point of contact contactPoint: number[] // the normal of the collision on the surface of // the colliding body contactNormal: number[] // velocity of impact along the contact normal impactVelocity: number // a unique ID for each contact event id: string // these are lower-level properties from cannon: // bi: one of the bodies involved in contact bi: THREE.Object3D // bj: the other body involved in contact bj: THREE.Object3D // ni: normal of contact relative to bi ni: number[] // ri: the point of contact relative to bi ri: number[] // rj: the point of contact relative to bj rj: number[] } collisionFilters: { bodyFilterGroup: number bodyFilterMask: number targetFilterGroup: number targetFilterMask: number } } type CollideBeginEvent = { op: 'event' type: 'collideBegin' target: Object3D body: Object3D } type CollideEndEvent = { op: 'event' type: 'collideEnd' target: Object3D body: Object3D } type RayhitEvent = { op: string type: 'rayhit' body: THREE.Object3D target: THREE.Object3D }

type CylinderArgs = [radiusTop?: number, radiusBottom?: number, height?: number, numSegments?: number] type SphereArgs = [radius: number] type TrimeshArgs = [vertices: ArrayLike, indices: ArrayLike] type HeightfieldArgs = [ data: number[][], options: { elementSize?: number; maxValue?: number; minValue?: number }, ] type ConvexPolyhedronArgs = [ vertices?: V[], faces?: number[][], normals?: V[], axes?: V[], boundingSphereRadius?: number, ]

interface PlaneProps extends BodyProps {} interface BoxProps extends BodyProps {} // extents: [x, y, z] interface CylinderProps extends BodyProps {} interface ParticleProps extends BodyProps {} interface SphereProps extends BodyProps {} interface TrimeshProps extends BodyPropsArgsRequired {} interface HeightfieldProps extends BodyPropsArgsRequired {} interface ConvexPolyhedronProps extends BodyProps {} interface CompoundBodyProps extends BodyProps { shapes: BodyProps & { type: ShapeType }[] }

interface ConstraintOptns { maxForce?: number maxMultiplier?: number collideConnected?: boolean wakeUpBodies?: boolean }

interface PointToPointConstraintOpts extends ConstraintOptns { pivotA: Triplet pivotB: Triplet }

interface ConeTwistConstrai

Extension points exported contracts — how you extend this code

CompoundBodyProps (Interface)
(no doc)
src/hooks.ts
ConstraintOptns (Interface)
(no doc)
src/setup.ts
DecoratedWorld (Interface)
(no doc)
src/worker/state.ts
IntrinsicElements (Interface)
(no doc)
examples/src/demos/demo-Heightfield.tsx
PublicApi (Interface)
(no doc)
src/hooks.ts
PointToPointConstraintOpts (Interface)
(no doc)
src/setup.ts
State (Interface)
(no doc)
src/worker/state.ts
IntrinsicElements (Interface)
(no doc)
examples/src/demos/Raycast/index.tsx

Core symbols most depended-on inside this repo

nn
called by 750
examples/public/draco-gltf/draco_decoder.js
Dm
called by 328
examples/public/draco-gltf/draco_decoder.js
p
called by 318
examples/public/draco-gltf/draco_wasm_wrapper.js
x
called by 285
examples/public/draco-gltf/draco_wasm_wrapper.js
pn
called by 186
examples/public/draco-gltf/draco_decoder.js
Gn
called by 171
examples/public/draco-gltf/draco_decoder.js
Sm
called by 158
examples/public/draco-gltf/draco_decoder.js
qn
called by 146
examples/public/draco-gltf/draco_decoder.js

Shape

Function 1,075
Method 64
Interface 19
Class 2

Languages

TypeScript100%

Modules by API surface

examples/public/draco-gltf/draco_decoder.js849 symbols
src/cannon-worker-api.ts64 symbols
src/hooks.ts51 symbols
examples/public/draco-gltf/draco_wasm_wrapper.js46 symbols
examples/src/demos/MondayMorning/index.tsx10 symbols
src/setup.ts9 symbols
examples/src/demos/Raycast/index.tsx8 symbols
src/Provider.tsx7 symbols
examples/src/demos/demo-Heightfield.tsx6 symbols
examples/src/demos/demo-ConvexPolyhedron.tsx6 symbols
examples/src/demos/demo-Chain.tsx6 symbols
examples/src/demos/Pingpong/index.tsx6 symbols

Dependencies from manifests, versioned

@babel/core7.16.5 · 1×
@babel/plugin-transform-runtime7.16.5 · 1×
@babel/preset-env7.16.5 · 1×
@babel/preset-react7.16.5 · 1×
@babel/preset-typescript7.16.5 · 1×
@react-three/cannonfile:../ · 1×
@react-three/drei8.11.1 · 1×
@react-three/fiber7.0.24 · 1×
@rollup/plugin-babel5.3.0 · 1×
@rollup/plugin-node-resolve13.1.1 · 1×
@types/lodash-es4.17.5 · 1×
@types/node17.0.0 · 1×

For agents

$ claude mcp add use-cannon \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact