Skip to content

Commit

Permalink
Box3 now supports computing minimal bounds for setFromObject (#20024)
Browse files Browse the repository at this point in the history
  • Loading branch information
arikwex authored Jan 21, 2022
1 parent 08f0972 commit bd42765
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 17 deletions.
12 changes: 7 additions & 5 deletions docs/api/en/math/Box3.html
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,14 @@ <h3>[method:Boolean equals]( [param:Box3 box] )</h3>
Returns true if this box and [page:Box3 box] share the same lower and upper bounds.
</p>

<h3>[method:this expandByObject]( [param:Object3D object] )</h3>
<h3>[method:this expandByObject]( [param:Object3D object], [param:Boolean precise] )</h3>
<p>
[page:Object3D object] - [page:Object3D] to expand the box by.<br /><br />
[page:Object3D object] - [page:Object3D] to expand the box by.<br />
precise - (optional) expand the bounding box as little as necessary at the expense of more computation. Default is false.<br /><br />

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).

</p>

Expand Down Expand Up @@ -264,9 +265,10 @@ <h3>[method:this setFromCenterAndSize]( [param:Vector3 center], [param:Vector3 s
in [page:Vector3 size]
</p>

<h3>[method:this setFromObject]( [param:Object3D object] )</h3>
<h3>[method:this setFromObject]( [param:Object3D object], [param:Boolean precise] )</h3>
<p>
[page:Object3D object] - [page:Object3D] to compute the bounding box of.<br /><br />
[page:Object3D object] - [page:Object3D] to compute the bounding box of.<br />
precise - (optional) compute the smallest world-axis-aligned bounding box at the expense of more computation. Default is false.<br /><br />

Computes a world-axis-aligned bounding box of an [page:Object3D] (including its children),
accounting for the object's, and children's, world transforms.<br /><br />
Expand Down
34 changes: 24 additions & 10 deletions src/math/Box3.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ class Box3 {

}

setFromObject( object ) {
setFromObject( object, precise = false ) {

this.makeEmpty();

return this.expandByObject( object );
return this.expandByObject( object, precise );

}

Expand Down Expand Up @@ -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.
Expand All @@ -201,24 +201,38 @@ 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 );

}

}

const children = object.children;

for ( let i = 0, l = children.length; i < l; i ++ ) {

this.expandByObject( children[ i ] );
this.expandByObject( children[ i ], precise );

}

Expand Down
33 changes: 31 additions & 2 deletions test/unit/src/math/Box3.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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() );

Expand Down

0 comments on commit bd42765

Please sign in to comment.