Skip to content
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: 18 additions & 1 deletion src/core/Raycaster.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Matrix4 } from '../math/Matrix4.js';
import { Ray } from '../math/Ray.js';
import { Layers } from './Layers.js';
import { error } from '../utils.js';
import { WebGPUCoordinateSystem } from '../constants.js';

const _matrix = /*@__PURE__*/ new Matrix4();

Expand Down Expand Up @@ -126,7 +127,23 @@ class Raycaster {

} else if ( camera.isOrthographicCamera ) {

this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera
let coordsZ;

if ( camera.reversedDepth ) {

coordsZ = camera.far / ( camera.far - camera.near );

} else if ( camera.coordinateSystem === WebGPUCoordinateSystem ) {

coordsZ = camera.near / ( camera.near - camera.far );

} else {

coordsZ = ( camera.near + camera.far ) / ( camera.near - camera.far );

}

this.ray.origin.set( coords.x, coords.y, coordsZ ).unproject( camera ); // set origin in plane of camera
this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
this.camera = camera;

Expand Down
101 changes: 101 additions & 0 deletions test/unit/src/core/Raycaster.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Line } from '../../../../src/objects/Line.js';
import { Points } from '../../../../src/objects/Points.js';
import { PerspectiveCamera } from '../../../../src/cameras/PerspectiveCamera.js';
import { OrthographicCamera } from '../../../../src/cameras/OrthographicCamera.js';
import { WebGPUCoordinateSystem } from '../../../../src/constants.js';

function checkRayDirectionAgainstReferenceVector( rayDirection, refVector, assert ) {

Expand Down Expand Up @@ -190,6 +191,106 @@ export default QUnit.module( 'Core', () => {

} );

QUnit.test( 'intersectObject (Perspective, WebGPU coordinate system)', ( assert ) => {

const camera = new PerspectiveCamera( 90, 1, 0.1, 100 );
camera.coordinateSystem = WebGPUCoordinateSystem;
camera.updateProjectionMatrix();

const front = getSphere();
front.position.set( 0, 0, - 5 );
front.updateMatrixWorld();

const behind = getSphere();
behind.position.set( 0, 0, 5 );
behind.updateMatrixWorld();

const raycaster = new Raycaster();
raycaster.setFromCamera( { x: 0, y: 0 }, camera );

assert.strictEqual( raycaster.intersectObject( front ).length, 1,
'Sphere in front of the perspective camera is intersected under WebGPU coordinate system.' );

assert.strictEqual( raycaster.intersectObject( behind ).length, 0,
'Sphere behind the perspective camera is not intersected under WebGPU coordinate system.' );

} );

QUnit.test( 'intersectObject (Orthographic, WebGPU coordinate system)', ( assert ) => {

const camera = new OrthographicCamera( - 1, 1, 1, - 1, 0.1, 10 );
camera.coordinateSystem = WebGPUCoordinateSystem;
camera.updateProjectionMatrix();

const front = getSphere();
front.position.set( 0, 0, - 5 );
front.updateMatrixWorld();

const behind = getSphere();
behind.position.set( 0, 0, 5 );
behind.updateMatrixWorld();

const raycaster = new Raycaster();
raycaster.setFromCamera( { x: 0, y: 0 }, camera );

assert.strictEqual( raycaster.intersectObject( front ).length, 1,
'Sphere in front of the orthographic camera is intersected under WebGPU coordinate system.' );

assert.strictEqual( raycaster.intersectObject( behind ).length, 0,
'Sphere behind the orthographic camera is not intersected under WebGPU coordinate system.' );

} );

QUnit.test( 'intersectObject (Perspective, reversed depth)', ( assert ) => {

const camera = new PerspectiveCamera( 90, 1, 0.1, 100 );
camera._reversedDepth = true;
camera.updateProjectionMatrix();

const front = getSphere();
front.position.set( 0, 0, - 5 );
front.updateMatrixWorld();

const behind = getSphere();
behind.position.set( 0, 0, 5 );
behind.updateMatrixWorld();

const raycaster = new Raycaster();
raycaster.setFromCamera( { x: 0, y: 0 }, camera );

assert.strictEqual( raycaster.intersectObject( front ).length, 1,
'Sphere in front of the perspective camera is intersected with reversed depth.' );

assert.strictEqual( raycaster.intersectObject( behind ).length, 0,
'Sphere behind the perspective camera is not intersected with reversed depth.' );

} );

QUnit.test( 'intersectObject (Orthographic, reversed depth)', ( assert ) => {

const camera = new OrthographicCamera( - 1, 1, 1, - 1, 0.1, 10 );
camera._reversedDepth = true;
camera.updateProjectionMatrix();

const front = getSphere();
front.position.set( 0, 0, - 5 );
front.updateMatrixWorld();

const behind = getSphere();
behind.position.set( 0, 0, 5 );
behind.updateMatrixWorld();

const raycaster = new Raycaster();
raycaster.setFromCamera( { x: 0, y: 0 }, camera );

assert.strictEqual( raycaster.intersectObject( front ).length, 1,
'Sphere in front of the orthographic camera is intersected with reversed depth.' );

assert.strictEqual( raycaster.intersectObject( behind ).length, 0,
'Sphere behind the orthographic camera is not intersected with reversed depth.' );

} );

QUnit.test( 'Line intersection threshold', ( assert ) => {

const raycaster = getRaycaster();
Expand Down