diff --git a/docs/api/en/math/Box3.html b/docs/api/en/math/Box3.html index 800b1325b04a3d..ce28e0e604a58e 100644 --- a/docs/api/en/math/Box3.html +++ b/docs/api/en/math/Box3.html @@ -121,13 +121,14 @@
- [page:Object3D object] - [page:Object3D] to expand the box by.
+ [page:Object3D object] - [page:Object3D] to expand the box by.
+ precise - (optional) expand the bounding box as little as necessary at the expense of more computation. Default is false.
Expands the boundaries of this box to include [page:Object3D object] and its children,
accounting for the object's, and children's, world transforms.
- The function may result in a larger box than strictly necessary.
+ The function may result in a larger box than strictly necessary (unless the precise parameter is set to true).
- [page:Object3D object] - [page:Object3D] to compute the bounding box of.
+ [page:Object3D object] - [page:Object3D] to compute the bounding box of.
+ precise - (optional) compute the smallest world-axis-aligned bounding box at the expense of more computation. Default is false.
Computes the world-axis-aligned bounding box of an [page:Object3D] (including its children),
accounting for the object's, and children's, world transforms.
diff --git a/src/math/Box3.js b/src/math/Box3.js
index 1a5e4ffd7f1254..31c7c15cfa6be5 100644
--- a/src/math/Box3.js
+++ b/src/math/Box3.js
@@ -109,11 +109,11 @@ class Box3 {
}
- setFromObject( object ) {
+ setFromObject( object, precise = false ) {
this.makeEmpty();
- return this.expandByObject( object );
+ return this.expandByObject( object, precise );
}
@@ -188,7 +188,7 @@ class Box3 {
}
- expandByObject( object ) {
+ expandByObject( object, precise = false ) {
// Computes the world-axis-aligned bounding box of an object (including its children),
// accounting for both the object's, and children's, world transforms
@@ -199,16 +199,30 @@ class Box3 {
if ( geometry !== undefined ) {
- if ( geometry.boundingBox === null ) {
+ if ( precise && geometry.attributes != undefined && geometry.attributes.position !== undefined ) {
- geometry.computeBoundingBox();
+ const position = geometry.attributes.position;
+ for ( let i = 0, l = position.count; i < l; i ++ ) {
- }
+ _vector.fromBufferAttribute( position, i ).applyMatrix4( object.matrixWorld );
+ this.expandByPoint( _vector );
+
+ }
+
+ } else {
+
+ if ( geometry.boundingBox === null ) {
- _box.copy( geometry.boundingBox );
- _box.applyMatrix4( object.matrixWorld );
+ geometry.computeBoundingBox();
- this.union( _box );
+ }
+
+ _box.copy( geometry.boundingBox );
+ _box.applyMatrix4( object.matrixWorld );
+
+ this.union( _box );
+
+ }
}
@@ -216,7 +230,7 @@ class Box3 {
for ( let i = 0, l = children.length; i < l; i ++ ) {
- this.expandByObject( children[ i ] );
+ this.expandByObject( children[ i ], precise );
}
diff --git a/test/unit/src/math/Box3.tests.js b/test/unit/src/math/Box3.tests.js
index 4a659c17f5d4b2..e8d14985fb027a 100644
--- a/test/unit/src/math/Box3.tests.js
+++ b/test/unit/src/math/Box3.tests.js
@@ -8,7 +8,13 @@ import { Vector3 } from '../../../../src/math/Vector3';
import { Matrix4 } from '../../../../src/math/Matrix4';
import { Mesh } from '../../../../src/objects/Mesh';
import { BufferAttribute } from '../../../../src/core/BufferAttribute';
-import { BoxGeometry } from '../../../../src/geometries/BoxGeometry';
+import {
+ BoxGeometry,
+ BoxBufferGeometry,
+} from '../../../../src/geometries/BoxGeometry';
+import {
+ SphereBufferGeometry,
+} from '../../../../src/geometries/SphereGeometry';
import {
negInf3,
posInf3,
@@ -165,8 +171,31 @@ export default QUnit.module( 'Maths', () => {
} );
- QUnit.test( 'clone', ( assert ) => {
+ QUnit.test( 'setFromObject/Precise', ( assert ) => {
+
+ var a = new Box3( zero3.clone(), one3.clone() );
+ var object = new Mesh( new SphereBufferGeometry( 1, 32, 32 ) );
+ var child = new Mesh( new SphereBufferGeometry( 2, 32, 32 ) );
+ object.add( child );
+ object.rotation.setFromVector3(new Vector3(0, 0, Math.PI / 4.0));
+
+ a.setFromObject( object );
+ var rotatedBox = new Box3(
+ new Vector3( - 2 * Math.SQRT2, - 2 * Math.SQRT2, - 2 ),
+ new Vector3( 2 * Math.SQRT2, 2 * Math.SQRT2, 2 )
+ );
+ assert.ok( compareBox( a, rotatedBox ), "Passed!" );
+
+ a.setFromObject( object, true );
+ var rotatedMinBox = new Box3(
+ new Vector3( - 2, - 2, - 2 ),
+ new Vector3( 2, 2, 2 )
+ );
+ assert.ok( compareBox( a, rotatedMinBox ), "Passed!" );
+ } );
+
+ QUnit.test( 'clone', ( assert ) => {
var a = new Box3( zero3.clone(), one3.clone() );