可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm loading an OBJ file using Three.js and OBJLoader.js. This returns a Three.Object3D object, which has what you'd expect from a 3D model (position vector, up vector...)
What I can't figure out is how to get a bounding box for it-- is this possible?
回答1:
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.
回答2:
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.
回答3:
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 + ')' ); }
回答4:
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