@@ -17,8 +17,10 @@ const _point2 = new Vector3();
1717const _plane = new Plane ( ) ;
1818const _line1 = new Line3 ( ) ;
1919const _line2 = new Line3 ( ) ;
20+ const _box = new Box3 ( ) ;
2021const _sphere = new Sphere ( ) ;
2122const _capsule = new Capsule ( ) ;
23+ const _center = new Capsule ( ) ;
2224
2325const _temp1 = new Vector3 ( ) ;
2426const _temp2 = new Vector3 ( ) ;
@@ -373,6 +375,61 @@ class Octree {
373375
374376 }
375377
378+ /**
379+ * Computes the intersection between the given bounding box and triangle.
380+ *
381+ * @param {Box3 } box - The bounding box to test.
382+ * @param {Triangle } triangle - The triangle to test.
383+ * @return {Object|false } The intersection object. If no intersection
384+ * is detected, the method returns `false`.
385+ */
386+ triangleBoxIntersect ( box , triangle ) {
387+
388+ // cheap check
389+
390+ if ( Math . max ( triangle . a . x , triangle . b . x , triangle . c . x ) < box . min . x ||
391+ Math . min ( triangle . a . x , triangle . b . x , triangle . c . x ) > box . max . x ||
392+ Math . max ( triangle . a . y , triangle . b . y , triangle . c . y ) < box . min . y ||
393+ Math . min ( triangle . a . y , triangle . b . y , triangle . c . y ) > box . max . y ||
394+ Math . max ( triangle . a . z , triangle . b . z , triangle . c . z ) < box . min . z ||
395+ Math . min ( triangle . a . z , triangle . b . z , triangle . c . z ) > box . max . z ) {
396+
397+ return false ;
398+
399+ }
400+
401+ // expensive check
402+
403+ if ( ! box . intersectsTriangle ( triangle ) ) return false ;
404+
405+ // there is an intersection, now compute collision data
406+
407+ triangle . getPlane ( _plane ) ;
408+
409+ // determine which corner of the box is "deepest" into the plane
410+
411+ _v1 . x = ( _plane . normal . x > 0 ) ? box . min . x : box . max . x ;
412+ _v1 . y = ( _plane . normal . y > 0 ) ? box . min . y : box . max . y ;
413+ _v1 . z = ( _plane . normal . z > 0 ) ? box . min . z : box . max . z ;
414+
415+ // Calculate the distance from the plane to that corner (the distance will be negative
416+ // because of the intersection)
417+
418+ const distance = _plane . distanceToPoint ( _v1 ) ;
419+
420+ const intersection = {
421+ depth : - distance , // Flip sign so depth is positive
422+ normal : _plane . normal . clone ( ) ,
423+ point : _v1 . clone ( )
424+ } ;
425+
426+ // project the point onto the triangle surface
427+ intersection . point . addScaledVector ( intersection . normal , distance ) ;
428+
429+ return intersection ;
430+
431+ }
432+
376433 /**
377434 * Computes the intersection between the given sphere and triangle.
378435 *
@@ -455,6 +512,38 @@ class Octree {
455512
456513 }
457514
515+ /**
516+ * Computes the triangles that potentially intersect with the given bounding box.
517+ *
518+ * @param {Box3 } box - The bounding box.
519+ * @param {Array<Triangle> } triangles - The target array that holds the triangles.
520+ */
521+ getBoxTriangles ( box , triangles ) {
522+
523+ for ( let i = 0 ; i < this . subTrees . length ; i ++ ) {
524+
525+ const subTree = this . subTrees [ i ] ;
526+
527+ if ( ! box . intersectsBox ( subTree . box ) ) continue ;
528+
529+ if ( subTree . triangles . length > 0 ) {
530+
531+ for ( let j = 0 ; j < subTree . triangles . length ; j ++ ) {
532+
533+ if ( triangles . indexOf ( subTree . triangles [ j ] ) === - 1 ) triangles . push ( subTree . triangles [ j ] ) ;
534+
535+ }
536+
537+ } else {
538+
539+ subTree . getBoxTriangles ( box , triangles ) ;
540+
541+ }
542+
543+ }
544+
545+ }
546+
458547 /**
459548 * Computes the triangles that potentially intersect with the given capsule.
460549 *
@@ -487,6 +576,47 @@ class Octree {
487576
488577 }
489578
579+ /**
580+ * Performs a bounding box intersection test with this Octree.
581+ *
582+ * @param {Box3 } box - The bounding box to test.
583+ * @return {Object|boolean } The intersection object. If no intersection
584+ * is detected, the method returns `false`.
585+ */
586+ boxIntersect ( box ) {
587+
588+ _box . copy ( box ) ;
589+
590+ const triangles = [ ] ;
591+ let result , hit = false ;
592+
593+ this . getBoxTriangles ( box , triangles ) ;
594+
595+ for ( let i = 0 ; i < triangles . length ; i ++ ) {
596+
597+ if ( result = this . triangleBoxIntersect ( _box , triangles [ i ] ) ) {
598+
599+ hit = true ;
600+
601+ _box . translate ( result . normal . multiplyScalar ( result . depth ) ) ;
602+
603+ }
604+
605+ }
606+
607+ if ( hit ) {
608+
609+ const collisionVector = _box . getCenter ( _center ) . sub ( box . getCenter ( _v1 ) ) ;
610+ const depth = collisionVector . length ( ) ;
611+
612+ return { normal : collisionVector . normalize ( ) , depth : depth } ;
613+
614+ }
615+
616+ return false ;
617+
618+ }
619+
490620 /**
491621 * Performs a bounding sphere intersection test with this Octree.
492622 *
@@ -558,7 +688,7 @@ class Octree {
558688
559689 if ( hit ) {
560690
561- const collisionVector = _capsule . getCenter ( new Vector3 ( ) ) . sub ( capsule . getCenter ( _v1 ) ) ;
691+ const collisionVector = _capsule . getCenter ( _center ) . sub ( capsule . getCenter ( _v1 ) ) ;
562692 const depth = collisionVector . length ( ) ;
563693
564694 return { normal : collisionVector . normalize ( ) , depth : depth } ;
0 commit comments