大家好,
我有一个Object3D实例,其中包括CubeGeometry和TextGeometry。 我的问题:有可能获得
这种复合几何的边界框? 我问这个问题,因为我看到Object3D类没有boundingBox-Method
而且我没有办法为包括在Object3D容器中的所有对象计算它。
我的想法是根据Object3D容器的中心类来使相机居中,因此我必须知道boundingBox。
问候roundrobin
到目前为止,谢谢。 也许我问错了,我的目的是要得到两个对象的边界框。 我知道如何计算一个几何的边界框,但是当我有一个复合3D对象时,如何计算边界框,例如两个立方体。 还是必须先将对象合并为一个几何体?
我希望你明白我的意思:)这很难解释。
我懂了。 我想现在唯一的方法是比较所有边界框,并用所有值做一些max()
和min()
s。
好的谢谢。 如果成功,我会发布解决方案
这是我的解决方案。 只需将对象传递给此函数,它就会查看其子元素以计算对象的高度/宽度,并为该对象分配height和width属性。
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);
}
我在寻找相同的东西时遇到了这个问题,最终解决了这个问题:
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;
}
@NickLarsen看起来不错!
我有两年前与roundrobin完全相同的问题和相同的想法。 @NickLarsen的解决方案看起来非常好,就像@mrdoob所说的那样,但是有一个大问题……我将尽力解释。
在我的场景中,总是有一个包含所有几何图形的Object3D。 例如,我有8个球体,它们具有不同的半径和不同的y坐标。 它们都位于x = 0和z = 0。
然后,我尝试使用NickLarsen的函数计算整个边界框,但结果非常奇怪。 为了找到错误,我将所有单个边界框都记录到控制台:
({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}})
({最小:{x:-7,y:-7,z:-7},最大:{x:7,y:7,z:7}})
({min:{x:-18,y:-18,z:-18},max:{x:18,y:18,z:18}})
({最小:{x:-15,y:-15,z:-15},最大:{x:15,y:15,z:15}})
({最小:{x:-3,y:-3,z:-3},最大:{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}})
如您所见,边界框始终在单个球体的局部坐标系中计算。 当您合并它们时,这没有任何意义! 如何获得世界坐标系中的边界框以获取Object3D的真实边界框?
在r.59dev分支中,请参阅Box3.setFromObject( object )
。
@PanChan您需要先对转换进行渗透,然后再运行它,它将按预期工作。 在此的实际使用中,我为每个对象克隆了几何图形,并在计算边界框之前对其应用了转换。 您可以在这里看到我的实际实现。 不过,对于这些东西,我还是个菜鸟,所以请对我的实现持相当怀疑的态度。
@NickLarsen我发现了另一个
var bb = geometry.boundingBox;
bb.translate(obj3D.localToWorld( new THREE.Vector3()));
不知道这是否是一个很好的解决方案,但它现在可以使用。 认为我正在等待具有专业解决方案的新版本;)感谢您的解释!
在我的项目中使用@NickLarsen解决方案,对于对象的边界框已经存在的情况,我进行了一些优化计算,因此无需再次进行计算。
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条件-肯定不是好的代码示例,但是该怎么做,更好的是我还没有解决? :)
这是一个非常老的线程。 如今,您可以新建new THREE.Box3().setFromObject(object3d)
我会尝试这种方法的,谢谢!
没问题。 我几个月前亲自经历了这种认识: https :
最有用的评论
我在寻找相同的东西时遇到了这个问题,最终解决了这个问题: