diff --git a/example/testToRemove.js b/example/testToRemove.js index afd634147..91cbbefff 100644 --- a/example/testToRemove.js +++ b/example/testToRemove.js @@ -3,11 +3,11 @@ import { computeBoundsTree, SAH } from '../src'; THREE.BufferGeometry.prototype.computeBoundsTree = computeBoundsTree; -const spawnPointRadius = 100; +const spawnPointRadius = 20; const radius = 10; // if radius 100 and tube 0.1 and spawnRadius 100, sort works really good. const tube = 0.1; const segmentsMultiplier = 32; -const sortedListMaxCount = 32; +const maxDepthSorted = 4; const maxLeafTris = 10; const strategy = SAH; @@ -116,7 +116,7 @@ function benchmark() { for ( let i = 0; i < tries; i ++ ) { - bvh.closestPointToPointHybrid( points[ i ], target, sortedListMaxCount ); + bvh.closestPointToPointHybrid( points[ i ], target, maxDepthSorted ); } diff --git a/src/core/cast/closestPointToPointHybrid.template.js b/src/core/cast/closestPointToPointHybrid.template.js index 8606d1bbf..5271954e8 100644 --- a/src/core/cast/closestPointToPointHybrid.template.js +++ b/src/core/cast/closestPointToPointHybrid.template.js @@ -15,7 +15,7 @@ export function closestPointToPointHybrid/* @echo INDIRECT_STRING */( root, point, target, - sortedListMaxCount, + maxDepthSorted, minThreshold, maxThreshold ) { @@ -33,13 +33,26 @@ export function closestPointToPointHybrid/* @echo INDIRECT_STRING */( const { float32Array, uint16Array, uint32Array } = BufferStack; - if ( sortedListMaxCount === 0 ) { + sortedList.clear(); - _closestPointToPoint( 0 ); + if ( maxDepthSorted > 0 ) { + + _fillSortedList( root, 0 ); } else { - _closestPointToPointSorted(); + sortedList.push( { nodeIndex32: root, distance: closestDistanceSquaredPointToBox( root, float32Array, point ) } ); + + } + + const nodes = sortedList.array; + for ( let i = nodes.length - 1; i >= 0; i -- ) { + + const { distance, nodeIndex32 } = nodes[ i ]; + + if ( distance >= closestDistanceSq ) break; + + _closestPointToPoint( nodeIndex32 ); } @@ -57,87 +70,44 @@ export function closestPointToPointHybrid/* @echo INDIRECT_STRING */( return target; - function _closestPointToPointSorted() { - - sortedList.clear(); - let count = 0; - let node = { nodeIndex32: 0, distance: closestDistanceSquaredPointToBox( 0, float32Array, point ) }; - - do { - - const { distance, nodeIndex32 } = node; - - if ( distance >= closestDistanceSq ) return; - - if ( count >= sortedListMaxCount ) { - - if ( _closestPointToPoint( nodeIndex32 ) ) return; - - continue; - - } - - count ++; - - const nodeIndex16 = nodeIndex32 * 2; - const isLeaf = IS_LEAF( nodeIndex16, uint16Array ); - if ( isLeaf ) { - - const offset = OFFSET( nodeIndex32, uint32Array ); - const count = COUNT( nodeIndex16, uint16Array ); - - for ( let i = offset, l = count + offset; i < l; i ++ ) { - - /* @if INDIRECT */ - - const ti = bvh.resolveTriangleIndex( i ); - setTriangle( triangle, 3 * ti, index, pos ); - - /* @else */ + function _fillSortedList( nodeIndex32, depth ) { - setTriangle( triangle, i * 3, index, pos ); - - /* @endif */ - - triangle.needsUpdate = true; - - triangle.closestPointToPoint( point, temp ); - const distSq = point.distanceToSquared( temp ); - if ( distSq < closestDistanceSq ) { - - temp1.copy( temp ); - closestDistanceSq = distSq; - closestDistanceTriIndex = i; - - if ( distSq < minThresholdSq ) return; + const nodeIndex16 = nodeIndex32 * 2; + const isLeaf = IS_LEAF( nodeIndex16, uint16Array ); + if ( isLeaf ) { - } + sortedList.push( { nodeIndex32, distance: closestDistanceSquaredPointToBox( nodeIndex32, float32Array, point ) } ); - } + return; - continue; + } - } + const leftIndex = LEFT_NODE( nodeIndex32 ); + const rightIndex = RIGHT_NODE( nodeIndex32, uint32Array ); - const leftIndex = LEFT_NODE( nodeIndex32 ); - const rightIndex = RIGHT_NODE( nodeIndex32, uint32Array ); + if ( depth === maxDepthSorted ) { const leftDistance = closestDistanceSquaredPointToBox( leftIndex, float32Array, point ); const rightDistance = closestDistanceSquaredPointToBox( rightIndex, float32Array, point ); - if ( leftDistance < closestDistanceSq && leftDistance < maxThresholdSq ) { + if ( leftDistance > rightDistance ) { // leftDistance < maxThresholdSq - consider this? sortedList.push( { nodeIndex32: leftIndex, distance: leftDistance } ); + sortedList.push( { nodeIndex32: rightIndex, distance: rightDistance } ); - } - - if ( rightDistance < closestDistanceSq && rightDistance < maxThresholdSq ) { + } else { sortedList.push( { nodeIndex32: rightIndex, distance: rightDistance } ); + sortedList.push( { nodeIndex32: leftIndex, distance: leftDistance } ); } - } while ( node = sortedList.pop() ); + return; + + } + + _fillSortedList( leftIndex, depth + 1 ); + _fillSortedList( rightIndex, depth + 1 ); } diff --git a/src/core/utils/SortedListDesc.js b/src/core/utils/SortedListDesc.js index 3e4d4e3a2..5ce845a89 100644 --- a/src/core/utils/SortedListDesc.js +++ b/src/core/utils/SortedListDesc.js @@ -8,7 +8,7 @@ export class SortedListDesc { clear() { - this.array = []; + this.array.length = 0; }