Skip to content

Commit bd42765

Browse files
authored
Box3 now supports computing minimal bounds for setFromObject (#20024)
1 parent 08f0972 commit bd42765

3 files changed

Lines changed: 62 additions & 17 deletions

File tree

docs/api/en/math/Box3.html

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,14 @@ <h3>[method:Boolean equals]( [param:Box3 box] )</h3>
121121
Returns true if this box and [page:Box3 box] share the same lower and upper bounds.
122122
</p>
123123

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

128129
Expands the boundaries of this box to include [page:Object3D object] and its children,
129130
accounting for the object's, and children's, world transforms.
130-
The function may result in a larger box than strictly necessary.
131+
The function may result in a larger box than strictly necessary (unless the precise parameter is set to true).
131132

132133
</p>
133134

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

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

271273
Computes a world-axis-aligned bounding box of an [page:Object3D] (including its children),
272274
accounting for the object's, and children's, world transforms.<br /><br />

src/math/Box3.js

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ class Box3 {
109109

110110
}
111111

112-
setFromObject( object ) {
112+
setFromObject( object, precise = false ) {
113113

114114
this.makeEmpty();
115115

116-
return this.expandByObject( object );
116+
return this.expandByObject( object, precise );
117117

118118
}
119119

@@ -188,7 +188,7 @@ class Box3 {
188188

189189
}
190190

191-
expandByObject( object ) {
191+
expandByObject( object, precise = false ) {
192192

193193
// Computes the world-axis-aligned bounding box of an object (including its children),
194194
// accounting for both the object's, and children's, world transforms.
@@ -201,24 +201,38 @@ class Box3 {
201201

202202
if ( geometry !== undefined ) {
203203

204-
if ( geometry.boundingBox === null ) {
204+
if ( precise && geometry.attributes != undefined && geometry.attributes.position !== undefined ) {
205205

206-
geometry.computeBoundingBox();
206+
const position = geometry.attributes.position;
207+
for ( let i = 0, l = position.count; i < l; i ++ ) {
207208

208-
}
209+
_vector.fromBufferAttribute( position, i ).applyMatrix4( object.matrixWorld );
210+
this.expandByPoint( _vector );
211+
212+
}
213+
214+
} else {
215+
216+
if ( geometry.boundingBox === null ) {
209217

210-
_box.copy( geometry.boundingBox );
211-
_box.applyMatrix4( object.matrixWorld );
218+
geometry.computeBoundingBox();
212219

213-
this.union( _box );
220+
}
221+
222+
_box.copy( geometry.boundingBox );
223+
_box.applyMatrix4( object.matrixWorld );
224+
225+
this.union( _box );
226+
227+
}
214228

215229
}
216230

217231
const children = object.children;
218232

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

221-
this.expandByObject( children[ i ] );
235+
this.expandByObject( children[ i ], precise );
222236

223237
}
224238

test/unit/src/math/Box3.tests.js

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ import { Vector3 } from '../../../../src/math/Vector3';
88
import { Matrix4 } from '../../../../src/math/Matrix4';
99
import { Mesh } from '../../../../src/objects/Mesh';
1010
import { BufferAttribute } from '../../../../src/core/BufferAttribute';
11-
import { BoxGeometry } from '../../../../src/geometries/BoxGeometry';
11+
import {
12+
BoxGeometry,
13+
BoxBufferGeometry,
14+
} from '../../../../src/geometries/BoxGeometry';
15+
import {
16+
SphereBufferGeometry,
17+
} from '../../../../src/geometries/SphereGeometry';
1218
import {
1319
negInf3,
1420
posInf3,
@@ -165,8 +171,31 @@ export default QUnit.module( 'Maths', () => {
165171

166172
} );
167173

168-
QUnit.test( 'clone', ( assert ) => {
174+
QUnit.test( 'setFromObject/Precise', ( assert ) => {
175+
176+
var a = new Box3( zero3.clone(), one3.clone() );
177+
var object = new Mesh( new SphereBufferGeometry( 1, 32, 32 ) );
178+
var child = new Mesh( new SphereBufferGeometry( 2, 32, 32 ) );
179+
object.add( child );
169180

181+
object.rotation.setFromVector3(new Vector3(0, 0, Math.PI / 4.0));
182+
183+
a.setFromObject( object );
184+
var rotatedBox = new Box3(
185+
new Vector3( - 2 * Math.SQRT2, - 2 * Math.SQRT2, - 2 ),
186+
new Vector3( 2 * Math.SQRT2, 2 * Math.SQRT2, 2 )
187+
);
188+
assert.ok( compareBox( a, rotatedBox ), "Passed!" );
189+
190+
a.setFromObject( object, true );
191+
var rotatedMinBox = new Box3(
192+
new Vector3( - 2, - 2, - 2 ),
193+
new Vector3( 2, 2, 2 )
194+
);
195+
assert.ok( compareBox( a, rotatedMinBox ), "Passed!" );
196+
} );
197+
198+
QUnit.test( 'clone', ( assert ) => {
170199

171200
var a = new Box3( zero3.clone(), one3.clone() );
172201

0 commit comments

Comments
 (0)