threlte logo
@threlte/rapier

<CollisionGroups>

The most efficient way of preventing some pairs of colliders from interacting with each other is to use a <CollisionGroups> component.

Each collider that is a child (direct or indirect) of the component <CollisionGroups> is applied a memberships and filters attribute. The shorthand groups sets both properties at once.

For general usage instructions, see the relevant documentation here.

Example

  • Collider A is affected by Collider B and not by Collider C
  • Collider B is affected by Collider A and Collider C
  • Collider C is affected by Collider B and not by Collider A
<script lang="ts">
  import { Canvas } from '@threlte/core'
  import { HTML } from '@threlte/extras'
  import { Debug, World } from '@threlte/rapier'
  import Scene from './Scene.svelte'
  import { Pane, Button } from 'svelte-tweakpane-ui'

  let reset: () => void | undefined
</script>

<Pane
  title="Collision Groups"
  position="fixed"
>
  <Button
    title="Reset"
    on:click={reset}
  />
</Pane>

<div>
  <Canvas>
    <World>
      <Debug />
      <Scene bind:reset />

      {#snippet fallback()}
        <HTML transform>
          <p>
            It seems your browser<br />
            doesn't support WASM.<br />
            I'm sorry.
          </p>
        </HTML>
      {/snippet}
    </World>
  </Canvas>
</div>

<style>
  div {
    height: 100%;
  }
  p {
    font-size: 0.75rem;
    line-height: 1rem;
  }
</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 } from '@threlte/extras'
  import { AutoColliders, CollisionGroups, RigidBody } from '@threlte/rapier'
  import { BoxGeometry, MeshStandardMaterial } from 'three'
  import Ground from './Ground.svelte'

  const geometry = new BoxGeometry(1, 1, 1)

  let resetCounter = 0
  export const reset = () => {
    resetCounter += 1
  }
</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]}
/>

{#key resetCounter}
  <!-- Collider A -->
  <CollisionGroups
    memberships={[1]}
    filter={[2]}
  >
    <T.Group position={[0, 1.5, 1 - Math.random() * 2]}>
      <RigidBody>
        <AutoColliders shape={'cuboid'}>
          <T.Mesh
            castShadow
            {geometry}
            material={new MeshStandardMaterial({
              color: 'red'
            })}
          />
        </AutoColliders>
      </RigidBody>
    </T.Group>
  </CollisionGroups>

  <!-- Collider B -->
  <CollisionGroups
    memberships={[2]}
    filter={[1, 3]}
  >
    <T.Group position={[0, 4.5, 1 - Math.random() * 2]}>
      <RigidBody>
        <AutoColliders shape={'cuboid'}>
          <T.Mesh
            castShadow
            {geometry}
            material={new MeshStandardMaterial({
              color: 'green'
            })}
          />
        </AutoColliders>
      </RigidBody>
    </T.Group>
  </CollisionGroups>

  <!-- Collider C -->
  <CollisionGroups
    memberships={[3]}
    filter={[2]}
  >
    <T.Group position={[0, 3, 1 - Math.random() * 2]}>
      <RigidBody>
        <AutoColliders shape={'cuboid'}>
          <T.Mesh
            castShadow
            {geometry}
            material={new MeshStandardMaterial({
              color: 'blue'
            })}
          />
        </AutoColliders>
      </RigidBody>
    </T.Group>
  </CollisionGroups>
{/key}

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

<CollisionGroups groups={[1, 2, 3]}>
  <Ground />
</CollisionGroups>
<!-- Collider A -->
<CollisionGroups
  memberships={[1]}
  filter={[2]}
>
  <RigidBody>
    <AutoColliders shape={'cuboid'}>
      <Mesh
        castShadow
        {geometry}
        {material}
      />
    </AutoColliders>
  </RigidBody>
</CollisionGroups>

<!-- Collider B -->
<CollisionGroups
  memberships={[2]}
  filter={[1, 3]}
>
  <RigidBody>
    <AutoColliders shape={'cuboid'}>
      <Mesh
        castShadow
        {geometry}
        {material}
      />
    </AutoColliders>
  </RigidBody>
</CollisionGroups>

<!-- Collider C -->
<CollisionGroups
  memberships={[3]}
  filter={[2]}
>
  <RigidBody>
    <AutoColliders shape={'cuboid'}>
      <Mesh
        castShadow
        {geometry}
        {material}
      />
    </AutoColliders>
  </RigidBody>
</CollisionGroups>

Component Signature

Provide either the shorthand property groups to set both memberships and filter to the same value or set them up individually.

Props

name
type
required

filter
CollisionGroupsBitMask
yes

groups
CollisionGroupsBitMask
yes

memberships
CollisionGroupsBitMask
yes