Skip to content

Commit

Permalink
Merge pull request #196 from gkjohnson/remove-lazy-generation
Browse files Browse the repository at this point in the history
Remove lazyGeneration option
  • Loading branch information
gkjohnson authored Mar 2, 2021
2 parents a13662b + 3b15327 commit a813614
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 194 deletions.
12 changes: 1 addition & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const invMat = new THREE.Matrix4();

// ...

const bvh = new MeshBVH( geometry, { lazyGeneration: false } );
const bvh = new MeshBVH( geometry );
invMat.copy( mesh.matrixWorld ).invert();

// raycasting
Expand Down Expand Up @@ -226,16 +226,6 @@ Constructs the bounds tree for the given geometry and produces a new index attri
// Print out warnings encountered during tree construction.
verbose: true,

// If true the bounds tree is generated progressively as the tree is used allowing
// for a fast initialization time and memory allocation as needed but a higher memory
// footprint once the tree is completed. The initial raycasts are also slower until the
// tree is built up.
// If false then the bounds tree will be completely generated up front and packed into
// an array buffer for a lower final memory footprint and long initialization time.
// Note that this will keep intermediate buffers needed for generation in scope until
// the tree has been fully generated.
lazyGeneration: true

}
```

Expand Down
31 changes: 13 additions & 18 deletions benchmark/run-benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@ function logExtremes( bvh, geometry ) {

}

function runSuite( strategy, lazyGeneration = true ) {

const options = { lazyGeneration, strategy };
let preFunc = lazyGeneration ? () => geometry.computeBoundsTree( options ) : null;
function runSuite( strategy ) {

const options = { strategy };
geometry.computeBoundsTree( options );
logExtremes( geometry.boundsTree, geometry );

Expand All @@ -69,7 +67,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'Serialize',
preFunc,
null,
() => {

MeshBVH.serialize( geometry.boundsTree, geometry );
Expand All @@ -84,7 +82,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'Deserialize',
preFunc,
null,
() => {

MeshBVH.deserialize( serialized, geometry );
Expand All @@ -100,7 +98,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'BVH Raycast',
preFunc,
null,
() => mesh.raycast( raycaster, [] ),
3000

Expand All @@ -110,7 +108,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'First Hit Raycast',
preFunc,
null,
() => mesh.raycast( raycaster, [] ),
3000

Expand All @@ -119,7 +117,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'Sphere Shapecast',
preFunc,
null,
() => {

mesh.geometry.boundsTree.shapecast( mesh, box => sphere.intersectsBox( box ), tri => {
Expand All @@ -136,7 +134,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'IntersectsSphere',
preFunc,
null,
() => mesh.geometry.boundsTree.intersectsSphere( mesh, sphere ),
3000

Expand All @@ -145,7 +143,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'IntersectsBox',
preFunc,
null,
() => mesh.geometry.boundsTree.intersectsBox( mesh, box, boxMat ),
3000

Expand All @@ -154,7 +152,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'DistanceToGeometry',
preFunc,
null,
() => mesh.geometry.boundsTree.closestPointToGeometry( mesh, intersectGeometry, geomMat, target1, target2 ),
3000

Expand All @@ -164,7 +162,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'DistanceToPoint',
preFunc,
null,
() => mesh.geometry.boundsTree.closestPointToPoint( mesh, vec, target1 ),
3000

Expand All @@ -176,7 +174,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'IntersectsGeometry with BVH',
preFunc,
null,
() => mesh.geometry.boundsTree.intersectsGeometry( mesh, intersectGeometry, geomMat ),
3000

Expand All @@ -187,7 +185,7 @@ function runSuite( strategy, lazyGeneration = true ) {
runBenchmark(

'IntersectsGeometry without BVH',
preFunc,
null,
() => mesh.geometry.boundsTree.intersectsGeometry( mesh, intersectGeometry, geomMat ),
3000

Expand All @@ -199,9 +197,6 @@ function runSuite( strategy, lazyGeneration = true ) {
console.log( '*Strategy: CENTER*' );
runSuite( CENTER );

console.log( '' );
console.log( '*Strategy: Non-Lazy CENTER*' );
runSuite( CENTER, false );

console.log( '' );
console.log( '*Strategy: AVERAGE*' );
Expand Down
2 changes: 1 addition & 1 deletion scripts/generate-cast-functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import path from 'path';
function replaceUnneededCode( str ) {

str = str.replace(
/if \( [^)]*node.continueGeneration \)(.|\n|\r)*?}[\r|\n]/mg,
/\/\* INSERT_BUFFER_VARS \*\//mg,
match => {

if ( match.indexOf( '/* skip */' ) !== - 1 ) {
Expand Down
28 changes: 4 additions & 24 deletions src/MeshBVH.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,6 @@ export default class MeshBVH {

static serialize( bvh, geometry, copyIndexBuffer = true ) {

function finishTree( node ) {

if ( node.continueGeneration ) {

node.continueGeneration();

}

if ( ! node.count ) {

finishTree( node.left );
finishTree( node.right );

}

}

function countNodes( node ) {

if ( node.count ) {
Expand Down Expand Up @@ -125,7 +108,6 @@ export default class MeshBVH {
for ( let i = 0; i < roots.length; i ++ ) {

const root = roots[ i ];
finishTree( root );
let nodeCount = countNodes( root );

const buffer = new ArrayBuffer( BYTES_PER_NODE * nodeCount );
Expand Down Expand Up @@ -200,12 +182,10 @@ export default class MeshBVH {
maxDepth: 40,
maxLeafTris: 10,
verbose: true,
lazyGeneration: true,

// undocumented options

// whether to the pack the data as a buffer or not. The data
// will not be packed if lazyGeneration is true.
// whether to the pack the data as a buffer or not.
packData: true,

// Whether to skip generating the tree. Used for deserialization.
Expand All @@ -219,7 +199,7 @@ export default class MeshBVH {
if ( ! options[ SKIP_GENERATION ] ) {

this._roots = buildTree( geo, options );
if ( ! options.lazyGeneration && options.packData ) {
if ( options.packData ) {

this._roots = MeshBVH.serialize( this, geo, false ).roots;
this._isPacked = true;
Expand Down Expand Up @@ -254,7 +234,7 @@ export default class MeshBVH {
const left = stride4Offset + BYTES_PER_NODE / 4;
const right = uint32Array[ stride4Offset + 6 ];
const splitAxis = uint32Array[ stride4Offset + 7 ];
const stopTraversal = callback( depth, isLeaf, new Float32Array( buffer, stride4Offset * 4, 6 ), splitAxis, false );
const stopTraversal = callback( depth, isLeaf, new Float32Array( buffer, stride4Offset * 4, 6 ), splitAxis );

if ( ! stopTraversal ) {

Expand All @@ -280,7 +260,7 @@ export default class MeshBVH {

} else {

const stopTraversal = callback( depth, isLeaf, node.boundingData, node.splitAxis, ! ! node.continueGeneration );
const stopTraversal = callback( depth, isLeaf, node.boundingData, node.splitAxis );

if ( ! stopTraversal ) {

Expand Down
6 changes: 3 additions & 3 deletions src/Utils/Debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@ function getRootExtremes( bvh, group ) {
splits: [ 0, 0, 0 ]
};

bvh.traverse( ( depth, isLeaf, boundingData, offsetOrSplit, countOrIsUnfinished ) => {
bvh.traverse( ( depth, isLeaf, boundingData, offsetOrSplit, count ) => {

result.total ++;
if ( isLeaf ) {

result.depth.min = Math.min( depth, result.depth.min );
result.depth.max = Math.max( depth, result.depth.max );

result.tris.min = Math.min( countOrIsUnfinished, result.tris.min );
result.tris.max = Math.max( countOrIsUnfinished, result.tris.max );
result.tris.min = Math.min( count, result.tris.min );
result.tris.max = Math.max( count, result.tris.max );

} else {

Expand Down
39 changes: 4 additions & 35 deletions src/buildFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -552,23 +552,8 @@ export function buildTree( geo, options ) {
node.left = left;
left.boundingData = new Float32Array( 6 );

if ( lazyGeneration ) {

getBounds( triangleBounds, lstart, lcount, left.boundingData );
left.continueGeneration = function () {

delete this.continueGeneration;
getCentroidBounds( triangleBounds, lstart, lcount, cacheCentroidBoundingData );
splitNode( left, lstart, lcount, cacheCentroidBoundingData, depth + 1 );

};

} else {

getBounds( triangleBounds, lstart, lcount, left.boundingData, cacheCentroidBoundingData );
splitNode( left, lstart, lcount, cacheCentroidBoundingData, depth + 1 );

}
getBounds( triangleBounds, lstart, lcount, left.boundingData, cacheCentroidBoundingData );
splitNode( left, lstart, lcount, cacheCentroidBoundingData, depth + 1 );

// repeat for right
const right = new MeshBVHNode();
Expand All @@ -577,23 +562,8 @@ export function buildTree( geo, options ) {
node.right = right;
right.boundingData = new Float32Array( 6 );

if ( lazyGeneration ) {

getBounds( triangleBounds, rstart, rcount, right.boundingData );
right.continueGeneration = function () {

delete this.continueGeneration;
getCentroidBounds( triangleBounds, rstart, rcount, cacheCentroidBoundingData );
splitNode( right, rstart, rcount, cacheCentroidBoundingData, depth + 1 );

};

} else {

getBounds( triangleBounds, rstart, rcount, right.boundingData, cacheCentroidBoundingData );
splitNode( right, rstart, rcount, cacheCentroidBoundingData, depth + 1 );

}
getBounds( triangleBounds, rstart, rcount, right.boundingData, cacheCentroidBoundingData );
splitNode( right, rstart, rcount, cacheCentroidBoundingData, depth + 1 );

}

Expand All @@ -611,7 +581,6 @@ export function buildTree( geo, options ) {
const verbose = options.verbose;
const maxLeafTris = options.maxLeafTris;
const strategy = options.strategy;
const lazyGeneration = options.lazyGeneration;
let reachedMaxDepth = false;

const roots = [];
Expand Down
Loading

0 comments on commit a813614

Please sign in to comment.