Skip to content

Commit

Permalink
Check for frustum containment
Browse files Browse the repository at this point in the history
  • Loading branch information
gkjohnson committed Feb 5, 2025
1 parent 2866b9f commit 6a58034
Showing 1 changed file with 37 additions and 3 deletions.
40 changes: 37 additions & 3 deletions src/r3f/utilities/QueryManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const _line0 = /* @__PURE__ */ new Line3();
const _line1 = /* @__PURE__ */ new Line3();
const _params = /* @__PURE__ */ new Vector2();
const _direction = /* @__PURE__ */ new Vector3();
const _matrix = /* @__PURE__ */ new Matrix4();
export class QueryManager extends EventDispatcher {

constructor() {
Expand Down Expand Up @@ -88,8 +89,9 @@ export class QueryManager extends EventDispatcher {
const start = performance.now();

// Iterate over all cameras
cameras.forEach( camera => {
cameras.forEach( ( camera, c ) => {

_matrix.copy( camera.matrixWorldInverse ).premultiply( camera.projectionMatrix );
_direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );

_line0.start.setFromMatrixPosition( camera.matrixWorld );
Expand All @@ -101,6 +103,8 @@ export class QueryManager extends EventDispatcher {
const { ray } = info;

// save the values for sorting
let distance;
let inFrustum;
if ( info.point === null ) {

// prioritize displaying points that are from rays pointing in the same direction as
Expand All @@ -110,11 +114,37 @@ export class QueryManager extends EventDispatcher {
closestPointLineToLine( _line0, _line1, _params );

info.distance = _params.x * ( 1.0 - Math.abs( _direction.dot( ray.direction ) ) );
info.inFrustum = true;

} else {

// calculate the distance to the last hit point
info.distance = _line1.start.subVectors( info.point, _line0.start ).dot( _direction );
// if the point is within the frustum then prioritize it
const p = _line1.start;
p.copy( info.point ).applyMatrix4( _matrix );
if ( p.x > - 1 && p.x < 1 && p.y > - 1 && p.y < 1 && p.z > - 1 && p.z < 1 ) {

// calculate the distance to the last hit point
info.distance = p.subVectors( info.point, _line0.start ).dot( _direction );
info.inFrustum = true;

} else {

info.distance = 0;
info.inFrustum = false;

}

}

if ( c === 0 ) {

info.distance = distance;
info.inFrustum = inFrustum;

} else {

info.inFrustum = info.inFrustum || inFrustum;
info.distance = Math.min( info.distance, distance );

}

Expand All @@ -131,6 +161,10 @@ export class QueryManager extends EventDispatcher {

return a.point === null ? 1 : - 1;

} else if ( a.inFrustum !== b.inFrustum ) {

return a.inFrustum ? 1 : - 1;

} else if ( ( a.distance < 0 ) !== ( b.distance < 0 ) ) {

return a.distance < 0 ? - 1 : 1;
Expand Down

0 comments on commit 6a58034

Please sign in to comment.