7

THREE.Frustum オブジェクトを処理するのに助けが必要です。

私の問題:

近/遠面の頂点を計算する必要があります。私はこれらのチュートリアルを見てきました

  1. http://www.lighthouse3d.com/tutorials/view-frustum-culling/view-frustums-shape/
  2. http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-extracting-the-planes/

そして、説明した手順を正確に実装するこの関数をスケッチしました(そうであることを願っています)(カメラが左右しか見えないと仮定して、左上/右上の頂点を取得するだけです):

        // Near Plane dimensions
        hNear = 2 * Math.tan(camera.fov / 2) * camera.near; // height
        wNear = hNear * camera.aspect; // width

        // Far Plane dimensions
        hFar = 2 * Math.tan(camera.fov / 2) * camera.far; // height
        wFar = hFar * camera.aspect; // width

getVertices : function() {
        var p = camera.position.clone();
        var l = getCurrentTarget(); // see below
        var u = new THREE.Vector3(0, 1, 0);

        var d = new THREE.Vector3();
        d.sub(l, p);
        d.normalize();

        var r = new THREE.Vector3();
        r.cross(u, d);
        r.normalize();

        // Near Plane center
        var dTmp = d.clone();
        var nc = new THREE.Vector3();
        nc.add(p, dTmp.multiplyScalar(camera.near));

        // Near Plane top-right and top-left vertices
        var uTmp = u.clone();
        var rTmp = r.clone();
        var ntr = new THREE.Vector3();
        ntr.add(nc, uTmp.multiplyScalar(hNear / 2));
        ntr.subSelf(rTmp.multiplyScalar(wNear / 2));

        uTmp.copy(u);
        rTmp.copy(r);
        var ntl = new THREE.Vector3();
        ntl.add(nc, uTmp.multiplyScalar(hNear / 2));
        ntl.addSelf(rTmp.multiplyScalar(wNear / 2));

        // Far Plane center
        dTmp.copy(d);
        var fc = new THREE.Vector3();
        fc.add(p, dTmp.multiplyScalar(camera.far));

        // Far Plane top-right and top-left vertices
        uTmp.copy(u);
        rTmp.copy(r);
        var ftr = new THREE.Vector3();
        ftr.add(fc, uTmp.multiplyScalar(hFar / 2));
        ftr.subSelf(rTmp.multiplyScalar(wFar / 2));

        uTmp.copy(u);
        rTmp.copy(r);
        var ftl = new THREE.Vector3();
        ftl.add(fc, uTmp.multiplyScalar(hFar / 2));
        ftl.addSelf(rTmp.multiplyScalar(wFar / 2));

getCurrentTarget : function() {
        var l = new THREE.Vector3(0, 0, -100);
        this.camera.updateMatrixWorld();
        this.camera.matrixWorld.multiplyVector3(l);
        return l;
    }

これはうまくいくようですが...

私の質問:

THREE.Frustum オブジェクトを使用して、より洗練された (おそらくより正しい) 方法で同じ結果を得ることができますか?

4

1 に答える 1

7

Three.Frustumは実際には役に立ちません。これは平面のセットです。幸いなことに、あなたのソリューションは正しいように見えますが、これについて考える簡単な方法があります。

ニア プレーンの右上隅は、次の座標を持つカメラ スペース内のポイントです。

var ntr = new THREE.Vector3( wNear / 2, hNear / 2, -camera.near );

wNearとの定義を使用しますhNear。どちらが正しいですか。

更新されていることを確認しcamera.matrixWorldたら、次のようにそのポイントをワールド座標に変換します。

camera.updateMatrixWorld();
ntr.applyMatrix4( camera.matrixWorld );

ここで、符号を反転して他の 3 つのコーナーを取得し、遠方平面の計算を繰り返します。

ほら、あなたは正しかった。より複雑なルートをたどっただけです。:-)

編集: three.js r.66 に更新

于 2012-08-18T20:28:16.673 に答える