web-dev-qa-db-ja.com

three.js Object3Dから境界ボックスを取得する方法はありますか?

Three.jsおよびOBJLoader.jsを使用してOBJファイルをロードしています。これはThree.Object3Dオブジェクトを返します。これには、3Dモデルに期待するものがあります(位置ベクトル、アップベクトルなど)。

私が理解できないのは、そのための境界ボックスを取得する方法です-これは可能ですか?

44
larryq

オブジェクトのすべての子を反復処理する必要はありません。ライブラリにはこれを行うメソッドがあります:THREE.Box3#setFromObjectドキュメントを参照 。たとえば、次のことができます。

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

すべての子を含むobjのバウンディングボックスを取得し、変換、回転などを考慮します。

BoundingBoxヘルパーは、オブジェクトのバウンディングボックスを計算するためだけではなく、シーンにバウンディングボックスを描画するためのものです。

71
caseygrun

境界ボックスの位置とサイズが必要な場合オブジェクトがシーンに表示されるとき、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ジオメトリ上の親メッシュなどに適用される可能性のある平行移動、回転、スケーリングは考慮されません。手動で調整するのは非常に難しいことがわかりましたが、ヘルパーがそれを行います。

27
ammulder

形状の場合、そのジオメトリオブジェクトには、boundingBoxプロパティがあります。このプロパティはTHREE.Box3オブジェクト。この Box3オブジェクトは2つのTHREE.Vector3オブジェクト、minおよび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 + ')' );

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

はい、次のようなものが必要です。

_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()が使用可能になる前です。

12
gaitat