BVHVolumeConstraint

@three-blocks/coreWebGPUPhysicsBVH
new BVHVolumeConstraint(options : Object)

BVHVolumeConstraint - Direct BVH boundary constraint for particle simulations.

Unlike SDFVolumeConstraint which requires SDF precomputation, this class queries the BVH directly each frame. Best for dynamic meshes or when SDF resolution would be prohibitively high.

Supports two modes:

  • 'triangles' (default): For triangle meshes, uses signed distance for inside/outside detection
  • 'points': For point clouds (like Gaussian Splat centers), uses pointRadius shell around each point
Constructor Parameters
optionsObject
Configuration options
  • geometryTHREE.BufferGeometry
    Source geometry with BVH
  • bvhoptional*
    BVH from three-mesh-bvh (auto-retrieved from geometry.boundsTree if not provided)
  • modeoptionalstring
    Mode: 'triangles' for meshes, 'points' for point clouds
    Default is 'triangles'.
  • stiffnessoptionalnumber
    Boundary stiffness
    Default is 1000.0.
  • dampingoptionalnumber
    Velocity damping
    Default is 0.5.
  • thresholdoptionalnumber
    Distance threshold for triangles mode (positive = offset from surface)
    Default is 0.0.
  • pointRadiusoptionalnumber
    Shell radius for points mode
    Default is 0.5.
  • maxSearchDistanceoptionalnumber
    Maximum BVH search distance
    Default is 10.0.
  • containmentoptionalboolean
    For triangles mode: if true, keep particles INSIDE; if false, push OUT
    Default is false.
  • worldMatrixoptionalTHREE.Matrix4
    World transformation matrix for the mesh
Example
import { BVHVolumeConstraint } from '@three-blocks/core';
import { computeBoundsTree } from 'three-mesh-bvh';

// Triangle mesh constraint (containment)
geometry.computeBoundsTree();
const containerConstraint = new BVHVolumeConstraint({
  geometry,
  mode: 'triangles',
  stiffness: 1000,
  containment: true // Keep particles inside
});

// Point cloud constraint (collision with Gaussian Splats)
pointsGeometry.computeBoundsTree();
const splatsConstraint = new BVHVolumeConstraint({
  geometry: pointsGeometry,
  mode: 'points',
  pointRadius: 0.5, // Shell thickness around each point
  stiffness: 1000,
});

// In simulation loop
await containerConstraint.apply(renderer, positionsBuffer, velocitiesBuffer, particleCount);
await splatsConstraint.apply(renderer, positionsBuffer, velocitiesBuffer, particleCount);

Properties

.geometry : THREE.BufferGeometry

.bvh : *

.mode : string

.stiffness : number

.damping : number

.threshold : number

.pointRadius : number

.maxSearchDistance : number

.containment : boolean

.boundsMatrix : THREE.Matrix4

.inverseBoundsMatrix : THREE.Matrix4

Methods

setWorldMatrix#

setWorldMatrix(matrix : THREE.Matrix4)

Sets the world transformation matrix for the BVH mesh.

Parameters
matrixTHREE.Matrix4
World transformation matrix

apply#

apply(renderer : THREE.WebGPURenderer, positionsBuffer : THREE.StorageBufferAttribute, velocitiesBuffer : THREE.StorageBufferAttribute, particleCount : number) : Promise<void>

Applies the BVH boundary constraint to particle buffers.

Parameters
rendererTHREE.WebGPURenderer
WebGPU renderer
positionsBufferTHREE.StorageBufferAttribute
Particle positions
velocitiesBufferTHREE.StorageBufferAttribute
Particle velocities
particleCountnumber
Number of particles
Returns
Promise<void>

updateBVH#

updateBVH(geometry : THREE.BufferGeometry, bvh : *)

Updates the BVH data (for dynamic meshes).

Parameters
geometryTHREE.BufferGeometry
Updated geometry
bvhoptional*
Updated BVH (auto-retrieved from geometry.boundsTree if not provided)
Default is null.

dispose#

dispose()

Disposes GPU resources.