私はhtml5とTHREE.jsを使用してゲームを作成していますが、カメラは「YXZ」のオイラー次数で回転します。
これは、カメラが頭のように上下左右に回転するためです。一人称視点と同様。
このオイラー順序では、camera.rotationのzプロパティは使用されません(常に0)。 xはラジアンでピッチまたは緯度を指定するために使用され、yは経度を表すために使用されます。
私はユーザーの周りを球形に動く多数のターゲットを持っています。カメラは常にこの球の中心にあります。球の半径が1000であるとしましょう。
私の目的は、カメラの位置とターゲットの位置の間の角度を計算することです。
2つのベクトル間の角度を計算するこのコードを記述しました。
var A = new THREE.Vector3(1,0,0);
var B = new THREE.Vector3(0,1,0);
var theta = Math.acos( A.dot(B) / A.length() / B.length() );
// theta = PI/2;
ターゲットのベクトルがあります(targets [0] .position)。
問題は、カメラが見ている場所のベクトルを取得する方法を理解できないことです。
私はVector3.applyProjectionとapplyEulerのメソッドを見てきましたが、いじってみましたが、それでも良い結果は得られません。
投影が行われる前に、オイラー次数を最初に「XYZ」に戻す必要があると思いますか?私は試しましたが、これを行う方法がわかりません。ドキュメントを理解するのはかなり難しいです。
カメラが真っ直ぐに向いている場合は、中心から現在の回転方向にRADIUSの距離)のベクトルを取得する必要があるとします。
だから私は計算ができる2つのベクトルになるでしょう!
カメラは内部の負のZ軸を見下ろしています。したがって、負のz軸を指すベクトルを作成します。
var vector = new THREE.Vector3( 0, 0, - 1 );
次に、カメラに適用されているベクトルに同じ回転を適用します。
vector.applyQuaternion( camera.quaternion );
次のように、ターゲットに対するラジアンの角度を取得できます。
angle = vector.angleTo( target.position );
編集:カメラが次のように見える方向を取得できます。
var vector = new THREE.Vector3(); // create once and reuse it!
...
camera.getWorldDirection( vector );
注:結果を保存するvector
を渡すことにより、メソッドが呼び出されるたびに新しいTHREE.Vector3
をインスタンス化する必要がなくなります。
Three.js r.107に更新しました
私は船長の明白な質問を理解しようと長い間費やしました。
これは私にとって最終的にどのように機能したかです:
vector = camera.getWorldDirection();
theta = Math.atan2(vector.x,vector.z);
シータはラジアンです。これは、カメラの向きと同じ向きにゲームのキャラクターを向ける方法です。 getWorldDirection()は、カメラのかなり新しいオプションです。
ふわふわバニーはそれを釘付けにした。彼の素晴らしいアイデアを少し変更するだけで、回転を度単位で取得できます。
var vector = camera.getWorldDirection();
angle = THREE.Math.radToDeg( Math.atan2(vector.x,vector.z) );
コメントはできませんが、ふわふわバニーの答えは完璧に機能します。 getWorldDirection()
そして、そのベクトルをラジアンに変更する方法です。