web-dev-qa-db-ja.com

Projectionを使用してThree.jsでワールド座標をスクリーン座標に変換する

Three.jsでの投影解除に関する優れたスタックの質問( 12 )、つまりブラウザーの(x、y)マウス座標を( x、y、z)Three.jsキャンバススペースの座標。ほとんどの場合、次のパターンに従います。

    var elem = renderer.domElement, 
        boundingRect = elem.getBoundingClientRect(),
        x = (event.clientX - boundingRect.left) * (elem.width / boundingRect.width),
        y = (event.clientY - boundingRect.top) * (elem.height / boundingRect.height);

    var vector = new THREE.Vector3( 
        ( x / WIDTH ) * 2 - 1, 
        - ( y / HEIGHT ) * 2 + 1, 
        0.5 
    );

    projector.unprojectVector( vector, camera );
    var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
    var intersects = ray.intersectObjects( scene.children );

私は逆のことを試みてきました-「画面から世界」空間に行く代わりに、「世界から画面」空間に行きます。 Three.jsでオブジェクトの位置がわかっている場合、画面上のオブジェクトの位置を確認するにはどうすればよいですか?

この問題に対する解決策は公開されていないようです。 これに関する別の質問がちょうどStackに表示されました ですが、著者は私にとっては機能していない関数で問題を解決したと主張しています。彼らのソリューションは投影されたレイを使用せず、2Dから3DへはunprojectVector()を使用するため、3Dから2DへのソリューションにはprojectVector()が必要になると確信しています。

この問題 Githubでも開かれています。

どんな助けも大歓迎です。

31
BishopZ

これで試してください:

var width = 640, height = 480;
var widthHalf = width / 2, heightHalf = height / 2;

var vector = new THREE.Vector3();
var projector = new THREE.Projector();
projector.projectVector( vector.setFromMatrixPosition( object.matrixWorld ), camera );

vector.x = ( vector.x * widthHalf ) + widthHalf;
vector.y = - ( vector.y * heightHalf ) + heightHalf;
34
mrdoob

最新のThree.js(r75)の場合、次の方法でベクターをスクリーンに投影できます。

var width = window.innerWidth, height = window.innerHeight;
var widthHalf = width / 2, heightHalf = height / 2;

var pos = object.position.clone();
pos.project(camera);
pos.x = ( pos.x * widthHalf ) + widthHalf;
pos.y = - ( pos.y * heightHalf ) + heightHalf;
7
dkobozev

deprecatedまたはwarningsログを取得するすべての人にとって、受け入れられる答えは、古いThree.jsバージョンに対するものです。これでさらに簡単になりました:

let pos = new THREE.Vector3();
pos = pos.setFromMatrixPosition(object.matrixWorld);
pos.project(camera);

let widthHalf = canvasWidth / 2;
let heightHalf = canvasHeight / 2;

pos.x = (pos.x * widthHalf) + widthHalf;
pos.y = - (pos.y * heightHalf) + heightHalf;
pos.z = 0;

console.log(pos);
6
martin

cannot情報を失うため、(x、y)座標を(x、y、z)座標に変換します。引用したのは、(x、y)によって生成されたレイと交差するシーン内のすべてのオブジェクト上のすべてのポイントを見つける方法です。

あなたが要求する「世界からスクリーン」への移行は、投影のすべてであり、単一のポイント(x、y、z)のレンダリングと同等です。あなたがすることは、投影行列をあなたのポイント(x、y、z)に適用することです。それはおそらく http://mrdoob.github.com/three.js/docs/49/#ProjectorProjector.projectVector(vector, camera)関数ですが、それが出力するという事実のためです3Dベクトル、私は次元の1つが0であるとしか仮定できず、無視できます。

0
ninjagecko