Terrain with Rapier physics
This example shows how to include user-generated random terrain as a fixed <RigidBody>, within a Rapier world.
This is an adaption of Rapier’s own demo (select “Demo: triangle mesh”).
<script lang="ts">
import { Canvas } from '@threlte/core'
import { World } from '@threlte/rapier'
import Scene from './Scene.svelte'
import { Pane, Button } from 'svelte-tweakpane-ui'
let reset: () => any | undefined
let toggleDebug: () => any | undefined
</script>
<Pane
title=""
position="fixed"
>
<Button
title="Reset"
on:click={reset}
/>
<Button
title="Toggle Debug"
on:click={toggleDebug}
/>
</Pane>
<div>
<Canvas>
<World>
<Scene
bind:reset
bind:toggleDebug
/>
</World>
</Canvas>
</div>
<style>
div {
height: 100%;
}
</style>How does it work
- Similar to the 3D noise example, loop over the vertices of a PlaneGeometry, and use a noise map to create a heightfield array
heights. - Attach the heightfield to a rapier
<Collider>
<Collider
shape={'heightfield'}
args={[nsubdivs, nsubdivs, heights, scale]}
/>- Wrap in a fixed
<RigidBody>. We don’t want this terrain to respond to gravity and fall downwards when rapier physics simulation begins.
<RigidBody type={'fixed'}>
<Collider ... />
</RigidBody>- Add some falling random shapes to the scene to prove that the terrain is functioning properly (see “FallingShapes.svelte”)
-
define some shapes in an array
- geometry
<AutoCollider>type- color
-
fill an array of 50 items with a random shape, with a random position and rotation, and loop over it in markup
-
add a
<T.Mesh>to the scene, provide it with the chosen geometry, and a material with the chosen color -
wrap that in an
<AutoColliders>with the chosen AutoCollider -
wrap in a
'dynamic'<RigidBody>. Dynamic because we want these shapes to fall in the scene according to gravity. -
finally, wrap in a
<T.Group>to set our random position and rotation