{{ message }}

# BoundingBox of a compounded Object3D object? #581

Closed
opened this issue Sep 26, 2011 · 15 comments
Closed

# BoundingBox of a compounded Object3D object?#581

opened this issue Sep 26, 2011 · 15 comments
Labels

### roundrobin commented Sep 26, 2011

 Hello Guys, i hava a Object3D instance, which includes a CubeGeometry and a TextGeometry. My Question: It is possible to get the bounding box of this compounded geometries? i ask this, because i saw that the Object3D class doesn't have a boundingBox-Method and i have no approach to calculate it for all objects include in the Object3D container. My idea was it to center the camera depending on the Object3D- containers centeroid and therefore i have to know the boundingBox. Greetings roundrobin The text was updated successfully, but these errors were encountered:

### mrdoob commented Sep 26, 2011

 `Object3D` doesn't have a method for computing the bounding box, but `Geometry` does. With that out of the way, you just need to follow this.

### roundrobin commented Sep 26, 2011

 thanks so far. maybe i ask wrong, my itention was to get the bounding box of the two objects. I know how to calculate the bounding box for one geometry, but when i have a compounded 3D objects, how i can calculate the bounding box, for example of two cubes. Or it is neccecary to merge the objects before to one geometry? i hope you got my point :) it`s difficult to explain.
closed this Sep 26, 2011
reopened this Sep 26, 2011

### mrdoob commented Sep 26, 2011

 I see. I guess the only way right now is to compare all the bounding boxes and do some `max()` and `min()`s with all the values.

### roundrobin commented Sep 26, 2011

 okay thanks. I'll post my solution if I am successfully
closed this Sep 26, 2011

### richardcarhart commented Nov 1, 2012

 Here's my solution. Simply pass the object to this function and it will look through it's children to compute the height/width of the object and assign a height and width property to the object. ```calculateDimensions(myObject); ... /* * Get the size of the compound object by computing the bounding box and getting the max/min of each of its children */ function calculateDimensions(_object) { var absoluteMinX = 0, absoluteMaxX = 0, absoluteMinY = 0, absoluteMaxY = 0, absoluteMinZ = 0, absoluteMaxZ = 0; for (var i = 0; i < _object.children.length; i++) { _object.children[i].geometry.computeBoundingBox(); absoluteMinX = Math.min(absoluteMinX,_object.children[i].geometry.boundingBox.min.x); absoluteMaxX = Math.max(absoluteMaxX,_object.children[i].geometry.boundingBox.max.x); absoluteMinY = Math.min(absoluteMinY,_object.children[i].geometry.boundingBox.min.y); absoluteMaxY = Math.max(absoluteMaxY,_object.children[i].geometry.boundingBox.max.y); absoluteMinZ = Math.min(absoluteMinZ,_object.children[i].geometry.boundingBox.min.z); absoluteMaxZ = Math.max(absoluteMaxZ,_object.children[i].geometry.boundingBox.max.z); } // set generic height and width values _object.depth = (absoluteMaxX - absoluteMinX) * _object.scale.x; _object.height = (absoluteMaxY - absoluteMinY) * _object.scale.y; _object.width = (absoluteMaxZ - absoluteMinZ) * _object.scale.z; // remember the original dimensions if (_object.originalDepth === undefined) _object.originalDepth = _object.depth; if (_object.originalHeight === undefined) _object.originalHeight = _object.height; if (_object.originalWidth === undefined) _object.originalWidth = _object.width; console.log("Depth: " + _object.depth + ", Height: " + _object.height + ", Width: " + _object.width); } ```

### NickLarsen commented Feb 23, 2013

 I came across this looking for the same thing and ended up settling on this: ``````function getCompoundBoundingBox(object3D) { var box = null; object3D.traverse(function (obj3D) { var geometry = obj3D.geometry; if (geometry === undefined) return; geometry.computeBoundingBox(); if (box === null) { box = geometry.boundingBox; } else { box.union(geometry.boundingBox); } }); return box; } ``````

### mrdoob commented Feb 24, 2013

 @NickLarsen Looks good!

### PanChan commented Jun 18, 2013

 I have exactly the same problem and the same idea as roundrobin, two years ago. The solution of @NickLarsen looks really good, like @mrdoob said, but there is a big problem... I'll try to explain it. In my scene there is always one Object3D which contains all geometries. For example I have 8 Spheres with different radius and different y-coordinate. They are all located at x=0 and z=0. Then I tried to compute the whole boundingbox with the function from NickLarsen, but the result was very strange. To find the error, I logged all the single bounding boxes to the console: ({min:{x:-10, y:-10, z:-10}, max:{x:10, y:10, z:10}}) ({min:{x:-20, y:-20, z:-20}, max:{x:20, y:20, z:20}}) ({min:{x:-7, y:-7, z:-7}, max:{x:7, y:7, z:7}}) ({min:{x:-18, y:-18, z:-18}, max:{x:18, y:18, z:18}}) ({min:{x:-15, y:-15, z:-15}, max:{x:15, y:15, z:15}}) ({min:{x:-3, y:-3, z:-3}, max:{x:3, y:3, z:3}}) ({min:{x:-10, y:-10, z:-10}, max:{x:10, y:10, z:10}}) ({min:{x:-25, y:-25, z:-25}, max:{x:25, y:25, z:25}}) As you can see, the bounding boxes are always calculated in the local coordinate system of the single sphere. And when you union them, it makes no sense! How can I get the boundingbox in world coordinates to get the real boundingbox of my Object3D ?

### WestLangley commented Jun 18, 2013

 In the r.59dev branch, see `Box3.setFromObject( object )`.

### NickLarsen commented Jun 19, 2013

 @PanChan you need to percolate your transformations before you run this and it will work as intended. In my actual use of this, I clone the geometry for each object and apply the transformations to it before computing the bounding box. You can see my actual implementation here. I'm pretty noob when it comes to this stuff though, so take my implementation with a good dose of skepticism.

### PanChan commented Jun 19, 2013

 @NickLarsen I found another solution which seems to work. After computing the boundingbox, I translate it to the world system: ``````var bb = geometry.boundingBox; bb.translate(obj3D.localToWorld( new THREE.Vector3()));`````` Don't know if it's a good solution, but it works for now. Think I'm waiting for the new revision with the professional solution ;) Thanks for the explanation!

### asg-3d commented Nov 12, 2013

 Using @NickLarsen solution in my project I'm a bit optimized calculation for cases where the bounding box of the object already exists, and thus calculate it again is not necessary. ```function getComplexBoundingBox(object3D) { var box = null; object3D.traverse(function(obj3D) { if (obj3D.matrixWorldNeedsUpdate) obj3D.updateMatrixWorld(); var geometry = obj3D.geometry; // If current is not a geometry (THREE.Geometry), proceed to the next one if (geometry === undefined) return null; // If this object is already bounding box, then use it if (geometry.boundingBox) { var workableBox = geometry.boundingBox.clone(); // Move the resulting bounding box to the position of the object itself workableBox.applyMatrix4(obj3D.matrixWorld); if (box === null) { box = workableBox; } else { box.union(workableBox); } // If there is no bounding box for current object - creating } else { var workableGeometry = geometry.clone(); // Move the resulting geometry in the position of the object itself workableGeometry.applyMatrix(obj3D.matrixWorld); // Calculate the bounding box for the resulting geometry workableGeometry.computeBoundingBox(); if (box === null) { box = workableGeometry.boundingBox; } else { box.union(workableGeometry.boundingBox); } } }); return box; }``` 5 IF conditions - it is certainly not an example of good code, but what to do, better yet I have not worked out? :)

### danielribeiro commented Nov 12, 2013

 This is a really old thread. Nowadays you can just new `new THREE.Box3().setFromObject(object3d)`

### asg-3d commented Nov 12, 2013

 I will try this method, thanks!

### danielribeiro commented Nov 12, 2013

 No problem. I went through this realization a few months ago myself: danielribeiro/three-hub@859f148#diff-0dad6abd7a4801d561b83deddedc1baa