threlte logo
@threlte/rapier

<AutoColliders>

The <AutoColliders> component generates colliders based on its children. Currently these shapes are available:

  1. cuboid – uses each child mesh bounding box and generates a cuboid collider
  2. ball – uses each child mesh bounding box and generates a ball collider
  3. capsule – uses each child mesh bounding box and generates a capsule collider
  4. trimesh – uses each child mesh geometry and generates a polygonal collider which resembles the geometry
  5. convexHull – uses each child mesh geometry and generates a collider which resembles a convex hull around the geometry

The resulting colliders can be transformed (i.e. positioned, rotated and scaled) as well as given regular collider properties such as mass or centerOfMass.

<script lang="ts">
  import { Pane, Checkbox } from 'svelte-tweakpane-ui'
  import { Canvas } from '@threlte/core'
  import { HTML } from '@threlte/extras'
  import { Debug, World } from '@threlte/rapier'
  import Scene from './Scene.svelte'

  let debug = true
</script>

<Pane
  title="Auto Colliders"
  position="fixed"
>
  <Checkbox
    bind:value={debug}
    label="Debug"
  />
</Pane>

<div>
  <Canvas>
    <World>
      {#if debug}
        <Debug />
      {/if}

      <Scene />

      <HTML
        slot="fallback"
        transform
      >
        <p class="text-xs">
          It seems your browser<br />
          doesn't support WASM.<br />
          I'm sorry.
        </p>
      </HTML>
    </World>
  </Canvas>
</div>

<style>
  div {
    height: 100%;
  }
</style>
<script lang="ts">
  import { T } from '@threlte/core'
  import { AutoColliders } from '@threlte/rapier'
  import { BoxGeometry, MeshStandardMaterial } from 'three'
</script>

<T.Group position={[0, -0.5, 0]}>
  <AutoColliders shape={'cuboid'}>
    <T.Mesh
      receiveShadow
      geometry={new BoxGeometry(10, 1, 10)}
      material={new MeshStandardMaterial()}
    />
  </AutoColliders>
</T.Group>
<script lang="ts">
  import { T } from '@threlte/core'
  import { OrbitControls, Environment, useGltf } from '@threlte/extras'
  import { AutoColliders, RigidBody } from '@threlte/rapier'
  import { derived } from 'svelte/store'
  import type { MeshStandardMaterial, Mesh } from 'three'
  import { DEG2RAD } from 'three/src/math/MathUtils.js'
  import Ground from './Ground.svelte'

  const gltf = useGltf<{
    nodes: {
      'node_damagedHelmet_-6514': Mesh
    }
    materials: {
      Material_MR: MeshStandardMaterial
    }
  }>('/models/helmet/DamagedHelmet.gltf')

  const helmet = derived(gltf, (gltf) => {
    if (!gltf || !gltf.nodes['node_damagedHelmet_-6514']) return
    return gltf.nodes['node_damagedHelmet_-6514']
  })
</script>

<Environment
  path="/hdr/"
  files="shanghai_riverside_1k.hdr"
/>

<T.PerspectiveCamera
  makeDefault
  position.x={12}
  position.y={13}
  fov={40}
>
  <OrbitControls target.x={2.5} />
</T.PerspectiveCamera>

<T.DirectionalLight
  castShadow
  position={[8, 20, -3]}
/>

{#if $helmet}
  <T.Group
    position={[-2.5, 2, 2.5]}
    rotation={[90 * DEG2RAD, 0, 0]}
  >
    <RigidBody>
      <AutoColliders shape={'convexHull'}>
        <T.Mesh
          castShadow
          geometry={$helmet.geometry}
          material={$helmet.material}
        />
      </AutoColliders>
    </RigidBody>
  </T.Group>

  <T.Group
    position={[2.5, 2, 2.5]}
    rotation={[90 * DEG2RAD, 0, 0]}
  >
    <RigidBody>
      <AutoColliders shape={'ball'}>
        <T.Mesh
          castShadow
          geometry={$helmet.geometry}
          material={$helmet.material}
        />
      </AutoColliders>
    </RigidBody>
  </T.Group>

  <T.Group
    position={[2.5, 2, -2.5]}
    rotation={[90 * DEG2RAD, 0, 0]}
  >
    <RigidBody>
      <AutoColliders shape={'cuboid'}>
        <T.Mesh
          castShadow
          geometry={$helmet.geometry}
          material={$helmet.material}
        />
      </AutoColliders>
    </RigidBody>
  </T.Group>

  <T.Group
    position={[0, 2, 0]}
    rotation={[90 * DEG2RAD, 0, 0]}
  >
    <RigidBody>
      <AutoColliders shape={'trimesh'}>
        <T.Mesh
          castShadow
          geometry={$helmet.geometry}
          material={$helmet.material}
        />
      </AutoColliders>
    </RigidBody>
  </T.Group>

  <T.Group
    position={[-2.5, 2, -2.5]}
    rotation={[90 * DEG2RAD, 0, 0]}
  >
    <RigidBody>
      <AutoColliders shape={'capsule'}>
        <T.Mesh
          castShadow
          geometry={$helmet.geometry}
          material={$helmet.material}
        />
      </AutoColliders>
    </RigidBody>
  </T.Group>
{/if}

<T.GridHelper args={[50]} />

<Ground />

Model: Battle Damaged Sci-fi Helmet by theblueturtle_

Component Signature

If a <AutoColliders> component is not a child of a <RigidBody> component, the transform properties are reactive.

If you don't provide any of the properties density, mass or massProperties, Rapier will figure that out for you.

You can provide either a property density, mass or massProperties.

Props

name
type
required
default

contactForceEventThreshold
number
no

density
number
no

friction
number
no

frictionCombineRule
CoefficientCombineRule
no

mass
number
no

massProperties
{ mass: number, centerOfMass: Position, principalAngularInertia: Position, angularInertiaLocalFrame: Rotation, }
no

restitution
number
no

restitutionCombineRule
CoefficientCombineRule
no

sensor
boolean
no

shape
'cuboid' | 'ball' | 'capsule' | 'trimesh' | 'convexHull'
no
'convexHull'

Events

name
payload

create
{ ref: Collider[], cleanup: (callback: () => void) => void }

collisionenter
{ targetCollider: Collider, targetRigidBody: RigidBody | null, manifold: TempContactManifold, flipped: boolean }

collisionexit
{ targetCollider: Collider, targetRigidBody: RigidBody | null }

sensorenter
{ targetCollider: Collider, targetRigidBody: RigidBody | null }

sensorexit
{ targetCollider: Collider targetRigidBody: RigidBody | null }

contact
{ targetCollider: Collider, targetRigidBody: RigidBody | null, manifold: TempContactManifold, flipped: boolean, maxForceDirection: Vector, maxForceMagnitude: number, totalForce: Vector, totalForceMagnitude: number, }

Bindings

name
type

colliders
Collider[]