Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate the use of a stack of array buffers #551

Merged
merged 1 commit into from
Aug 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions src/core/MeshBVH.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import {
raycastFirst,
shapecast,
intersectsGeometry,
setBuffer,
clearBuffer,
} from './castFunctions.js';
import { OrientedBox } from '../math/OrientedBox.js';
import { ExtendedTriangle } from '../math/ExtendedTriangle.js';
import { PrimitivePool } from '../utils/PrimitivePool.js';
import { arrayToBox } from '../utils/ArrayBoxUtilities.js';
import { iterateOverTriangles, setTriangle } from '../utils/TriangleUtilities.js';
import { BufferStack } from './utils/BufferStack.js';

const SKIP_GENERATION = Symbol( 'skip tree generation' );

Expand Down Expand Up @@ -394,9 +393,9 @@ export class MeshBVH {
const materialSide = isArrayMaterial ? materialOrSide[ groups[ i ].materialIndex ].side : side;
const startCount = intersects.length;

setBuffer( roots[ i ] );
BufferStack.setBuffer( roots[ i ] );
raycast( 0, geometry, materialSide, ray, intersects );
clearBuffer();
BufferStack.clearBuffer();

if ( isArrayMaterial ) {

Expand Down Expand Up @@ -430,9 +429,9 @@ export class MeshBVH {

const materialSide = isArrayMaterial ? materialOrSide[ groups[ i ].materialIndex ].side : side;

setBuffer( roots[ i ] );
BufferStack.setBuffer( roots[ i ] );
const result = raycastFirst( 0, geometry, materialSide, ray );
clearBuffer();
BufferStack.clearBuffer();

if ( result != null && ( closestResult == null || result.distance < closestResult.distance ) ) {

Expand All @@ -457,9 +456,9 @@ export class MeshBVH {
let result = false;
for ( const root of this._roots ) {

setBuffer( root );
BufferStack.setBuffer( root );
result = intersectsGeometry( 0, geometry, otherGeometry, geomToMesh );
clearBuffer();
BufferStack.clearBuffer();

if ( result ) {

Expand Down Expand Up @@ -555,9 +554,9 @@ export class MeshBVH {
let byteOffset = 0;
for ( const root of this._roots ) {

setBuffer( root );
BufferStack.setBuffer( root );
result = shapecast( 0, geometry, intersectsBounds, intersectsRange, boundsTraverseOrder, byteOffset );
clearBuffer();
BufferStack.clearBuffer();

if ( result ) {

Expand Down
2 changes: 1 addition & 1 deletion src/core/bvhcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Box3 } from 'three';
import { OrientedBox } from '../math/OrientedBox.js';
import { arrayToBox } from '../utils/ArrayBoxUtilities.js';
import { PrimitivePool } from '../utils/PrimitivePool.js';
import { COUNT, OFFSET, LEFT_NODE, RIGHT_NODE, IS_LEAF, BOUNDING_DATA_INDEX } from './nodeBufferFunctions.js';
import { COUNT, OFFSET, LEFT_NODE, RIGHT_NODE, IS_LEAF, BOUNDING_DATA_INDEX } from './utils/nodeBufferUtils.js';
import { MeshBVH } from './MeshBVH.js';
import { setTriangle } from '../utils/TriangleUtilities.js';
import { ExtendedTriangle } from '../math/ExtendedTriangle.js';
Expand Down
79 changes: 15 additions & 64 deletions src/core/castFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ import { intersectTris, intersectClosestTri } from '../utils/GeometryRayIntersec
import { setTriangle } from '../utils/TriangleUtilities.js';
import { arrayToBox } from '../utils/ArrayBoxUtilities.js';
import { PrimitivePool } from '../utils/PrimitivePool.js';
import { COUNT, OFFSET, LEFT_NODE, RIGHT_NODE, IS_LEAF, BOUNDING_DATA_INDEX, SPLIT_AXIS } from './nodeBufferFunctions.js';
import { COUNT, OFFSET, LEFT_NODE, RIGHT_NODE, IS_LEAF, BOUNDING_DATA_INDEX, SPLIT_AXIS } from './utils/nodeBufferUtils.js';
import { BufferStack } from './utils/BufferStack.js';
import { intersectRay } from './utils/intersectUtils.js';

const boundingBox = new Box3();
const boxIntersection = new Vector3();
const xyzFields = [ 'x', 'y', 'z' ];

export function raycast( nodeIndex32, geometry, side, ray, intersects ) {

let nodeIndex16 = nodeIndex32 * 2,
float32Array = _float32Array,
uint16Array = _uint16Array,
uint32Array = _uint32Array;
const { float32Array, uint16Array, uint32Array } = BufferStack;
let nodeIndex16 = nodeIndex32 * 2;

const isLeaf = IS_LEAF( nodeIndex16, uint16Array );
if ( isLeaf ) {
Expand Down Expand Up @@ -50,10 +50,8 @@ export function raycast( nodeIndex32, geometry, side, ray, intersects ) {

export function raycastFirst( nodeIndex32, geometry, side, ray ) {

let nodeIndex16 = nodeIndex32 * 2,
float32Array = _float32Array,
uint16Array = _uint16Array,
uint32Array = _uint32Array;
const { float32Array, uint16Array, uint32Array } = BufferStack;
let nodeIndex16 = nodeIndex32 * 2;

const isLeaf = IS_LEAF( nodeIndex16, uint16Array );
if ( isLeaf ) {
Expand Down Expand Up @@ -167,10 +165,8 @@ export const shapecast = ( function () {
depth = 0
) {

let nodeIndex16 = nodeIndex32 * 2,
float32Array = _float32Array,
uint16Array = _uint16Array,
uint32Array = _uint32Array;
const { float32Array, uint16Array, uint32Array } = BufferStack;
let nodeIndex16 = nodeIndex32 * 2;

const isLeaf = IS_LEAF( nodeIndex16, uint16Array );
if ( isLeaf ) {
Expand Down Expand Up @@ -296,9 +292,8 @@ export const shapecast = ( function () {
// when converting to the buffer equivalents
function getLeftOffset( nodeIndex32 ) {

let nodeIndex16 = nodeIndex32 * 2,
uint16Array = _uint16Array,
uint32Array = _uint32Array;
const { uint16Array, uint32Array } = BufferStack;
let nodeIndex16 = nodeIndex32 * 2;

// traverse until we find a leaf
while ( ! IS_LEAF( nodeIndex16, uint16Array ) ) {
Expand All @@ -314,9 +309,8 @@ export const shapecast = ( function () {

function getRightEndOffset( nodeIndex32 ) {

let nodeIndex16 = nodeIndex32 * 2,
uint16Array = _uint16Array,
uint32Array = _uint32Array;
const { uint16Array, uint32Array } = BufferStack;
let nodeIndex16 = nodeIndex32 * 2;

// traverse until we find a leaf
while ( ! IS_LEAF( nodeIndex16, uint16Array ) ) {
Expand Down Expand Up @@ -349,10 +343,8 @@ export const intersectsGeometry = ( function () {

return function intersectsGeometry( nodeIndex32, geometry, otherGeometry, geometryToBvh, cachedObb = null ) {

let nodeIndex16 = nodeIndex32 * 2,
float32Array = _float32Array,
uint16Array = _uint16Array,
uint32Array = _uint32Array;
const { float32Array, uint16Array, uint32Array } = BufferStack;
let nodeIndex16 = nodeIndex32 * 2;

if ( cachedObb === null ) {

Expand Down Expand Up @@ -478,44 +470,3 @@ export const intersectsGeometry = ( function () {

} )();

function intersectRay( nodeIndex32, array, ray, target ) {

arrayToBox( nodeIndex32, array, boundingBox );
return ray.intersectBox( boundingBox, target );

}

const bufferStack = [];
let _prevBuffer;
let _float32Array;
let _uint16Array;
let _uint32Array;
export function setBuffer( buffer ) {

if ( _prevBuffer ) {

bufferStack.push( _prevBuffer );

}

_prevBuffer = buffer;
_float32Array = new Float32Array( buffer );
_uint16Array = new Uint16Array( buffer );
_uint32Array = new Uint32Array( buffer );

}

export function clearBuffer() {

_prevBuffer = null;
_float32Array = null;
_uint16Array = null;
_uint32Array = null;

if ( bufferStack.length ) {

setBuffer( bufferStack.pop() );

}

}
45 changes: 45 additions & 0 deletions src/core/utils/BufferStack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class _BufferStack {

constructor() {

this.float32Array = null;
this.uint16Array = null;
this.uint32Array = null;

const stack = [];
let prevBuffer = null;
this.setBuffer = buffer => {

if ( prevBuffer ) {

stack.push( prevBuffer );

}

prevBuffer = buffer;
this.float32Array = new Float32Array( buffer );
this.uint16Array = new Uint16Array( buffer );
this.uint32Array = new Uint32Array( buffer );

};

this.clearBuffer = () => {

prevBuffer = null;
this.float32Array = null;
this.uint16Array = null;
this.uint32Array = null;

if ( stack.length !== 0 ) {

this.setBuffer( stack.pop() );

}

};

}

}

export const BufferStack = new _BufferStack();
10 changes: 10 additions & 0 deletions src/core/utils/intersectUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Box3 } from 'three';
import { arrayToBox } from '../../utils/ArrayBoxUtilities.js';

const _boundingBox = /* @__PURE__ */ new Box3();
export function intersectRay( nodeIndex32, array, ray, target ) {

arrayToBox( nodeIndex32, array, _boundingBox );
return ray.intersectBox( _boundingBox, target );

}
File renamed without changes.
2 changes: 1 addition & 1 deletion src/gpu/MeshBVHUniformStruct.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
RIGHT_NODE,
OFFSET,
SPLIT_AXIS,
} from '../core/nodeBufferFunctions.js';
} from '../core/utils/nodeBufferUtils.js';

function bvhToTextures( bvh, boundsTexture, contentsTexture ) {

Expand Down
Loading