1 | import { Vector3 } from './Vector3.js';
|
2 | import { Sphere } from './Sphere.js';
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | function Box3( min, max ) {
|
10 |
|
11 | this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );
|
12 | this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );
|
13 |
|
14 | }
|
15 |
|
16 | Object.assign( Box3.prototype, {
|
17 |
|
18 | isBox3: true,
|
19 |
|
20 | set: function ( min, max ) {
|
21 |
|
22 | this.min.copy( min );
|
23 | this.max.copy( max );
|
24 |
|
25 | return this;
|
26 |
|
27 | },
|
28 |
|
29 | setFromArray: function ( array ) {
|
30 |
|
31 | var minX = + Infinity;
|
32 | var minY = + Infinity;
|
33 | var minZ = + Infinity;
|
34 |
|
35 | var maxX = - Infinity;
|
36 | var maxY = - Infinity;
|
37 | var maxZ = - Infinity;
|
38 |
|
39 | for ( var i = 0, l = array.length; i < l; i += 3 ) {
|
40 |
|
41 | var x = array[ i ];
|
42 | var y = array[ i + 1 ];
|
43 | var z = array[ i + 2 ];
|
44 |
|
45 | if ( x < minX ) minX = x;
|
46 | if ( y < minY ) minY = y;
|
47 | if ( z < minZ ) minZ = z;
|
48 |
|
49 | if ( x > maxX ) maxX = x;
|
50 | if ( y > maxY ) maxY = y;
|
51 | if ( z > maxZ ) maxZ = z;
|
52 |
|
53 | }
|
54 |
|
55 | this.min.set( minX, minY, minZ );
|
56 | this.max.set( maxX, maxY, maxZ );
|
57 |
|
58 | return this;
|
59 |
|
60 | },
|
61 |
|
62 | setFromBufferAttribute: function ( attribute ) {
|
63 |
|
64 | var minX = + Infinity;
|
65 | var minY = + Infinity;
|
66 | var minZ = + Infinity;
|
67 |
|
68 | var maxX = - Infinity;
|
69 | var maxY = - Infinity;
|
70 | var maxZ = - Infinity;
|
71 |
|
72 | for ( var i = 0, l = attribute.count; i < l; i ++ ) {
|
73 |
|
74 | var x = attribute.getX( i );
|
75 | var y = attribute.getY( i );
|
76 | var z = attribute.getZ( i );
|
77 |
|
78 | if ( x < minX ) minX = x;
|
79 | if ( y < minY ) minY = y;
|
80 | if ( z < minZ ) minZ = z;
|
81 |
|
82 | if ( x > maxX ) maxX = x;
|
83 | if ( y > maxY ) maxY = y;
|
84 | if ( z > maxZ ) maxZ = z;
|
85 |
|
86 | }
|
87 |
|
88 | this.min.set( minX, minY, minZ );
|
89 | this.max.set( maxX, maxY, maxZ );
|
90 |
|
91 | return this;
|
92 |
|
93 | },
|
94 |
|
95 | setFromPoints: function ( points ) {
|
96 |
|
97 | this.makeEmpty();
|
98 |
|
99 | for ( var i = 0, il = points.length; i < il; i ++ ) {
|
100 |
|
101 | this.expandByPoint( points[ i ] );
|
102 |
|
103 | }
|
104 |
|
105 | return this;
|
106 |
|
107 | },
|
108 |
|
109 | setFromCenterAndSize: function () {
|
110 |
|
111 | var v1 = new Vector3();
|
112 |
|
113 | return function setFromCenterAndSize( center, size ) {
|
114 |
|
115 | var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
|
116 |
|
117 | this.min.copy( center ).sub( halfSize );
|
118 | this.max.copy( center ).add( halfSize );
|
119 |
|
120 | return this;
|
121 |
|
122 | };
|
123 |
|
124 | }(),
|
125 |
|
126 | setFromObject: function ( object ) {
|
127 |
|
128 | this.makeEmpty();
|
129 |
|
130 | return this.expandByObject( object );
|
131 |
|
132 | },
|
133 |
|
134 | clone: function () {
|
135 |
|
136 | return new this.constructor().copy( this );
|
137 |
|
138 | },
|
139 |
|
140 | copy: function ( box ) {
|
141 |
|
142 | this.min.copy( box.min );
|
143 | this.max.copy( box.max );
|
144 |
|
145 | return this;
|
146 |
|
147 | },
|
148 |
|
149 | makeEmpty: function () {
|
150 |
|
151 | this.min.x = this.min.y = this.min.z = + Infinity;
|
152 | this.max.x = this.max.y = this.max.z = - Infinity;
|
153 |
|
154 | return this;
|
155 |
|
156 | },
|
157 |
|
158 | isEmpty: function () {
|
159 |
|
160 |
|
161 |
|
162 | return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );
|
163 |
|
164 | },
|
165 |
|
166 | getCenter: function ( target ) {
|
167 |
|
168 | if ( target === undefined ) {
|
169 |
|
170 | console.warn( 'THREE.Box3: .getCenter() target is now required' );
|
171 | target = new Vector3();
|
172 |
|
173 | }
|
174 |
|
175 | return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
|
176 |
|
177 | },
|
178 |
|
179 | getSize: function ( target ) {
|
180 |
|
181 | if ( target === undefined ) {
|
182 |
|
183 | console.warn( 'THREE.Box3: .getSize() target is now required' );
|
184 | target = new Vector3();
|
185 |
|
186 | }
|
187 |
|
188 | return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min );
|
189 |
|
190 | },
|
191 |
|
192 | expandByPoint: function ( point ) {
|
193 |
|
194 | this.min.min( point );
|
195 | this.max.max( point );
|
196 |
|
197 | return this;
|
198 |
|
199 | },
|
200 |
|
201 | expandByVector: function ( vector ) {
|
202 |
|
203 | this.min.sub( vector );
|
204 | this.max.add( vector );
|
205 |
|
206 | return this;
|
207 |
|
208 | },
|
209 |
|
210 | expandByScalar: function ( scalar ) {
|
211 |
|
212 | this.min.addScalar( - scalar );
|
213 | this.max.addScalar( scalar );
|
214 |
|
215 | return this;
|
216 |
|
217 | },
|
218 |
|
219 | expandByObject: function () {
|
220 |
|
221 |
|
222 |
|
223 |
|
224 | var scope, i, l;
|
225 |
|
226 | var v1 = new Vector3();
|
227 |
|
228 | function traverse( node ) {
|
229 |
|
230 | var geometry = node.geometry;
|
231 |
|
232 | if ( geometry !== undefined ) {
|
233 |
|
234 | if ( geometry.isGeometry ) {
|
235 |
|
236 | var vertices = geometry.vertices;
|
237 |
|
238 | for ( i = 0, l = vertices.length; i < l; i ++ ) {
|
239 |
|
240 | v1.copy( vertices[ i ] );
|
241 | v1.applyMatrix4( node.matrixWorld );
|
242 |
|
243 | scope.expandByPoint( v1 );
|
244 |
|
245 | }
|
246 |
|
247 | } else if ( geometry.isBufferGeometry ) {
|
248 |
|
249 | var attribute = geometry.attributes.position;
|
250 |
|
251 | if ( attribute !== undefined ) {
|
252 |
|
253 | for ( i = 0, l = attribute.count; i < l; i ++ ) {
|
254 |
|
255 | v1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );
|
256 |
|
257 | scope.expandByPoint( v1 );
|
258 |
|
259 | }
|
260 |
|
261 | }
|
262 |
|
263 | }
|
264 |
|
265 | }
|
266 |
|
267 | }
|
268 |
|
269 | return function expandByObject( object ) {
|
270 |
|
271 | scope = this;
|
272 |
|
273 | object.updateMatrixWorld( true );
|
274 |
|
275 | object.traverse( traverse );
|
276 |
|
277 | return this;
|
278 |
|
279 | };
|
280 |
|
281 | }(),
|
282 |
|
283 | containsPoint: function ( point ) {
|
284 |
|
285 | return point.x < this.min.x || point.x > this.max.x ||
|
286 | point.y < this.min.y || point.y > this.max.y ||
|
287 | point.z < this.min.z || point.z > this.max.z ? false : true;
|
288 |
|
289 | },
|
290 |
|
291 | containsBox: function ( box ) {
|
292 |
|
293 | return this.min.x <= box.min.x && box.max.x <= this.max.x &&
|
294 | this.min.y <= box.min.y && box.max.y <= this.max.y &&
|
295 | this.min.z <= box.min.z && box.max.z <= this.max.z;
|
296 |
|
297 | },
|
298 |
|
299 | getParameter: function ( point, target ) {
|
300 |
|
301 |
|
302 |
|
303 |
|
304 | if ( target === undefined ) {
|
305 |
|
306 | console.warn( 'THREE.Box3: .getParameter() target is now required' );
|
307 | target = new Vector3();
|
308 |
|
309 | }
|
310 |
|
311 | return target.set(
|
312 | ( point.x - this.min.x ) / ( this.max.x - this.min.x ),
|
313 | ( point.y - this.min.y ) / ( this.max.y - this.min.y ),
|
314 | ( point.z - this.min.z ) / ( this.max.z - this.min.z )
|
315 | );
|
316 |
|
317 | },
|
318 |
|
319 | intersectsBox: function ( box ) {
|
320 |
|
321 |
|
322 | return box.max.x < this.min.x || box.min.x > this.max.x ||
|
323 | box.max.y < this.min.y || box.min.y > this.max.y ||
|
324 | box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
|
325 |
|
326 | },
|
327 |
|
328 | intersectsSphere: ( function () {
|
329 |
|
330 | var closestPoint = new Vector3();
|
331 |
|
332 | return function intersectsSphere( sphere ) {
|
333 |
|
334 |
|
335 | this.clampPoint( sphere.center, closestPoint );
|
336 |
|
337 |
|
338 | return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );
|
339 |
|
340 | };
|
341 |
|
342 | } )(),
|
343 |
|
344 | intersectsPlane: function ( plane ) {
|
345 |
|
346 |
|
347 |
|
348 |
|
349 | var min, max;
|
350 |
|
351 | if ( plane.normal.x > 0 ) {
|
352 |
|
353 | min = plane.normal.x * this.min.x;
|
354 | max = plane.normal.x * this.max.x;
|
355 |
|
356 | } else {
|
357 |
|
358 | min = plane.normal.x * this.max.x;
|
359 | max = plane.normal.x * this.min.x;
|
360 |
|
361 | }
|
362 |
|
363 | if ( plane.normal.y > 0 ) {
|
364 |
|
365 | min += plane.normal.y * this.min.y;
|
366 | max += plane.normal.y * this.max.y;
|
367 |
|
368 | } else {
|
369 |
|
370 | min += plane.normal.y * this.max.y;
|
371 | max += plane.normal.y * this.min.y;
|
372 |
|
373 | }
|
374 |
|
375 | if ( plane.normal.z > 0 ) {
|
376 |
|
377 | min += plane.normal.z * this.min.z;
|
378 | max += plane.normal.z * this.max.z;
|
379 |
|
380 | } else {
|
381 |
|
382 | min += plane.normal.z * this.max.z;
|
383 | max += plane.normal.z * this.min.z;
|
384 |
|
385 | }
|
386 |
|
387 | return ( min <= plane.constant && max >= plane.constant );
|
388 |
|
389 | },
|
390 |
|
391 | intersectsTriangle: ( function () {
|
392 |
|
393 |
|
394 | var v0 = new Vector3();
|
395 | var v1 = new Vector3();
|
396 | var v2 = new Vector3();
|
397 |
|
398 |
|
399 | var f0 = new Vector3();
|
400 | var f1 = new Vector3();
|
401 | var f2 = new Vector3();
|
402 |
|
403 | var testAxis = new Vector3();
|
404 |
|
405 | var center = new Vector3();
|
406 | var extents = new Vector3();
|
407 |
|
408 | var triangleNormal = new Vector3();
|
409 |
|
410 | function satForAxes( axes ) {
|
411 |
|
412 | var i, j;
|
413 |
|
414 | for ( i = 0, j = axes.length - 3; i <= j; i += 3 ) {
|
415 |
|
416 | testAxis.fromArray( axes, i );
|
417 |
|
418 | var r = extents.x * Math.abs( testAxis.x ) + extents.y * Math.abs( testAxis.y ) + extents.z * Math.abs( testAxis.z );
|
419 |
|
420 | var p0 = v0.dot( testAxis );
|
421 | var p1 = v1.dot( testAxis );
|
422 | var p2 = v2.dot( testAxis );
|
423 |
|
424 | if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) {
|
425 |
|
426 |
|
427 |
|
428 | return false;
|
429 |
|
430 | }
|
431 |
|
432 | }
|
433 |
|
434 | return true;
|
435 |
|
436 | }
|
437 |
|
438 | return function intersectsTriangle( triangle ) {
|
439 |
|
440 | if ( this.isEmpty() ) {
|
441 |
|
442 | return false;
|
443 |
|
444 | }
|
445 |
|
446 |
|
447 | this.getCenter( center );
|
448 | extents.subVectors( this.max, center );
|
449 |
|
450 |
|
451 | v0.subVectors( triangle.a, center );
|
452 | v1.subVectors( triangle.b, center );
|
453 | v2.subVectors( triangle.c, center );
|
454 |
|
455 |
|
456 | f0.subVectors( v1, v0 );
|
457 | f1.subVectors( v2, v1 );
|
458 | f2.subVectors( v0, v2 );
|
459 |
|
460 |
|
461 |
|
462 |
|
463 | var axes = [
|
464 | 0, - f0.z, f0.y, 0, - f1.z, f1.y, 0, - f2.z, f2.y,
|
465 | f0.z, 0, - f0.x, f1.z, 0, - f1.x, f2.z, 0, - f2.x,
|
466 | - f0.y, f0.x, 0, - f1.y, f1.x, 0, - f2.y, f2.x, 0
|
467 | ];
|
468 | if ( ! satForAxes( axes ) ) {
|
469 |
|
470 | return false;
|
471 |
|
472 | }
|
473 |
|
474 |
|
475 | axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ];
|
476 | if ( ! satForAxes( axes ) ) {
|
477 |
|
478 | return false;
|
479 |
|
480 | }
|
481 |
|
482 |
|
483 |
|
484 | triangleNormal.crossVectors( f0, f1 );
|
485 | axes = [ triangleNormal.x, triangleNormal.y, triangleNormal.z ];
|
486 | return satForAxes( axes );
|
487 |
|
488 | };
|
489 |
|
490 | } )(),
|
491 |
|
492 | clampPoint: function ( point, target ) {
|
493 |
|
494 | if ( target === undefined ) {
|
495 |
|
496 | console.warn( 'THREE.Box3: .clampPoint() target is now required' );
|
497 | target = new Vector3();
|
498 |
|
499 | }
|
500 |
|
501 | return target.copy( point ).clamp( this.min, this.max );
|
502 |
|
503 | },
|
504 |
|
505 | distanceToPoint: function () {
|
506 |
|
507 | var v1 = new Vector3();
|
508 |
|
509 | return function distanceToPoint( point ) {
|
510 |
|
511 | var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
|
512 | return clampedPoint.sub( point ).length();
|
513 |
|
514 | };
|
515 |
|
516 | }(),
|
517 |
|
518 | getBoundingSphere: function () {
|
519 |
|
520 | var v1 = new Vector3();
|
521 |
|
522 | return function getBoundingSphere( target ) {
|
523 |
|
524 | if ( target === undefined ) {
|
525 |
|
526 | console.warn( 'THREE.Box3: .getBoundingSphere() target is now required' );
|
527 | target = new Sphere();
|
528 |
|
529 | }
|
530 |
|
531 | this.getCenter( target.center );
|
532 |
|
533 | target.radius = this.getSize( v1 ).length() * 0.5;
|
534 |
|
535 | return target;
|
536 |
|
537 | };
|
538 |
|
539 | }(),
|
540 |
|
541 | intersect: function ( box ) {
|
542 |
|
543 | this.min.max( box.min );
|
544 | this.max.min( box.max );
|
545 |
|
546 |
|
547 | if ( this.isEmpty() ) this.makeEmpty();
|
548 |
|
549 | return this;
|
550 |
|
551 | },
|
552 |
|
553 | union: function ( box ) {
|
554 |
|
555 | this.min.min( box.min );
|
556 | this.max.max( box.max );
|
557 |
|
558 | return this;
|
559 |
|
560 | },
|
561 |
|
562 | applyMatrix4: function () {
|
563 |
|
564 | var points = [
|
565 | new Vector3(),
|
566 | new Vector3(),
|
567 | new Vector3(),
|
568 | new Vector3(),
|
569 | new Vector3(),
|
570 | new Vector3(),
|
571 | new Vector3(),
|
572 | new Vector3()
|
573 | ];
|
574 |
|
575 | return function applyMatrix4( matrix ) {
|
576 |
|
577 |
|
578 | if ( this.isEmpty() ) return this;
|
579 |
|
580 |
|
581 | points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix );
|
582 | points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix );
|
583 | points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix );
|
584 | points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix );
|
585 | points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix );
|
586 | points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix );
|
587 | points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix );
|
588 | points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );
|
589 |
|
590 | this.setFromPoints( points );
|
591 |
|
592 | return this;
|
593 |
|
594 | };
|
595 |
|
596 | }(),
|
597 |
|
598 | translate: function ( offset ) {
|
599 |
|
600 | this.min.add( offset );
|
601 | this.max.add( offset );
|
602 |
|
603 | return this;
|
604 |
|
605 | },
|
606 |
|
607 | equals: function ( box ) {
|
608 |
|
609 | return box.min.equals( this.min ) && box.max.equals( this.max );
|
610 |
|
611 | }
|
612 |
|
613 | } );
|
614 |
|
615 |
|
616 | export { Box3 };
|