zincjs 2.3.0 → 2.3.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/zinc.js +268 -71
- package/build/zinc.js.map +1 -1
- package/package.json +2 -2
- package/src/loaders/niftiReader.js +1 -1
- package/src/minimap.js +2 -2
- package/src/primitives/augmentShader.js +39 -22
- package/src/primitives/geometry.js +24 -29
- package/src/primitives/glyphset.js +2 -2
- package/src/primitives/lines.js +4 -2
- package/src/primitives/marker.js +4 -5
- package/src/primitives/markerCluster.js +8 -8
- package/src/primitives/pointset.js +7 -2
- package/src/primitives/zincObject.js +0 -1
- package/src/region.js +0 -2
- package/src/renderer.js +6 -1
- package/src/scene.js +1 -3
- package/src/sceneLoader.js +10 -6
- package/src/texture/textureArray.js +1 -1
- package/src/three/Geometry.js +45 -34
- package/src/three/Loader.js +1 -0
- package/src/three/line/Line.js +2 -2
- package/src/three/line/LineMaterial.js +432 -212
- package/src/three/line/LineSegments2.js +299 -151
- package/src/three/line/LineSegmentsGeometry.js +68 -20
- package/src/utilities.js +63 -3
- package/src/videoHandler.js +4 -1
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
import { LineSegmentsGeometry } from './LineSegmentsGeometry.js';
|
|
14
14
|
import { LineMaterial } from './LineMaterial.js';
|
|
15
15
|
|
|
16
|
+
const _viewport = new Vector4();
|
|
17
|
+
|
|
16
18
|
const _start = new Vector3();
|
|
17
19
|
const _end = new Vector3();
|
|
18
20
|
|
|
@@ -29,20 +31,259 @@ const _box = new Box3();
|
|
|
29
31
|
const _sphere = new Sphere();
|
|
30
32
|
const _clipToWorldVector = new Vector4();
|
|
31
33
|
|
|
34
|
+
let _ray, _lineWidth;
|
|
35
|
+
|
|
36
|
+
// Returns the margin required to expand by in world space given the distance from the camera,
|
|
37
|
+
// line width, resolution, and camera projection
|
|
38
|
+
function getWorldSpaceHalfWidth( camera, distance, resolution ) {
|
|
39
|
+
|
|
40
|
+
// transform into clip space, adjust the x and y values by the pixel width offset, then
|
|
41
|
+
// transform back into world space to get world offset. Note clip space is [-1, 1] so full
|
|
42
|
+
// width does not need to be halved.
|
|
43
|
+
_clipToWorldVector.set( 0, 0, - distance, 1.0 ).applyMatrix4( camera.projectionMatrix );
|
|
44
|
+
_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
|
|
45
|
+
_clipToWorldVector.x = _lineWidth / resolution.width;
|
|
46
|
+
_clipToWorldVector.y = _lineWidth / resolution.height;
|
|
47
|
+
_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
|
|
48
|
+
_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
|
|
49
|
+
|
|
50
|
+
return Math.abs( Math.max( _clipToWorldVector.x, _clipToWorldVector.y ) );
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function raycastWorldUnits( lineSegments, intersects ) {
|
|
55
|
+
|
|
56
|
+
const matrixWorld = lineSegments.matrixWorld;
|
|
57
|
+
const geometry = lineSegments.geometry;
|
|
58
|
+
const instanceStart = geometry.attributes.instanceStart;
|
|
59
|
+
const instanceEnd = geometry.attributes.instanceEnd;
|
|
60
|
+
const segmentCount = Math.min( geometry.instanceCount, instanceStart.count );
|
|
61
|
+
|
|
62
|
+
for ( let i = 0, l = segmentCount; i < l; i ++ ) {
|
|
63
|
+
|
|
64
|
+
_line.start.fromBufferAttribute( instanceStart, i );
|
|
65
|
+
_line.end.fromBufferAttribute( instanceEnd, i );
|
|
66
|
+
|
|
67
|
+
_line.applyMatrix4( matrixWorld );
|
|
68
|
+
|
|
69
|
+
const pointOnLine = new Vector3();
|
|
70
|
+
const point = new Vector3();
|
|
71
|
+
|
|
72
|
+
_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
|
|
73
|
+
const isInside = point.distanceTo( pointOnLine ) < _lineWidth * 0.5;
|
|
74
|
+
|
|
75
|
+
if ( isInside ) {
|
|
76
|
+
|
|
77
|
+
intersects.push( {
|
|
78
|
+
point,
|
|
79
|
+
pointOnLine,
|
|
80
|
+
distance: _ray.origin.distanceTo( point ),
|
|
81
|
+
object: lineSegments,
|
|
82
|
+
face: null,
|
|
83
|
+
faceIndex: i,
|
|
84
|
+
uv: null,
|
|
85
|
+
uv1: null,
|
|
86
|
+
} );
|
|
87
|
+
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function raycastScreenSpace( lineSegments, camera, intersects ) {
|
|
95
|
+
|
|
96
|
+
const projectionMatrix = camera.projectionMatrix;
|
|
97
|
+
const material = lineSegments.material;
|
|
98
|
+
const resolution = material.resolution;
|
|
99
|
+
const matrixWorld = lineSegments.matrixWorld;
|
|
100
|
+
|
|
101
|
+
const geometry = lineSegments.geometry;
|
|
102
|
+
const instanceStart = geometry.attributes.instanceStart;
|
|
103
|
+
const instanceEnd = geometry.attributes.instanceEnd;
|
|
104
|
+
const segmentCount = Math.min( geometry.instanceCount, instanceStart.count );
|
|
105
|
+
|
|
106
|
+
const near = - camera.near;
|
|
107
|
+
|
|
108
|
+
//
|
|
109
|
+
|
|
110
|
+
// pick a point 1 unit out along the ray to avoid the ray origin
|
|
111
|
+
// sitting at the camera origin which will cause "w" to be 0 when
|
|
112
|
+
// applying the projection matrix.
|
|
113
|
+
_ray.at( 1, _ssOrigin );
|
|
114
|
+
|
|
115
|
+
// ndc space [ - 1.0, 1.0 ]
|
|
116
|
+
_ssOrigin.w = 1;
|
|
117
|
+
_ssOrigin.applyMatrix4( camera.matrixWorldInverse );
|
|
118
|
+
_ssOrigin.applyMatrix4( projectionMatrix );
|
|
119
|
+
_ssOrigin.multiplyScalar( 1 / _ssOrigin.w );
|
|
120
|
+
|
|
121
|
+
// screen space
|
|
122
|
+
_ssOrigin.x *= resolution.x / 2;
|
|
123
|
+
_ssOrigin.y *= resolution.y / 2;
|
|
124
|
+
_ssOrigin.z = 0;
|
|
125
|
+
|
|
126
|
+
_ssOrigin3.copy( _ssOrigin );
|
|
127
|
+
|
|
128
|
+
_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
|
|
129
|
+
|
|
130
|
+
for ( let i = 0, l = segmentCount; i < l; i ++ ) {
|
|
131
|
+
|
|
132
|
+
_start4.fromBufferAttribute( instanceStart, i );
|
|
133
|
+
_end4.fromBufferAttribute( instanceEnd, i );
|
|
134
|
+
|
|
135
|
+
_start4.w = 1;
|
|
136
|
+
_end4.w = 1;
|
|
137
|
+
|
|
138
|
+
// camera space
|
|
139
|
+
_start4.applyMatrix4( _mvMatrix );
|
|
140
|
+
_end4.applyMatrix4( _mvMatrix );
|
|
141
|
+
|
|
142
|
+
// skip the segment if it's entirely behind the camera
|
|
143
|
+
const isBehindCameraNear = _start4.z > near && _end4.z > near;
|
|
144
|
+
if ( isBehindCameraNear ) {
|
|
145
|
+
|
|
146
|
+
continue;
|
|
147
|
+
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// trim the segment if it extends behind camera near
|
|
151
|
+
if ( _start4.z > near ) {
|
|
152
|
+
|
|
153
|
+
const deltaDist = _start4.z - _end4.z;
|
|
154
|
+
const t = ( _start4.z - near ) / deltaDist;
|
|
155
|
+
_start4.lerp( _end4, t );
|
|
156
|
+
|
|
157
|
+
} else if ( _end4.z > near ) {
|
|
158
|
+
|
|
159
|
+
const deltaDist = _end4.z - _start4.z;
|
|
160
|
+
const t = ( _end4.z - near ) / deltaDist;
|
|
161
|
+
_end4.lerp( _start4, t );
|
|
162
|
+
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// clip space
|
|
166
|
+
_start4.applyMatrix4( projectionMatrix );
|
|
167
|
+
_end4.applyMatrix4( projectionMatrix );
|
|
168
|
+
|
|
169
|
+
// ndc space [ - 1.0, 1.0 ]
|
|
170
|
+
_start4.multiplyScalar( 1 / _start4.w );
|
|
171
|
+
_end4.multiplyScalar( 1 / _end4.w );
|
|
172
|
+
|
|
173
|
+
// screen space
|
|
174
|
+
_start4.x *= resolution.x / 2;
|
|
175
|
+
_start4.y *= resolution.y / 2;
|
|
176
|
+
|
|
177
|
+
_end4.x *= resolution.x / 2;
|
|
178
|
+
_end4.y *= resolution.y / 2;
|
|
179
|
+
|
|
180
|
+
// create 2d segment
|
|
181
|
+
_line.start.copy( _start4 );
|
|
182
|
+
_line.start.z = 0;
|
|
183
|
+
|
|
184
|
+
_line.end.copy( _end4 );
|
|
185
|
+
_line.end.z = 0;
|
|
186
|
+
|
|
187
|
+
// get closest point on ray to segment
|
|
188
|
+
const param = _line.closestPointToPointParameter( _ssOrigin3, true );
|
|
189
|
+
_line.at( param, _closestPoint );
|
|
190
|
+
|
|
191
|
+
// check if the intersection point is within clip space
|
|
192
|
+
const zPos = MathUtils.lerp( _start4.z, _end4.z, param );
|
|
193
|
+
const isInClipSpace = zPos >= - 1 && zPos <= 1;
|
|
194
|
+
|
|
195
|
+
const isInside = _ssOrigin3.distanceTo( _closestPoint ) < _lineWidth * 0.5;
|
|
196
|
+
|
|
197
|
+
if ( isInClipSpace && isInside ) {
|
|
198
|
+
|
|
199
|
+
_line.start.fromBufferAttribute( instanceStart, i );
|
|
200
|
+
_line.end.fromBufferAttribute( instanceEnd, i );
|
|
201
|
+
|
|
202
|
+
_line.start.applyMatrix4( matrixWorld );
|
|
203
|
+
_line.end.applyMatrix4( matrixWorld );
|
|
204
|
+
|
|
205
|
+
const pointOnLine = new Vector3();
|
|
206
|
+
const point = new Vector3();
|
|
207
|
+
|
|
208
|
+
_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
|
|
209
|
+
|
|
210
|
+
intersects.push( {
|
|
211
|
+
point: point,
|
|
212
|
+
pointOnLine: pointOnLine,
|
|
213
|
+
distance: _ray.origin.distanceTo( point ),
|
|
214
|
+
object: lineSegments,
|
|
215
|
+
face: null,
|
|
216
|
+
faceIndex: i,
|
|
217
|
+
uv: null,
|
|
218
|
+
uv1: null,
|
|
219
|
+
} );
|
|
220
|
+
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* A series of lines drawn between pairs of vertices.
|
|
229
|
+
*
|
|
230
|
+
* This adds functionality beyond {@link LineSegments}, like arbitrary line width and changing width
|
|
231
|
+
* to be in world units. {@link Line2} extends this object, forming a polyline instead of individual
|
|
232
|
+
* segments.
|
|
233
|
+
*
|
|
234
|
+
* This module can only be used with {@link WebGLRenderer}. When using {@link WebGPURenderer},
|
|
235
|
+
* import the class from `lines/webgpu/LineSegments2.js`.
|
|
236
|
+
*
|
|
237
|
+
* ```js
|
|
238
|
+
* const geometry = new LineSegmentsGeometry();
|
|
239
|
+
* geometry.setPositions( positions );
|
|
240
|
+
* geometry.setColors( colors );
|
|
241
|
+
*
|
|
242
|
+
* const material = new LineMaterial( { linewidth: 5, vertexColors: true } };
|
|
243
|
+
*
|
|
244
|
+
* const lineSegments = new LineSegments2( geometry, material );
|
|
245
|
+
* scene.add( lineSegments );
|
|
246
|
+
* ```
|
|
247
|
+
*
|
|
248
|
+
* @augments Mesh
|
|
249
|
+
* @three_import import { LineSegments2 } from 'three/addons/lines/LineSegments2.js';
|
|
250
|
+
*/
|
|
32
251
|
class LineSegments2 extends Mesh {
|
|
33
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Constructs a new wide line.
|
|
255
|
+
*
|
|
256
|
+
* @param {LineSegmentsGeometry} [geometry] - The line geometry.
|
|
257
|
+
* @param {LineMaterial} [material] - The line material.
|
|
258
|
+
*/
|
|
34
259
|
constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
|
|
35
260
|
|
|
36
261
|
super( geometry, material );
|
|
37
262
|
|
|
263
|
+
/**
|
|
264
|
+
* This flag can be used for type testing.
|
|
265
|
+
*
|
|
266
|
+
* @type {boolean}
|
|
267
|
+
* @readonly
|
|
268
|
+
* @default true
|
|
269
|
+
*/
|
|
270
|
+
this.isLineSegments2 = true;
|
|
271
|
+
|
|
38
272
|
this.type = 'LineSegments2';
|
|
39
273
|
|
|
40
274
|
}
|
|
41
275
|
|
|
42
|
-
|
|
43
|
-
|
|
276
|
+
/**
|
|
277
|
+
* Computes an array of distance values which are necessary for rendering dashed lines.
|
|
278
|
+
* For each vertex in the geometry, the method calculates the cumulative length from the
|
|
279
|
+
* current point to the very beginning of the line.
|
|
280
|
+
*
|
|
281
|
+
* @return {LineSegments2} A reference to this instance.
|
|
282
|
+
*/
|
|
44
283
|
computeLineDistances() {
|
|
45
284
|
|
|
285
|
+
// for backwards-compatibility, but could be a method of LineSegmentsGeometry...
|
|
286
|
+
|
|
46
287
|
const geometry = this.geometry;
|
|
47
288
|
|
|
48
289
|
const instanceStart = geometry.attributes.instanceStart;
|
|
@@ -68,37 +309,40 @@ class LineSegments2 extends Mesh {
|
|
|
68
309
|
|
|
69
310
|
}
|
|
70
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Computes intersection points between a casted ray and this instance.
|
|
314
|
+
*
|
|
315
|
+
* @param {Raycaster} raycaster - The raycaster.
|
|
316
|
+
* @param {Array<Object>} intersects - The target array that holds the intersection points.
|
|
317
|
+
*/
|
|
71
318
|
raycast( raycaster, intersects ) {
|
|
72
319
|
|
|
73
|
-
|
|
320
|
+
const worldUnits = this.material.worldUnits;
|
|
321
|
+
const camera = raycaster.camera;
|
|
322
|
+
|
|
323
|
+
if ( camera === null && ! worldUnits ) {
|
|
324
|
+
|
|
325
|
+
console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2 while worldUnits is set to false.' );
|
|
326
|
+
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// early out if no resolution has been set (line was not rendered yet)
|
|
330
|
+
|
|
331
|
+
if ( worldUnits === false && ( this.material.resolution.x === 0 || this.material.resolution.y === 0 ) ) {
|
|
74
332
|
|
|
75
|
-
|
|
333
|
+
return;
|
|
76
334
|
|
|
77
335
|
}
|
|
78
336
|
|
|
79
337
|
const threshold = ( raycaster.params.Line2 !== undefined ) ? raycaster.params.Line2.threshold || 0 : 0;
|
|
80
338
|
|
|
81
|
-
|
|
82
|
-
const camera = raycaster.camera;
|
|
83
|
-
const projectionMatrix = camera.projectionMatrix;
|
|
339
|
+
_ray = raycaster.ray;
|
|
84
340
|
|
|
85
341
|
const matrixWorld = this.matrixWorld;
|
|
86
342
|
const geometry = this.geometry;
|
|
87
343
|
const material = this.material;
|
|
88
|
-
const resolution = material.resolution;
|
|
89
|
-
const lineWidth = material.linewidth + threshold;
|
|
90
|
-
|
|
91
|
-
const instanceStart = geometry.attributes.instanceStart;
|
|
92
|
-
const instanceEnd = geometry.attributes.instanceEnd;
|
|
93
|
-
|
|
94
|
-
// camera forward is negative
|
|
95
|
-
const near = - camera.near;
|
|
96
344
|
|
|
97
|
-
|
|
98
|
-
// width in clip space
|
|
99
|
-
const ssMaxWidth = 2.0 * Math.max( lineWidth / resolution.width, lineWidth / resolution.height );
|
|
100
|
-
|
|
101
|
-
//
|
|
345
|
+
_lineWidth = material.linewidth + threshold;
|
|
102
346
|
|
|
103
347
|
// check if we intersect the sphere bounds
|
|
104
348
|
if ( geometry.boundingSphere === null ) {
|
|
@@ -108,25 +352,28 @@ class LineSegments2 extends Mesh {
|
|
|
108
352
|
}
|
|
109
353
|
|
|
110
354
|
_sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );
|
|
111
|
-
const distanceToSphere = Math.max( camera.near, _sphere.distanceToPoint( ray.origin ) );
|
|
112
|
-
|
|
113
|
-
// get the w component to scale the world space line width
|
|
114
|
-
_clipToWorldVector.set( 0, 0, - distanceToSphere, 1.0 ).applyMatrix4( camera.projectionMatrix );
|
|
115
|
-
_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
|
|
116
|
-
_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
|
|
117
355
|
|
|
118
356
|
// increase the sphere bounds by the worst case line screen space width
|
|
119
|
-
|
|
357
|
+
let sphereMargin;
|
|
358
|
+
if ( worldUnits ) {
|
|
359
|
+
|
|
360
|
+
sphereMargin = _lineWidth * 0.5;
|
|
361
|
+
|
|
362
|
+
} else {
|
|
363
|
+
|
|
364
|
+
const distanceToSphere = Math.max( camera.near, _sphere.distanceToPoint( _ray.origin ) );
|
|
365
|
+
sphereMargin = getWorldSpaceHalfWidth( camera, distanceToSphere, material.resolution );
|
|
366
|
+
|
|
367
|
+
}
|
|
368
|
+
|
|
120
369
|
_sphere.radius += sphereMargin;
|
|
121
370
|
|
|
122
|
-
if (
|
|
371
|
+
if ( _ray.intersectsSphere( _sphere ) === false ) {
|
|
123
372
|
|
|
124
373
|
return;
|
|
125
374
|
|
|
126
375
|
}
|
|
127
376
|
|
|
128
|
-
//
|
|
129
|
-
|
|
130
377
|
// check if we intersect the box bounds
|
|
131
378
|
if ( geometry.boundingBox === null ) {
|
|
132
379
|
|
|
@@ -135,145 +382,48 @@ class LineSegments2 extends Mesh {
|
|
|
135
382
|
}
|
|
136
383
|
|
|
137
384
|
_box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );
|
|
138
|
-
const distanceToBox = Math.max( camera.near, _box.distanceToPoint( ray.origin ) );
|
|
139
385
|
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
|
|
386
|
+
// increase the box bounds by the worst case line width
|
|
387
|
+
let boxMargin;
|
|
388
|
+
if ( worldUnits ) {
|
|
144
389
|
|
|
145
|
-
|
|
146
|
-
const boxMargin = Math.abs( ssMaxWidth / _clipToWorldVector.w ) * 0.5;
|
|
147
|
-
_box.max.x += boxMargin;
|
|
148
|
-
_box.max.y += boxMargin;
|
|
149
|
-
_box.max.z += boxMargin;
|
|
150
|
-
_box.min.x -= boxMargin;
|
|
151
|
-
_box.min.y -= boxMargin;
|
|
152
|
-
_box.min.z -= boxMargin;
|
|
390
|
+
boxMargin = _lineWidth * 0.5;
|
|
153
391
|
|
|
154
|
-
|
|
392
|
+
} else {
|
|
155
393
|
|
|
156
|
-
|
|
394
|
+
const distanceToBox = Math.max( camera.near, _box.distanceToPoint( _ray.origin ) );
|
|
395
|
+
boxMargin = getWorldSpaceHalfWidth( camera, distanceToBox, material.resolution );
|
|
157
396
|
|
|
158
397
|
}
|
|
159
398
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
// pick a point 1 unit out along the ray to avoid the ray origin
|
|
163
|
-
// sitting at the camera origin which will cause "w" to be 0 when
|
|
164
|
-
// applying the projection matrix.
|
|
165
|
-
ray.at( 1, _ssOrigin );
|
|
166
|
-
|
|
167
|
-
// ndc space [ - 1.0, 1.0 ]
|
|
168
|
-
_ssOrigin.w = 1;
|
|
169
|
-
_ssOrigin.applyMatrix4( camera.matrixWorldInverse );
|
|
170
|
-
_ssOrigin.applyMatrix4( projectionMatrix );
|
|
171
|
-
_ssOrigin.multiplyScalar( 1 / _ssOrigin.w );
|
|
172
|
-
|
|
173
|
-
// screen space
|
|
174
|
-
_ssOrigin.x *= resolution.x / 2;
|
|
175
|
-
_ssOrigin.y *= resolution.y / 2;
|
|
176
|
-
_ssOrigin.z = 0;
|
|
177
|
-
|
|
178
|
-
_ssOrigin3.copy( _ssOrigin );
|
|
179
|
-
|
|
180
|
-
_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
|
|
181
|
-
|
|
182
|
-
for ( let i = 0, l = instanceStart.count; i < l; i ++ ) {
|
|
183
|
-
|
|
184
|
-
_start4.fromBufferAttribute( instanceStart, i );
|
|
185
|
-
_end4.fromBufferAttribute( instanceEnd, i );
|
|
186
|
-
|
|
187
|
-
_start4.w = 1;
|
|
188
|
-
_end4.w = 1;
|
|
189
|
-
|
|
190
|
-
// camera space
|
|
191
|
-
_start4.applyMatrix4( _mvMatrix );
|
|
192
|
-
_end4.applyMatrix4( _mvMatrix );
|
|
193
|
-
|
|
194
|
-
// skip the segment if it's entirely behind the camera
|
|
195
|
-
var isBehindCameraNear = _start4.z > near && _end4.z > near;
|
|
196
|
-
if ( isBehindCameraNear ) {
|
|
197
|
-
|
|
198
|
-
continue;
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// trim the segment if it extends behind camera near
|
|
203
|
-
if ( _start4.z > near ) {
|
|
399
|
+
_box.expandByScalar( boxMargin );
|
|
204
400
|
|
|
205
|
-
|
|
206
|
-
const t = ( _start4.z - near ) / deltaDist;
|
|
207
|
-
_start4.lerp( _end4, t );
|
|
401
|
+
if ( _ray.intersectsBox( _box ) === false ) {
|
|
208
402
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const deltaDist = _end4.z - _start4.z;
|
|
212
|
-
const t = ( _end4.z - near ) / deltaDist;
|
|
213
|
-
_end4.lerp( _start4, t );
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// clip space
|
|
218
|
-
_start4.applyMatrix4( projectionMatrix );
|
|
219
|
-
_end4.applyMatrix4( projectionMatrix );
|
|
220
|
-
|
|
221
|
-
// ndc space [ - 1.0, 1.0 ]
|
|
222
|
-
_start4.multiplyScalar( 1 / _start4.w );
|
|
223
|
-
_end4.multiplyScalar( 1 / _end4.w );
|
|
224
|
-
|
|
225
|
-
// screen space
|
|
226
|
-
_start4.x *= resolution.x / 2;
|
|
227
|
-
_start4.y *= resolution.y / 2;
|
|
228
|
-
|
|
229
|
-
_end4.x *= resolution.x / 2;
|
|
230
|
-
_end4.y *= resolution.y / 2;
|
|
231
|
-
|
|
232
|
-
// create 2d segment
|
|
233
|
-
_line.start.copy( _start4 );
|
|
234
|
-
_line.start.z = 0;
|
|
235
|
-
|
|
236
|
-
_line.end.copy( _end4 );
|
|
237
|
-
_line.end.z = 0;
|
|
238
|
-
|
|
239
|
-
// get closest point on ray to segment
|
|
240
|
-
const param = _line.closestPointToPointParameter( _ssOrigin3, true );
|
|
241
|
-
_line.at( param, _closestPoint );
|
|
242
|
-
|
|
243
|
-
// check if the intersection point is within clip space
|
|
244
|
-
const zPos = MathUtils.lerp( _start4.z, _end4.z, param );
|
|
245
|
-
const isInClipSpace = zPos >= - 1 && zPos <= 1;
|
|
403
|
+
return;
|
|
246
404
|
|
|
247
|
-
|
|
405
|
+
}
|
|
248
406
|
|
|
249
|
-
|
|
407
|
+
if ( worldUnits ) {
|
|
250
408
|
|
|
251
|
-
|
|
252
|
-
_line.end.fromBufferAttribute( instanceEnd, i );
|
|
409
|
+
raycastWorldUnits( this, intersects );
|
|
253
410
|
|
|
254
|
-
|
|
255
|
-
_line.end.applyMatrix4( matrixWorld );
|
|
411
|
+
} else {
|
|
256
412
|
|
|
257
|
-
|
|
258
|
-
const point = new Vector3();
|
|
413
|
+
raycastScreenSpace( this, camera, intersects );
|
|
259
414
|
|
|
260
|
-
|
|
415
|
+
}
|
|
261
416
|
|
|
262
|
-
|
|
417
|
+
}
|
|
263
418
|
|
|
264
|
-
|
|
265
|
-
pointOnLine: pointOnLine,
|
|
266
|
-
distance: ray.origin.distanceTo( point ),
|
|
419
|
+
onBeforeRender( renderer ) {
|
|
267
420
|
|
|
268
|
-
|
|
269
|
-
face: null,
|
|
270
|
-
faceIndex: i,
|
|
271
|
-
uv: null,
|
|
272
|
-
uv2: null,
|
|
421
|
+
const uniforms = this.material.uniforms;
|
|
273
422
|
|
|
274
|
-
|
|
423
|
+
if ( uniforms && uniforms.resolution ) {
|
|
275
424
|
|
|
276
|
-
|
|
425
|
+
renderer.getViewport( _viewport );
|
|
426
|
+
this.material.uniforms.resolution.value.set( _viewport.z, _viewport.w );
|
|
277
427
|
|
|
278
428
|
}
|
|
279
429
|
|
|
@@ -281,6 +431,4 @@ class LineSegments2 extends Mesh {
|
|
|
281
431
|
|
|
282
432
|
}
|
|
283
433
|
|
|
284
|
-
LineSegments2.prototype.LineSegments2 = true;
|
|
285
|
-
|
|
286
434
|
export { LineSegments2 };
|
|
@@ -12,12 +12,32 @@ import {
|
|
|
12
12
|
const _box = new Box3();
|
|
13
13
|
const _vector = new Vector3();
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* A series of vertex pairs, forming line segments.
|
|
17
|
+
*
|
|
18
|
+
* This is used in {@link LineSegments2} to describe the shape.
|
|
19
|
+
*
|
|
20
|
+
* @augments InstancedBufferGeometry
|
|
21
|
+
* @three_import import { LineSegmentsGeometry } from 'three/addons/lines/LineSegmentsGeometry.js';
|
|
22
|
+
*/
|
|
15
23
|
class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
16
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Constructs a new line segments geometry.
|
|
27
|
+
*/
|
|
17
28
|
constructor() {
|
|
18
29
|
|
|
19
30
|
super();
|
|
20
31
|
|
|
32
|
+
/**
|
|
33
|
+
* This flag can be used for type testing.
|
|
34
|
+
*
|
|
35
|
+
* @type {boolean}
|
|
36
|
+
* @readonly
|
|
37
|
+
* @default true
|
|
38
|
+
*/
|
|
39
|
+
this.isLineSegmentsGeometry = true;
|
|
40
|
+
|
|
21
41
|
this.type = 'LineSegmentsGeometry';
|
|
22
42
|
|
|
23
43
|
const positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
|
|
@@ -30,6 +50,12 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
|
30
50
|
|
|
31
51
|
}
|
|
32
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Applies the given 4x4 transformation matrix to the geometry.
|
|
55
|
+
*
|
|
56
|
+
* @param {Matrix4} matrix - The matrix to apply.
|
|
57
|
+
* @return {LineSegmentsGeometry} A reference to this instance.
|
|
58
|
+
*/
|
|
33
59
|
applyMatrix4( matrix ) {
|
|
34
60
|
|
|
35
61
|
const start = this.attributes.instanceStart;
|
|
@@ -61,6 +87,13 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
|
61
87
|
|
|
62
88
|
}
|
|
63
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Sets the given line positions for this geometry. The length must be a multiple of six since
|
|
92
|
+
* each line segment is defined by a start end vertex in the pattern `(xyz xyz)`.
|
|
93
|
+
*
|
|
94
|
+
* @param {Float32Array|Array<number>} array - The position data to set.
|
|
95
|
+
* @return {LineSegmentsGeometry} A reference to this geometry.
|
|
96
|
+
*/
|
|
64
97
|
setPositions( array ) {
|
|
65
98
|
|
|
66
99
|
let lineSegments;
|
|
@@ -80,6 +113,8 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
|
80
113
|
this.setAttribute( 'instanceStart', new InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
|
|
81
114
|
this.setAttribute( 'instanceEnd', new InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
|
|
82
115
|
|
|
116
|
+
this.instanceCount = this.attributes.instanceStart.count;
|
|
117
|
+
|
|
83
118
|
//
|
|
84
119
|
|
|
85
120
|
this.computeBoundingBox();
|
|
@@ -89,6 +124,13 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
|
89
124
|
|
|
90
125
|
}
|
|
91
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Sets the given line colors for this geometry. The length must be a multiple of six since
|
|
129
|
+
* each line segment is defined by a start end color in the pattern `(rgb rgb)`.
|
|
130
|
+
*
|
|
131
|
+
* @param {Float32Array|Array<number>} array - The position data to set.
|
|
132
|
+
* @return {LineSegmentsGeometry} A reference to this geometry.
|
|
133
|
+
*/
|
|
92
134
|
setColors( array ) {
|
|
93
135
|
|
|
94
136
|
let colors;
|
|
@@ -112,6 +154,12 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
|
112
154
|
|
|
113
155
|
}
|
|
114
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Setups this line segments geometry from the given wireframe geometry.
|
|
159
|
+
*
|
|
160
|
+
* @param {WireframeGeometry} geometry - The geometry that should be used as a data source for this geometry.
|
|
161
|
+
* @return {LineSegmentsGeometry} A reference to this geometry.
|
|
162
|
+
*/
|
|
115
163
|
fromWireframeGeometry( geometry ) {
|
|
116
164
|
|
|
117
165
|
this.setPositions( geometry.attributes.position.array );
|
|
@@ -120,6 +168,12 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
|
120
168
|
|
|
121
169
|
}
|
|
122
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Setups this line segments geometry from the given edges geometry.
|
|
173
|
+
*
|
|
174
|
+
* @param {EdgesGeometry} geometry - The geometry that should be used as a data source for this geometry.
|
|
175
|
+
* @return {LineSegmentsGeometry} A reference to this geometry.
|
|
176
|
+
*/
|
|
123
177
|
fromEdgesGeometry( geometry ) {
|
|
124
178
|
|
|
125
179
|
this.setPositions( geometry.attributes.position.array );
|
|
@@ -128,6 +182,12 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
|
128
182
|
|
|
129
183
|
}
|
|
130
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Setups this line segments geometry from the given mesh.
|
|
187
|
+
*
|
|
188
|
+
* @param {Mesh} mesh - The mesh geometry that should be used as a data source for this geometry.
|
|
189
|
+
* @return {LineSegmentsGeometry} A reference to this geometry.
|
|
190
|
+
*/
|
|
131
191
|
fromMesh( mesh ) {
|
|
132
192
|
|
|
133
193
|
this.fromWireframeGeometry( new WireframeGeometry( mesh.geometry ) );
|
|
@@ -138,20 +198,18 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
|
138
198
|
|
|
139
199
|
}
|
|
140
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Setups this line segments geometry from the given line segments.
|
|
203
|
+
*
|
|
204
|
+
* @param {LineSegments} lineSegments - The line segments that should be used as a data source for this geometry.
|
|
205
|
+
* Assumes the source geometry is not using indices.
|
|
206
|
+
* @return {LineSegmentsGeometry} A reference to this geometry.
|
|
207
|
+
*/
|
|
141
208
|
fromLineSegments( lineSegments ) {
|
|
142
209
|
|
|
143
210
|
const geometry = lineSegments.geometry;
|
|
144
211
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
console.error( 'THREE.LineSegmentsGeometry no longer supports Geometry. Use THREE.BufferGeometry instead.' );
|
|
148
|
-
return;
|
|
149
|
-
|
|
150
|
-
} else if ( geometry.isBufferGeometry ) {
|
|
151
|
-
|
|
152
|
-
this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
|
|
153
|
-
|
|
154
|
-
}
|
|
212
|
+
this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
|
|
155
213
|
|
|
156
214
|
// set colors, maybe
|
|
157
215
|
|
|
@@ -235,16 +293,6 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
|
235
293
|
|
|
236
294
|
}
|
|
237
295
|
|
|
238
|
-
applyMatrix( matrix ) {
|
|
239
|
-
|
|
240
|
-
console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );
|
|
241
|
-
|
|
242
|
-
return this.applyMatrix4( matrix );
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
|
|
246
296
|
}
|
|
247
297
|
|
|
248
|
-
LineSegmentsGeometry.prototype.isLineSegmentsGeometry = true;
|
|
249
|
-
|
|
250
298
|
export { LineSegmentsGeometry };
|