/
Raycaster.js
110 lines (63 loc) · 2.18 KB
/
Raycaster.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { Ray } from '../math/Ray.js';
import { Layers } from './Layers.js';
class Raycaster {
constructor( origin, direction, near = 0, far = Infinity ) {
this.ray = new Ray( origin, direction );
// direction is assumed to be normalized (for accurate distance calculations)
this.near = near;
this.far = far;
this.camera = null;
this.layers = new Layers();
this.params = {
Mesh: {},
Line: { threshold: 1 },
LOD: {},
Points: { threshold: 1 },
Sprite: {}
};
}
set( origin, direction ) {
// direction is assumed to be normalized (for accurate distance calculations)
this.ray.set( origin, direction );
}
setFromCamera( coords, camera ) {
if ( camera.isPerspectiveCamera ) {
this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
this.camera = camera;
} 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
this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
this.camera = camera;
} else {
console.error( 'THREE.Raycaster: Unsupported camera type: ' + camera.type );
}
}
intersectObject( object, recursive = true, intersects = [] ) {
intersectObject( object, this, intersects, recursive );
intersects.sort( ascSort );
return intersects;
}
intersectObjects( objects, recursive = true, intersects = [] ) {
for ( let i = 0, l = objects.length; i < l; i ++ ) {
intersectObject( objects[ i ], this, intersects, recursive );
}
intersects.sort( ascSort );
return intersects;
}
}
function ascSort( a, b ) {
return a.distance - b.distance;
}
function intersectObject( object, raycaster, intersects, recursive ) {
if ( object.layers.test( raycaster.layers ) ) {
object.raycast( raycaster, intersects );
}
if ( recursive === true ) {
const children = object.children;
for ( let i = 0, l = children.length; i < l; i ++ ) {
intersectObject( children[ i ], raycaster, intersects, true );
}
}
}
export { Raycaster };