マップに惑星全体を使用するゲームを作成しています。この手法を使用して球形の惑星をテッセレーションし、カメラコントロールを追加しています。
球の次元は1から-1であるため、球上の各点も正規化されたベクトルです。いつでも、球を構成する六角形のタイルの1つは、「選択された」タイルです。その後、プレーヤーは十字キーを使用して選択範囲を隣接するタイルに移動できます。また、アナログスティックを使用してカメラを個別に回転させることもできます
選択したタイルとカメラに関して2つのことを行う必要があります。まず、カメラに最も近いタイルに選択を切り替えることができる必要があります。次に、ハイライトされたタイルの中央にカメラを配置する必要があります
球は原点に配置され、カメラは点(0,0,1)に配置されます。グラフィックエンジンでは、カメラをX軸とY軸を中心に回転させることしかできないため、最初の問題を解決するために、クォータニオンを使用して点(0,0,1)をx軸とy軸を中心に回転させ、カメラがある3D空間:
private Quaternion quat = new Quaternion(0,0,0,0);
private double[] output = new double[4];
private double[] cam = new double[3];
private double camX = 0;
private double camY = 0;
private double camZ = 1;
private double[] getCamPosition(){
quat.setAxisAngle(1, 0, 0, Math.toRadians(-graphicsEngine.getRotationX()));
quat.RotateVector(camX, camY, camZ, output);
cam[0] = output[0];
cam[1] = output[1];
cam[2] = output[2];
quat.setAxisAngle(0, 1, 0, Math.toRadians(-graphicsEngine.getRotationY()));
quat.RotateVector(cam[0], cam[1], cam[2], output);
cam[0] = output[0];
cam[1] = output[1];
cam[2] = output[2];
return cam;
}
次に、各タイルの図心とカメラの位置の間の距離を比較し、新しく選択したタイルに最も近いタイルを取得します。
しかし、2番目の問題を解決するために、私は逆のことをしたいと思います。図心(すでに正規化されたベクトルの形式になっています)を取得し、カメラを中心に配置するために必要なXの周りの回転とYの周りの回転を調べます。
現時点では、カメラを(0,0,1)に回転させて戻し、X軸とY軸の(0,0,1)と図心の間の角度を取得し、それを使用してカメラを回転させています。 2回目:
private double[] outputArray = new double[2];
/**
* Cam is always (0,0,1)
*/
public void centreOnSelected(double camX, double camY, double camZ){
selectedTile.getCentroidAngles(outputArray);
outputArray[0] -= Math.atan2(camZ, camY);
outputArray[1] -= Math.atan2(camX, camZ);
// this determines if the centroid is pointing away from the camera
// I.e. is on the far side of the sphere to the camera point (0,0,1)
if(!selected.getCentroidDirectionY(camX, camZ)){
outputArray[0] = -Math.PI - outputArray[0];
}
graphicsEngine.rotateCam(Math.toDegrees(outputArray[0]), Math.toDegrees(outputArray[1]));
}
およびselected
(タイルクラス)
void getCentroidAngles(double[] outputArray){
outputArray[0] = Math.atan2(centroidZ, centroidY);
outputArray[1] = Math.atan2(centroidX, centroidZ);
}
問題は、これが機能しないことです(x軸は常に外れているようです)。角度を取得して回転する数学と関係があると確信しています。
注:グラフィックエンジンは最初にX軸を中心に回転し、次にY軸を中心に回転します。
gl.glRotatef(mRotateX, 1, 0, 0);
gl.glRotatef(mRotateY, 0, 1, 0);
図心はすべて正しい場所にあり、カメラは間違いなく正しい量だけ回転しているので、問題はグラフィックエンジンにあるのではないと確信しています。また、プログラムをステップスルーしてこれが機能することを確認したので、カメラを(0,0,1)に再配置することでもありません。
問題を説明するためのビデオも作成しました。
http://www.youtube.com/watch?v=Uvka7ifZMlE
これは何日も私を悩ませてきたので、これを修正するのに助けがあれば大歓迎です!
ありがとうジェームズ