Hello:
I’m learning the source code in Box3.js
.
The documentation says to pass precise = true
to get a more precise bounding box, but reading the source code I found that they all use the position
of the attribute
( the final call to setFromBufferAttribute
is also made in the computeBoundingBox
, passing in the position )
So can someone tell me why precise = true
and why it’s more precise? Thank you.
This is the relevant code.
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
object.updateWorldMatrix( false, false );
const geometry = object.geometry;
if ( geometry !== undefined ) {
if ( precise && geometry.attributes != undefined && geometry.attributes.position !== undefined ) {
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 ) {
geometry.computeBoundingBox();
}
_box.copy( geometry.boundingBox );
_box.applyMatrix4( object.matrixWorld );
this.union( _box );
}
}
computeBoundingBox() {
if ( this.boundingBox === null ) {
this.boundingBox = new Box3();
}
const position = this.attributes.position;
const morphAttributesPosition = this.morphAttributes.position;
if ( position && position.isGLBufferAttribute ) {
console.error( 'THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set "mesh.frustumCulled" to "false".', this );
this.boundingBox.set(
new Vector3( - Infinity, - Infinity, - Infinity ),
new Vector3( + Infinity, + Infinity, + Infinity )
);
return;
}
if ( position !== undefined ) {
this.boundingBox.setFromBufferAttribute( position );
// process morph attributes if present
if ( morphAttributesPosition ) {
for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
const morphAttribute = morphAttributesPosition[ i ];
_box.setFromBufferAttribute( morphAttribute );
if ( this.morphTargetsRelative ) {
_vector.addVectors( this.boundingBox.min, _box.min );
this.boundingBox.expandByPoint( _vector );
_vector.addVectors( this.boundingBox.max, _box.max );
this.boundingBox.expandByPoint( _vector );
} else {
this.boundingBox.expandByPoint( _box.min );
this.boundingBox.expandByPoint( _box.max );
}
}
}
} else {
this.boundingBox.makeEmpty();
}
if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
console.error( 'THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
}
}
setFromBufferAttribute( attribute ) {
let minX = + Infinity;
let minY = + Infinity;
let minZ = + Infinity;
let maxX = - Infinity;
let maxY = - Infinity;
let maxZ = - Infinity;
for ( let i = 0, l = attribute.count; i < l; i ++ ) {
const x = attribute.getX( i );
const y = attribute.getY( i );
const z = attribute.getZ( i );
if ( x < minX ) minX = x;
if ( y < minY ) minY = y;
if ( z < minZ ) minZ = z;
if ( x > maxX ) maxX = x;
if ( y > maxY ) maxY = y;
if ( z > maxZ ) maxZ = z;
}
this.min.set( minX, minY, minZ );
this.max.set( maxX, maxY, maxZ );
return this;
}