Skip to content
🎉 Angular Three v4 is here! Read the announcement

Colliders

Colliders define the physical shape of objects for collision detection. By default, rigid bodies auto-generate colliders from child meshes, but you can also define explicit colliders.

Rigid bodies automatically create colliders based on their child mesh geometries:

<ngt-object3D rigidBody>
<!-- Collider auto-generated from box geometry -->
<ngt-mesh>
<ngt-box-geometry />
<ngt-mesh-standard-material />
</ngt-mesh>
</ngt-object3D>

Control the auto-collider type via the colliders option:

<!-- Use ball colliders -->
<ngt-object3D rigidBody [options]="{ colliders: 'ball' }">
<ngt-mesh>
<ngt-sphere-geometry />
</ngt-mesh>
</ngt-object3D>

Disable auto-colliders to define manual colliders:

<ngt-object3D rigidBody [options]="{ colliders: false }">
<!-- Manual colliders only -->
<ngt-object3D [ballCollider]="[0.5]" />
</ngt-object3D>

Creates a spherical collider:

<ngt-object3D [ballCollider]="[radius]" [position]="[0, 2, 0]" />
ArgumentTypeDescription
radiusnumberRadius of the sphere

Creates a box collider with half-extents:

<ngt-object3D [cuboidCollider]="[halfWidth, halfHeight, halfDepth]" [position]="[0, 0, 0]" />
ArgumentTypeDescription
halfWidthnumberHalf-extent along X axis
halfHeightnumberHalf-extent along Y axis
halfDepthnumberHalf-extent along Z axis

Creates a capsule collider:

<ngt-object3D [capsuleCollider]="[halfHeight, radius]" [position]="[0, 1, 0]" />
ArgumentTypeDescription
halfHeightnumberHalf the height of the cylindrical part
radiusnumberRadius of the capsule

Creates a cylinder collider:

<ngt-object3D [cylinderCollider]="[halfHeight, radius]" />
ArgumentTypeDescription
halfHeightnumberHalf the height of the cylinder
radiusnumberRadius of the cylinder

Creates a cone collider:

<ngt-object3D [coneCollider]="[halfHeight, radius]" />
ArgumentTypeDescription
halfHeightnumberHalf the height of the cone
radiusnumberBase radius of the cone

Creates a convex hull from vertices:

<ngt-object3D [convexHullCollider]="[vertices]" />
ArgumentTypeDescription
verticesArrayLike<number>Flat array of vertex positions (x, y, z, …)

Creates a triangle mesh collider for exact collision shapes:

<ngt-object3D [trimeshCollider]="[vertices, indices]" />
ArgumentTypeDescription
verticesArrayLike<number>Flat array of vertex positions
indicesArrayLike<number>Triangle indices

Creates a heightfield for terrain-like surfaces:

<ngt-object3D [heightfieldCollider]="[rows, cols, heights, scale]" />
ArgumentTypeDescription
rowsnumberNumber of rows in the height grid
colsnumberNumber of columns
heightsnumber[]Array of height values
scale{ x, y, z }Scale factor for dimensions

Rounded variants provide smoother collision response:

<ngt-object3D [roundCuboidCollider]="[halfW, halfH, halfD, borderRadius]" />
<ngt-object3D [roundCylinderCollider]="[halfHeight, radius, borderRadius]" />
<ngt-object3D [roundConeCollider]="[halfHeight, radius, borderRadius]" />
<ngt-object3D [convexMeshCollider]="[vertices, indices]" />
<ngt-object3D [roundConvexHullCollider]="[vertices, indices, borderRadius]" />
<ngt-object3D [roundConvexMeshCollider]="[vertices, indices, borderRadius]" />
<ngt-object3D [polylineCollider]="[vertices, indices]" />

Generate colliders from mesh geometry when you need different collider types for parts of a complex object:

<ngt-object3D rigidBody [options]="{ colliders: false }">
<ngt-object3D [meshCollider]="'trimesh'">
<ngt-mesh>
<ngt-torus-geometry />
<ngt-mesh-standard-material />
</ngt-mesh>
</ngt-object3D>
</ngt-object3D>

Mesh collider types:

TypeDescription
'cuboid'Box from bounding box
'ball'Sphere from bounding sphere
'hull'Convex hull from vertices
'trimesh'Exact triangle mesh

All colliders accept an options input for physics properties:

<ngt-object3D
[ballCollider]="[0.5]"
[options]="{
friction: 0.5,
restitution: 0.8,
density: 1.0,
sensor: false
}"
/>
OptionTypeDefaultDescription
frictionnumberundefinedFriction coefficient (0 = no friction)
frictionCombineRuleCoefficientCombineRuleundefinedHow friction combines between bodies
restitutionnumberundefinedBounciness (0 = no bounce, 1 = perfect bounce)
restitutionCombineRuleCoefficientCombineRuleundefinedHow restitution combines
densitynumberundefinedUniform density for mass calculation
massnumberundefinedDirect mass value
massPropertiesobjectundefinedFull mass properties
sensorbooleanfalseMake this a sensor (no physical collision)
collisionGroupsInteractionGroupsundefinedCollision group bitmask
solverGroupsInteractionGroupsundefinedSolver group bitmask
activeCollisionTypesActiveCollisionTypesundefinedActive collision types
contactSkinnumber0Contact skin width

Sensors detect intersections without causing physical collision:

<ngt-object3D
[ballCollider]="[2]"
[options]="{ sensor: true }"
(intersectionEnter)="onEnterZone($event)"
(intersectionExit)="onExitZone($event)"
/>

Colliders can emit physics events:

<ngt-object3D
[cuboidCollider]="[1, 1, 1]"
(collisionEnter)="onCollisionEnter($event)"
(collisionExit)="onCollisionExit($event)"
(intersectionEnter)="onIntersectionEnter($event)"
(intersectionExit)="onIntersectionExit($event)"
(contactForce)="onContactForce($event)"
/>

Export the directive to access the underlying Rapier collider:

<ngt-object3D [ballCollider]="[0.5]" #col="ballCollider" />
@Component({...})
export class MyComponent {
col = viewChild.required<NgtrBallCollider>('col');
getCollider() {
return this.col().collider();
}
}
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { NgtArgs } from 'angular-three';
import { NgtrPhysics, NgtrRigidBody, NgtrBallCollider, NgtrCuboidCollider } from 'angular-three-rapier';
@Component({
template: `
<ngtr-physics>
<ng-template>
<!-- Compound collider -->
<ngt-object3D rigidBody [options]="{ colliders: false }">
<ngt-object3D [cuboidCollider]="[0.5, 0.5, 0.5]" [position]="[0, 0, 0]" />
<ngt-object3D [ballCollider]="[0.5]" [position]="[1, 0, 0]" />
<ngt-mesh>
<ngt-box-geometry />
<ngt-mesh-standard-material />
</ngt-mesh>
</ngt-object3D>
<!-- Sensor zone -->
<ngt-object3D [ballCollider]="[5]" [options]="{ sensor: true }" (intersectionEnter)="onEnter($event)" />
</ng-template>
</ngtr-physics>
`,
imports: [NgtrPhysics, NgtrRigidBody, NgtrBallCollider, NgtrCuboidCollider],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class ColliderExample {
onEnter(event: any) {
console.log('Object entered sensor zone', event);
}
}