@@ -9,35 +9,37 @@ import {
9
9
Intersection as ThreeIntersection ,
10
10
Object3D ,
11
11
} from 'three'
12
- import { computeIntersectionWorldPlane , getDominantIntersectionIndex , voidObjectIntersectionFromRay } from './utils.js'
12
+ import {
13
+ computeIntersectionWorldPlane ,
14
+ getDominantIntersectionIndex ,
15
+ pushTimes ,
16
+ voidObjectIntersectionFromRay ,
17
+ } from './utils.js'
13
18
import type { PointerCapture } from '../pointer.js'
14
19
import { Intersector } from './intersector.js'
15
20
import { Intersection , IntersectionOptions } from '../index.js'
16
21
import { updateAndCheckWorldTransformation } from '../utils.js'
17
22
18
23
const invertedMatrixHelper = new Matrix4 ( )
19
- const intersectsHelper : Array < ThreeIntersection & { details : { distanceOnLine : number ; lineIndex : number } } > = [ ]
20
24
const lineHelper = new Line3 ( )
21
25
const planeHelper = new Plane ( )
22
26
const rayHelper = new Ray ( )
23
27
const defaultLinePoints = [ new Vector3 ( 0 , 0 , 0 ) , new Vector3 ( 0 , 0 , 1 ) ]
24
28
25
- export class LinesIntersector extends Intersector {
29
+ export class LinesIntersector implements Intersector {
26
30
private raycasters : Array < Raycaster > = [ ]
27
31
private fromMatrixWorld = new Matrix4 ( )
28
32
29
- //state
30
- private intersectionLineIndex : number = 0
31
- private intersectionDistanceOnLine : number = 0
32
-
33
33
private ready ?: boolean
34
34
35
+ private intersects : Array < ThreeIntersection > = [ ]
36
+ private readonly pointerEventsOrders : Array < number | undefined > = [ ]
37
+ private readonly raycasterIndices : Array < number > = [ ]
38
+
35
39
constructor (
36
40
private readonly space : { current ?: Object3D | null } ,
37
41
private readonly options : IntersectionOptions & { linePoints ?: Array < Vector3 > ; minDistance ?: number } ,
38
- ) {
39
- super ( )
40
- }
42
+ ) { }
41
43
42
44
public isReady ( ) : boolean {
43
45
return this . ready ?? this . prepareTransformation ( )
@@ -81,7 +83,7 @@ export class LinesIntersector extends Intersector {
81
83
}
82
84
}
83
85
84
- protected prepareIntersection ( ) : void {
86
+ startIntersection ( ) : void {
85
87
if ( ! this . prepareTransformation ( ) ) {
86
88
return
87
89
}
@@ -110,37 +112,29 @@ export class LinesIntersector extends Intersector {
110
112
if ( ! this . isReady ( ) ) {
111
113
return
112
114
}
113
- let lineLengthSum = 0
115
+ const startOuter = this . intersects . length
114
116
const length = this . raycasters . length
115
- //TODO: optimize - we only need to intersect with raycasters before or equal to the raycaster that did the current intersection
116
117
for ( let i = 0 ; i < length ; i ++ ) {
117
118
const raycaster = this . raycasters [ i ]
118
- object . raycast ( raycaster , intersectsHelper )
119
- for ( const intersection of intersectsHelper ) {
120
- intersection . distance += lineLengthSum
121
- }
122
- const index = getDominantIntersectionIndex (
123
- this . intersection ,
124
- this . pointerEventsOrder ,
125
- intersectsHelper ,
126
- objectPointerEventsOrder ,
127
- this . options ,
128
- )
129
- if ( index != null ) {
130
- this . intersection = intersectsHelper [ index ]
131
- this . intersectionLineIndex = i
132
- this . intersectionDistanceOnLine = this . intersection . distance - raycaster . far
133
- this . pointerEventsOrder = objectPointerEventsOrder
134
- }
135
- intersectsHelper . length = 0
136
- lineLengthSum += raycaster . far
119
+ const startInner = this . intersects . length
120
+ object . raycast ( raycaster , this . intersects )
121
+ pushTimes ( this . raycasterIndices , i , this . intersects . length - startInner )
137
122
}
123
+ pushTimes ( this . pointerEventsOrders , objectPointerEventsOrder , this . intersects . length - startOuter )
138
124
}
139
125
140
126
public finalizeIntersection ( scene : Object3D ) : Intersection {
141
127
const pointerPosition = new Vector3 ( ) . setFromMatrixPosition ( this . fromMatrixWorld )
142
128
const pointerQuaternion = new Quaternion ( ) . setFromRotationMatrix ( this . fromMatrixWorld )
143
- if ( this . intersection == null ) {
129
+
130
+ const index = getDominantIntersectionIndex ( this . intersects , this . pointerEventsOrders , this . options )
131
+ const intersection = index == null ? undefined : this . intersects [ index ]
132
+ const raycasterIndex = index == null ? undefined : this . raycasterIndices [ index ]
133
+ this . intersects . length = 0
134
+ this . raycasterIndices . length = 0
135
+ this . pointerEventsOrders . length = 0
136
+
137
+ if ( intersection == null || raycasterIndex == null ) {
144
138
const lastRaycasterIndex = this . raycasters . length - 1
145
139
const prevDistance = this . raycasters . reduce (
146
140
( prev , caster , i ) => ( i === lastRaycasterIndex ? prev : prev + caster . far ) ,
@@ -160,19 +154,26 @@ export class LinesIntersector extends Intersector {
160
154
prevDistance ,
161
155
)
162
156
}
157
+
158
+ let distance = intersection . distance
159
+ for ( let i = 0 ; i < raycasterIndex ; i ++ ) {
160
+ distance += this . raycasters [ i ] . far
161
+ }
162
+
163
163
//TODO: consider maxLength
164
- return Object . assign ( this . intersection , {
164
+ return Object . assign ( intersection , {
165
165
details : {
166
- lineIndex : this . intersectionLineIndex ,
167
- distanceOnLine : this . intersectionDistanceOnLine ,
166
+ lineIndex : raycasterIndex ,
167
+ distanceOnLine : intersection . distance ,
168
168
type : 'lines' as const ,
169
169
} ,
170
+ distance,
170
171
pointerPosition,
171
172
pointerQuaternion,
172
- pointOnFace : this . intersection . point ,
173
- localPoint : this . intersection . point
173
+ pointOnFace : intersection . point ,
174
+ localPoint : intersection . point
174
175
. clone ( )
175
- . applyMatrix4 ( invertedMatrixHelper . copy ( this . intersection . object . matrixWorld ) . invert ( ) ) ,
176
+ . applyMatrix4 ( invertedMatrixHelper . copy ( intersection . object . matrixWorld ) . invert ( ) ) ,
176
177
} )
177
178
}
178
179
}
0 commit comments