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) } }