Three.js: unproject-特定の3Dオブジェクトの「画面(上、左)」で実際の位置を取得するにはどうすればよいですか?

作成日 2011年01月04日  ·  21コメント  ·  ソース: mrdoob/three.js

例として、画面の(x、y)上の1つのポイントを「3d」のポイントに投影する方法があることを私は知っていました。 しかし、私はそれをどのように翻訳し直す​​のか理解できません。 手がかりをありがとう。

Question

最も参考になるコメント

アップグレード後も誰かがこれを必要とする場合...

function screenXY(obj){

  var vector = obj.clone();
  var windowWidth = window.innerWidth;
  var minWidth = 1280;

  if(windowWidth < minWidth) {
    windowWidth = minWidth;
  }

  var widthHalf = (windowWidth/2);
  var heightHalf = (window.innerHeight/2);

  vector.project(camera);

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

  return vector;

};

全てのコメント21件

おそらくプロジェクターを使用していますが、MrDoobは明らかにこれについてもっと知っています:)

ええと、多分私たちはobject3d.screenを持っていて、それはVector2なり、すべてのレンダリングでそれを更新する必要がありますか?

そのobject3D.screenVectorが、すべてのobject3Dのobject3D.positionを2Dに変換するためにのみ使用される場合、object3D.screenの値が小さすぎないでしょうか。 つまり、位置x、y、zの任意のメッシュの任意の点x、y、zを2D座標に変換できる方が便利だと思います。

つまり、すべてのオブジェクトのすべての3D位置を事前に計算することは不可能です。

たとえば、Vector3(シーン内のポイントを表す)またはVector3とオブジェクト(Vector3がオブジェクト上のポイントを表す)のいずれかを受け取る関数THREE.3dto2d()あると便利です。
次に、この関数はシーン内の3D位置を計算します。
最後に、カメラ、その位置、回転、projectionMatrixなどを取得し、ポイントを2Dに変換します。

カメラも関数のパラメータにすべきだと思います...

ええと... Projector.projectSceneちょっとそれはすでにやっています;)

ほら、私それがプロジェクターだと

それを使った例はありますか?

うーん...まだ...これらの関数はレンダラーで使用するように設計されています...元のオブジェクトとは関係なくレンダリングする要素のリストを返します。 たぶん、元のオブジェクトへのリンクをいくつか置くだけでいいのかもしれません...うーん、もう少し考える必要があります。

私は現在休暇中ですが、戻ってきたらすぐに(来週)レンズフレアのデモ(または何か)を行います。

確かに、あなたの休日を楽しんでください、そして私は新しいデモを楽しみにしています! :-)

うーん、これは私(r32)で機能していましたが、r35では機能しなくなりました。

  toScreenXY: function(position, camera, jqdiv) {
    // converts 3D position to screen coords
    var pos = position.clone();
    projScreenMat = new THREE.Matrix4();
    projScreenMat.multiply( camera.projectionMatrix, camera.matrix);
    projScreenMat.multiplyVector3(pos);
    return { x: (pos.x+1)*jqdiv.width()/2 + jqdiv.offset().left, 
             y:(-pos.y+1)*jqdiv.height()/2 +jqdiv.offset().top }; 
  },

projScreenMat.multiplyVector3(pos);後のposは、以前は-1と1(ビューの中心で(0,0))の間で制限されていましたが、現在は予期しないように変化しているようです。

ええ、 camera.matrixcamera.matrixWorldInverse置き換える必要があります。
これで試してください:

toScreenXY: function ( position, camera, jqdiv ) {

    var pos = position.clone();
    projScreenMat = new THREE.Matrix4();
    projScreenMat.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
    projScreenMat.multiplyVector3( pos );

    return { x: ( pos.x + 1 ) * jqdiv.width() / 2 + jqdiv.offset().left,
         y: ( - pos.y + 1) * jqdiv.height() / 2 + jqdiv.offset().top };

}

うん、うまくいった、マトリックスの変更について知りませんでした。 この射影関数がalivediseの質問に答えてくれることを願っています。

3DCubeに関して私の質問をするのは正しいスレッドだと思います。 クリック可能な面でキャンバスに描かれた立方体があります。 立方体はX軸とY軸を中心に自由に回転しています。 私が欲しいのは、ユーザーがマウスを離したときに最も前面を取得し、自動的に回転して完全に見えるようにすることです。 この文脈での助けは非常にありがたいです。

