diff --git a/examples/js/Demo.js b/examples/js/Demo.js
index 77abab8ba..052c3bd2d 100644
--- a/examples/js/Demo.js
+++ b/examples/js/Demo.js
@@ -547,6 +547,7 @@ class Demo extends CANNON.EventTarget {
this.currentMaterial = this.solidMaterial
const contactDotMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff })
this.particleMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 })
+ this.triggerMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true })
const contactPointGeometry = new THREE.SphereGeometry(0.1, 6, 6)
this.contactMeshCache = new GeometryCache(this.scene, () => {
@@ -894,10 +895,9 @@ class Demo extends CANNON.EventTarget {
throw new Error('The argument passed to addVisual() is not a body')
}
- // if it's a particle paint it red, otherwise just gray
- const material = body.shapes.every((s) => s instanceof CANNON.Particle)
- ? this.particleMaterial
- : this.currentMaterial
+ // if it's a particle paint it red, if it's a trigger paint it as green, otherwise just gray
+ const isParticule = body.shapes.every((s) => s instanceof CANNON.Particle)
+ const material = isParticule ? this.particleMaterial : body.isTrigger ? this.triggerMaterial : this.currentMaterial
// get the correspondant three.js mesh
const mesh = bodyToMesh(body, material)
diff --git a/examples/trigger.html b/examples/trigger.html
new file mode 100644
index 000000000..192fc1c46
--- /dev/null
+++ b/examples/trigger.html
@@ -0,0 +1,68 @@
+
+
+
+
+ cannon.js - trigger demo
+
+
+
+
+
+
+
diff --git a/index.html b/index.html
index bf2674c0b..59ffe66d8 100644
--- a/index.html
+++ b/index.html
@@ -153,6 +153,7 @@
'spring',
'stacks',
'tear',
+ 'trigger',
'trimesh',
'tween',
]
diff --git a/readme.md b/readme.md
index 9f224fee5..be3f4d108 100644
--- a/readme.md
+++ b/readme.md
@@ -15,6 +15,7 @@ These minor changes and improvements were also made:
- Added a property `World.hasActiveBodies: boolean` which will be false when all physics bodies are sleeping. This allows for invalidating frames when physics aren't active for increased performance.
- Deprecated properties and methods have been removed.
- The [original cannon.js debugger](https://github.com/schteppe/cannon.js/blob/master/tools/threejs/CannonDebugRenderer.js), which shows the wireframes of each body, has been moved to its own repo [cannon-es-debugger](https://github.com/pmndrs/cannon-es-debugger).
+- Added a property `Body.isTrigger : boolean` which, when true allows for the body to trigger collision events without interacting physically with the other colliding bodies.
If instead you're using three.js in a **React** environment with [react-three-fiber](https://github.com/pmndrs/react-three-fiber), check out [use-cannon](https://github.com/pmndrs/use-cannon)! It's a wrapper around cannon-es.
diff --git a/screenshots/trigger.png b/screenshots/trigger.png
new file mode 100644
index 000000000..95cac91e3
Binary files /dev/null and b/screenshots/trigger.png differ
diff --git a/src/objects/Body.ts b/src/objects/Body.ts
index d630710e9..ed7c2936c 100644
--- a/src/objects/Body.ts
+++ b/src/objects/Body.ts
@@ -9,18 +9,18 @@ import type { Material } from '../material/Material'
import type { World } from '../world/World'
export const BODY_TYPES = {
- DYNAMIC: 1 as const,
- STATIC: 2 as const,
- KINEMATIC: 4 as const,
-}
+ DYNAMIC: 1,
+ STATIC: 2,
+ KINEMATIC: 4,
+} as const
export type BodyType = typeof BODY_TYPES[keyof typeof BODY_TYPES]
export const BODY_SLEEP_STATES = {
- AWAKE: 0 as const,
- SLEEPY: 1 as const,
- SLEEPING: 2 as const,
-}
+ AWAKE: 0,
+ SLEEPY: 1,
+ SLEEPING: 2,
+} as const
export type BodySleepState = typeof BODY_SLEEP_STATES[keyof typeof BODY_SLEEP_STATES]
@@ -44,6 +44,7 @@ export type BodyOptions = {
linearFactor?: Vec3
angularFactor?: Vec3
shape?: Shape
+ isTrigger?: boolean
}
/**
@@ -130,6 +131,7 @@ export class Body extends EventTarget {
aabbNeedsUpdate: boolean // Indicates if the AABB needs to be updated before use.
boundingRadius: number // Total bounding radius of the Body including its shapes, relative to body.position.
wlambda: Vec3
+ isTrigger: boolean // When true "collide" events are still triggered but bodies do not interact.
static idCounter: number
static COLLIDE_EVENT_NAME: 'collide'
@@ -246,6 +248,7 @@ export class Body extends EventTarget {
this.aabbNeedsUpdate = true
this.boundingRadius = 0
this.wlambda = new Vec3()
+ this.isTrigger = Boolean(options.isTrigger)
if (options.shape) {
this.addShape(options.shape)
diff --git a/src/solver/Solver.ts b/src/solver/Solver.ts
index 1d4777f5d..c2455b2c9 100644
--- a/src/solver/Solver.ts
+++ b/src/solver/Solver.ts
@@ -34,7 +34,7 @@ export class Solver {
* @param {Equation} eq
*/
addEquation(eq: Equation): void {
- if (eq.enabled) {
+ if (eq.enabled && !eq.bi.isTrigger && !eq.bj.isTrigger) {
this.equations.push(eq)
}
}