(sparse + dynamic) 3D spatial representation structure for fast searches in three.js
npm install @brakebein/threeoctreeGeometry was dropped, since it is deprecated and has been removed from three.js core (r125).
BufferGeometry.
THREE.OctreeRaycaster
OctreeRaycaster: consider backface culling with respect to material.side ( FrontSide | BackSide | DoubleSide )
html
`
Usage with npm and ES modules:
`
npm install @brakebein/threeoctree
`
`javascript
import { Octree } from '@brakebein/threeoctree';
const octree = new Octree();
`
$3
`javascript
const octree = new THREE.Octree({
undeferred: false, // optional, default = false, octree will defer insertion until you call octree.update();
depthMax: Infinity, // optional, default = Infinity, infinite depth
objectsThreshold: 8, // optional, default = 8
overlapPct: 0.15, // optional, default = 0.15 (15%), this helps sort objects that overlap nodes
scene: scene // optional, pass scene as parameter only if you wish to visualize octree
});
`
$3
Add mesh as single octree object:
`javascript
octree.add( mesh );
`
Add mesh's faces as octree objects:
`javascript
octree.add( mesh, { useFaces: true } );
`
Add mesh's vertices as octree objects:
`javascript
octree.add( mesh, { useVertices: true } );
`
( note that only vertices OR faces can be used, and useVertices overrides useFaces )
Remove all octree objects associated with a mesh:
`javascript
octree.remove( mesh );
`
$3
When octree.add( object ) is called and octree.undeferred !== true, insertion for that object is deferred until the octree is updated.
Update octree to insert all deferred objects after render cycle to makes sure object matrices are up-to-date.
`javascript
renderer.render( scene, camera );
octree.update();
`
$3
To account for moving objects within the octree:
`javascript
octree.rebuild();
`
$3
Search octree at a position in all directions for radius distance:
`javascript
octree.search( position, radius );
`
Search octree and organize results by object (i.e. all faces/vertices belonging to three object in one list vs a result for each face/vertex):
`javascript
octree.search( position, radius, true );
`
Search octree using a ray:
`javascript
octree.search( ray.origin, ray.far, true, ray.direction );
`
$3
The OctreeRaycaster extends the THREE.Raycaster class by two methods to help use the search results:
intersectOctreeObjects() and intersectOctreeObject().
In most cases you will use only the former:
`javascript
const octreeResults = octree.search( raycaster.ray.origin, raycaster.ray.far, true, raycaster.ray.direction );
const intersections = raycaster.intersectOctreeObjects( octreeResults );
`
If you wish to get an intersection from a user's mouse click, this is easy enough:
`javascript
function onClick ( event ) {
const mouse = new THREE.Vector2(
( event.pageX / window.innerWidth ) * 2 - 1,
-( event.pageY / window.innerHeight ) * 2 + 1
);
// set raycaster
const raycaster = new THREE.OctreeRaycaster();
raycaster.setFromCamera( mouse, camera );
// now search octree and find intersections using method above
const octreeResults = octree.search( raycaster.ray.origin, raycaster.ray.far, true, raycaster.ray.direction );
const intersections = raycaster.intersectOctreeObjects( octreeResults );
// ...
}
`
$3
Make use of generics in TypeScript:
`typescript
import { BoxGeometry, MeshBasicMaterial } from 'three';
import { Octree } from '@brakebein/threeoctree';
const octree = new Octree>();
const mesh = new Mesh( new BoxGeometry(), new MeshBasicMaterial() );
octree.add( mesh );
// ...
const octreeResults = octree.search( position, radius, true );
octreeResults[0].object // -> Mesh
``