ありがとうございました。

@ imrantariq2011 :これはこの問題とはあまり関係ありません。新しい問題を開いてもよろしいですか? ありがとう。

テクスチャマッピングの目的で、特定の面の各頂点のx、y画面座標を取得できるようにしたいと思います。

上記(toScreenXY:関数)を使用してこれを行う方法を確認できますが、最初に、特定の面のワールド変換(スケーリング、変換、回転)された頂点が必要です。 Projector.projectSceneをしばらく見てきましたが、上記の目標を達成するためのより簡単な方法があり、object.matrixWorld.getPosition()が顔の頂点ではなくオブジェクトの重心を取得するように見えるのではないかと思います。

ええ、上記のコードはの1つです。 .projectScene()自体からコードのビットを抽出するのが最善であれば、多くのポイントを投影する必要がある場合。

ここに来る人々はこれについて知りたいかもしれません:

https://github.com/zachberry/threejs-tracking-3d-to-2d

私はこれを使用します、それは動作します:

関数toScreenXY(pos3D)
{{
varプロジェクター=新しいTHREE.Projector();
var v =プロジェクター.projectVector(pos3D、カメラ);
var percX =(vx + 1)/ 2;
var percY =(-vy + 1)/ 2;
var left = percX * window.innerWidth;
var top = percY * window.innerHeight;

新しいTHREE.Vector2(left、top);を返します。
}

2014年8月1日(金曜日) 11:24で、アルテムFitiskinの[email protected]書きました:

toScreenXYを使用すると、非常に大きな値が得られます。
console.log(pos):// x:-1474.1436403989792、y:-730.829023361206、z:3.0004000663757324
そしてそれをjqdivで乗算した後、関数は非常に大きなxとyを返します。
私は何を間違っているのですか?

このメールに直接返信するか、GitHubで表示してください。

@arieljake

ガイドラインに記載されてstackoverflowに送信する必要があります。 このボードはバグと機能リクエスト用です。

結構です...それでも、ドゥーブ氏自身がコードを書いたので、何が得られますか?

@ arieljake #1979

アップグレード後も誰かがこれを必要とする場合...

function screenXY(obj){

  var vector = obj.clone();
  var windowWidth = window.innerWidth;
  var minWidth = 1280;

  if(windowWidth < minWidth) {
    windowWidth = minWidth;
  }

  var widthHalf = (windowWidth/2);
  var heightHalf = (window.innerHeight/2);

  vector.project(camera);

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

  return vector;

};

わかりました、非常に古い問題ですが、ネストされたオブジェクトがあり、上記のコードでは機能しませんでした。
私の場合は、レンダリング後にネストされたオブジェクトの実際のx-and-y(およびz)位置が必要だったので、上記の例を採用しました。
ご注意ください:

  1. 上記の例のobject.positionだけでなく、オブジェクト全体を引数として指定します。
  2. また、これはレンダラーがその仕事をして呼び出した後にのみ機能します
  3. ネストされていないオブジェクトに対しても機能しますが、いくつかの計算が多すぎます。
  4. また、domElementsまたはzSortラベルを並べ替えるために使用できるscreen-Zも提供します。
    screen-zの相対値は、カメラ/レンダラーの前面と背面のクリッピングプレーンに対して、0から1の間であり、これは私の目的(並べ替え)には問題なく機能します。
  5. renderer.domElement.widthとrenderer.domElement.heightによって、レンダラーの現在の幅と高さを取得できます。
scene.updateMatrixWorld(); 

そして

parent.updateMatrixWorld(); 

`` `js
関数nestedObjecttoScreenXYZ(obj、camera、width、height)
{{
var vector = new THREE.Vector3();
vector.setFromMatrixPosition(obj.matrixWorld);
var widthHalf =(width / 2);
var heightHalf =(height / 2);
vector.project(camera);
vector.x =(vector.x * widthHalf)+ widthHalf;
vector.y =-(vector.y * heightHalf)+ heightHalf;
戻りベクトル;
};



typical call:
```js
var screenpos=NestedObjecttoScreenXY(object,camera,renderer.domElement.width,renderer.domElement.height,true);

誰かが同じ問題に遭遇した場合に備えて。

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

seep picture seep  ·  3コメント

Horray picture Horray  ·  3コメント

makc picture makc  ·  3コメント

boyravikumar picture boyravikumar  ·  3コメント

akshaysrin picture akshaysrin  ·  3コメント