私は、ネットワークを介して電話のセンサーデータを読み取り、デバイスのマトリックスを計算するc++プログラムでAndroidのgetRotationMatrixの適応バージョンを使用しています。
この関数は正常に機能し、デバイスの向きを計算します。残念ながら、Ogre3dの軸システムはデバイスとは異なります。したがって、x軸を中心とした回転は正常に機能しますが、y軸とz軸は間違っています。デバイスレベルを保持し、北を指します(単位行列)。私が投げるとき、回転は正しいです。しかし、私が転がったり横揺れたりすると、回転が交互になります。Ogre3dではロールはヨーであり、その逆も同様です。
(Ogre3d) ([Device][5])
^ +y-axis ^ +z-axis
* *
* *
* * ^ +y-axis
* * *
* * *
* * *
************> + x-axis ************> +x-axis
*
*
v +z-axis
2軸システムをざっと見ると、Ogreのシステム(左側)は、基本的に、デバイスのシステムがx軸を中心に反時計回りに90度回転しているように見えます。
マトリックスを計算する前にセンサー値を最初に割り当てるときに、さまざまな組み合わせを試してみましたが、組み合わせが正しく機能していないようです。回転行列getRotationMatrix()がOgre3Dで正しく表示されることを確認するにはどうすればよいですか?
参考までに、行列を計算する関数は次のとおりです。
bool getRotationMatrix() {
//sensor data coming through the network are
//stored in accel(accelerometer) and mag(geomagnetic)
//vars which the function has access to
float Ax = accel[0]; float Ay = accel[1]; float Az = accel[2];
float Ex = mag[0]; float Ey = mag[1]; float Ez = mag[2];
float Hx = Ey * Az - Ez * Ay;
float Hy = Ez * Ax - Ex * Az;
float Hz = Ex * Ay - Ey * Ax;
float normH = (float) Math::Sqrt(Hx * Hx + Hy * Hy + Hz * Hz);
if (normH < 0.1f) {
// device is close to free fall (or in space?), or close to
// magnetic north pole. Typical values are > 100.
return false;
}
float invH = 1.0f / normH;
Hx *= invH;
Hy *= invH;
Hz *= invH;
float invA = 1.0f / (float) Math::Sqrt(Ax * Ax + Ay * Ay + Az * Az);
Ax *= invA;
Ay *= invA;
Az *= invA;
float Mx = Ay * Hz - Az * Hy;
float My = Az * Hx - Ax * Hz;
float Mz = Ax * Hy - Ay * Hx;
//ogre3d's matrix3 is column-major whereas getrotatinomatrix produces
//a row-major matrix thus i have tranposed it here
orientation[0][0] = Hx; orientation[0][2] = Mx; orientation[0][2] = Ax;
orientation[1][0] = Hy; orientation[1][3] = My; orientation[1][2] = Ay;
orientation[2][0] = Hz; orientation[2][4] = Mz; orientation[2][2] = Az;
return true;
}