2013-03-19 114 views

回答

15

對於任何形狀的幾何對象,都有一個boundingBox屬性。該屬性擁有一個THREE.Box3對象。這個Box3對象由兩個THREE.Vector3對象組成,minmax

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 + ')'); 

對於更復雜的形狀,如來自JSON Object files加載,邊界框屬性默認未定義的。它必須明確計算。

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 + ')'); 
} 
+1

謝謝Jodes。但是,我仍然不清楚如何爲Object3D類自身獲取邊界框。我是否需要遍歷所有子節點並查找「網格」類型,保存邊界框並比較和計算最大x/y/z值? – larryq 2013-03-19 15:06:25

+0

如果您想執行例如鼠標選擇,你可以使用'geometry.boundingBox'中的值並創建類似如下的框:'var box = new THREE.Mesh(new THREE.CubeGeometry(width,height,depth),new THREE.MeshLambertMaterial({顏色:0xFFF0FF}));'我傾向於把它附加到'Object3D'或'Mesh'上。然後,您可以對該對象進行光線投射或執行碰撞(或其他)。 – 2014-02-20 01:01:45

8

是的,你需要這樣的事:

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); 
} 

編輯:

此方法之前BoundingBoxHelper()BoxHelper()是可用

+0

我只想補充一點,你可能想要做一些類似於minX = Math.min(minX,bBox.min.x + mesh.position.x);用於計算整個盒子,以防萬一對象的某些孩子被放置在除(0,0,0)以外的位置 – Cabbibo 2014-06-04 20:27:23

21

如果你想在邊框作爲對象出現在場景中的位置和大小,嘗試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); 

幾何體上的.boundingBox沒有考慮平移,旋轉或縮放可以應用於父網等,我發現它非常難以調整爲手動,但幫手爲你做。

+1

請注意,_BoundingBoxHelper_已被[棄用](https://github.com/mrdoob/ three.js/issues/10143),並取代[BoxHelper](https:// threejs。組織/文檔/ index.html的#API /助理/ BoxHelper)。 – 2017-11-01 02:10:39

45

您不需要遍歷對象的所有子節點;在庫中有一個方法可以執行此操作:THREE.Box3#setFromObjectsee the docs。例如,你可以這樣做:

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

得到的obj邊框,包括其所有的孩子,佔任何平移,旋轉等

注意,BoundingBox助手用來在場景中繪製邊界框,而不是僅僅計算某個對象的邊界框。

+3

這是這裏最好的答案 – Jared 2014-11-24 20:20:04

+0

感謝這個偉大而簡潔的答案。只是想指出,鏈接到文檔更改爲[見文檔](https://threejs.org/docs/#api/math/Box3)雖然 – burnedikt 2017-09-06 16:21:08