Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to get a bounding box from a three.js Object3D?

People also ask

What is a bounding box used for?

A bounding box is an imaginary rectangle that serves as a point of reference for object detection and creates a collision box for that object. Data annotators draw these rectangles over images, outlining the object of interest within each image by defining its X and Y coordinates.

What is a bounding box JS?

¶ A bounding box is a box with the smallest possible measure (area for 2D or volume for 3D) for a given geometry or a set of points.

What is a bounding box 3D?

A bounding box is a rectangle that contains your entire 3D model.


You don't need to iterate over all children of the object; there's a method in the library to do this: THREE.Box3#setFromObject: see the docs. For example, you can do:

var bbox = new THREE.Box3().setFromObject(obj);

to get the bounding box of obj, including all of its children, and accounting for any translations, rotations, etc.

Note that the BoundingBox helper is intended to draw a bounding box in the scene, not for just calculating the bounding box of some object.


If you want the bounding box position and size as the object appears in the scene, try the BoundingBoxHelper:

var helper = new THREE.BoundingBoxHelper(someObject3D, 0xff0000);
helper.update();
// If you want a visible bounding box
scene.add(helper);
// If you just want the numbers
console.log(helper.box.min);
console.log(helper.box.max);

The .boundingBox on the geometry doesn't account for translations, rotations, or scaling that may be applied to the parent mesh and etc. and I found it very difficult to adjust for that manually, but the helper does it for you.


For any shape, on its geometry object, there is a boundingBox property. This property holds a THREE.Box3 object. This Box3 object consists of two THREE.Vector3 objects, min and max.

var geometry = new THREE.CylinderGeometry(...);
var material = new THREE.LineBasicMaterial(...);
var mesh = new THREE.Mesh(geometry, material);

var boundingBox = mesh.geometry.boundingBox.clone();
alert('bounding box coordinates: ' + 
    '(' + boundingBox.min.x + ', ' + boundingBox.min.y + ', ' + boundingBox.min.z + '), ' + 
    '(' + boundingBox.max.x + ', ' + boundingBox.max.y + ', ' + boundingBox.max.z + ')' );

For more complex shapes, like those loaded from JSON Object files, the bounding box property is undefined by default. It must be computed explicitly.

var loader = new THREE.ObjectLoader();
loader.load(imagePath, function(object){

    geometry = object.children[0].children[0].geometry;  // substitute the path to your geometry

    geometry.computeBoundingBox();  // otherwise geometry.boundingBox will be undefined

    var boundingBox = geometry.boundingBox.clone();
    alert('bounding box coordinates: ' + 
        '(' + boundingBox.min.x + ', ' + boundingBox.min.y + ', ' + boundingBox.min.z + '), ' + 
        '(' + boundingBox.max.x + ', ' + boundingBox.max.y + ', ' + boundingBox.max.z + ')' );
}

Yes you would need something like this:

if (object instanceof THREE.Object3D)
{
    object.traverse (function (mesh)
    {
        if (mesh instanceof THREE.Mesh)
        {
            mesh.geometry.computeBoundingBox ();
            var bBox = mesh.geometry.boundingBox;

            // compute overall bbox
            minX = Math.min (minX, bBox.min.x);
            minY = Math.min (minY, bBox.min.y);
            minZ = Math.min (minZ, bBox.min.z);
            maxX = Math.max (maxX, bBox.max.x);
            maxY = Math.max (maxY, bBox.max.y);
            maxZ = Math.max (maxZ, bBox.max.z);
        }
    });

    var bBox_min = new THREE.Vector3 (minX, minY, minZ);
    var bBox_max = new THREE.Vector3 (maxX, maxY, maxZ);
    var bBox_new = new THREE.Box3 (bBox_min, bBox_max);

    scene.add (object);
}

EDIT:

This method is before the BoundingBoxHelper() or BoxHelper() were available