2017-08-24 14 views
5

私の3Dオブジェクトが使用する画面上の領域を把握する必要があります。3DオブジェクトのThreeJS 2D境界ボックス

私はGoogleに回答を試みましたが、成功しませんでした。

機能geometry.computeBoundingBox()は3D境界ボックスのみを返します。

これを2D境界ボックスに変換するにはどうすればよいですか?

+1

これは良い挑戦のようです。オブジェクトやカメラはアニメーション化されますか?もしそうなら、それはフレームごとに一度占める画面空間を計算する必要がありますか? – Marquizzo

+1

はい、それは実行されていないと私は非常に驚いています。どちらもアニメ化することができますが、私は考えています。 Brb。 – vaid

答えて

2

は、あなたは、単にそれらからスクリーン空間へのすべての頂点を変換して2次元バウンディングボックスを作成する必要があります

function computeScreenSpaceBoundingBox(mesh, camera) { 
    var vertices = mesh.geometry.vertices; 
    var vertex = new THREE.Vector3(); 
    var min = new THREE.Vector3(1); 
    var max = new THREE.Vector3(-1); 

    for (var i = 0; i < vertices.length; i++) { 
    var vertexWorldCoord = vertex.copy(vertices[i]).applyMatrix4(mesh.matrixWorld); 
    var vertexScreenSpace = vertexWorldCoord.project(camera); 
    min.min(vertexScreenSpace); 
    max.max(vertexScreenSpace); 
    } 

    return new THREE.Box2(min, max); 
} 

得Box2のは、正規化されたスクリーン座標にある[-1、1]。あなたのレンダラーの高さと幅の半分に乗じてピクセルを取得することができます:

function normalizedToPixels(coord, renderWidthPixels, renderHeightPixels) { 
    var halfScreen = new THREE.Vector2(renderWidthPixels/2, renderHeightPixels/2) 
    return coord.clone().multiply(halfScreen); 
} 

ここでのデモを参照してください。http://jsfiddle.net/holgerl/6fy9d54t/

EDIT:@WestLangleyからの提案により、内部ループでメモリ使用量を削減します

+1

1秒あたりに作成するインスタンスの数はいくつですか?タイトなループで 'new'や' clone() 'を呼び出さないでください。コードとフィドルをリファクタリングして単一のインスタンスを作成し、 'copy()'または 'set()'を使って再利用します。 – WestLangley

+0

良い点。私は内部ループを更新して、作成されたインスタンスを減らしました。バウンディングボックスを必要なだけ更新されたメッシュのプロパティにすることで、さらに最適化することができます。他にもいくつかの最適化があります。しかし、私は、元の質問にどのように答えられるかということを主なポイントとして、コードを読みやすいようにしたいと思います。 @WestLangley –

関連する問題