オイラー角のglm::vec3
として保存したOpenVRコントローラーの向きをglm::fquat
に変換しようとしていますが、結果が大きく異なり、ゲーム内の動作が間違っています(説明するのは難しいですが、オブジェクトの方向は狭い範囲の角度で正常に動作し、奇妙な軸で反転します)。
これは私の変換コードです:
// get `orientation` from OpenVR controller sensor data
const glm::vec3 eulerAnglesInDegrees{orientation[PITCH], orientation[YAW], orientation[ROLL]};
debugPrint(eulerAnglesInDegrees);
const glm::fquat quaternion{glm::radians(eulerAnglesInDegrees)};
const glm::vec3 result{glm::degrees(glm::eulerAngles(quaternion))};
debugPrint(result);
// `result` should represent the same orientation as `eulerAnglesInDegrees`
私はeulerAnglesInDegrees
とresult
が同じまたは同じ向きの同等の表現であることを期待しますが、明らかにそうではありません。これらは私が印刷するいくつかの例の値です:
39.3851 5.17816 3.29104
39.3851 5.17816 3.29104
32.7636 144.849 44.3845
-147.236 35.1512 -135.616
39.3851 5.17816 3.29104
39.3851 5.17816 3.29104
32.0103 137.415 45.1592
-147.99 42.5846 -134.841
上記のように、一部の方向範囲では変換は正しく行われますが、他の方向範囲では完全に異なります。
何が悪いのですか?
私は既存の質問を見て、いくつか試してみました ここにリストされているすべての可能な回転順序 、 四元数の共役 、およびピッチ/ヨーの反転などの他のランダムなものを試しました/ロール。期待した結果が得られなかった。
glm
?を使用して、元の方向を表すオイラー角を四元数に変換したり、元に戻したりするにはどうすればよいですか?
不一致のその他の例:
original: 4; 175; 26;
computed: -175; 4; -153;
difference: 179; 171; 179;
original: -6; 173; 32;
computed: 173; 6; -147;
difference: -179; 167; 179;
original: 9; 268; -46;
computed: -170; -88; 133;
difference: 179; 356; -179;
original: -27; -73; 266;
computed: -27; -73; -93;
difference: 0; 0; 359;
original: -33; 111; 205;
computed: 146; 68; 25;
difference: -179; 43; 180;
最終的なcomputed
の結果を修正するためのパターンを見つけようとしましたが、簡単に識別できるものはないようです。
GIF +動作のビデオ:
私の直感/現在の理解の視覚的表現:
tony の大体 advice に従い、試行錯誤とパターンの識別を行った後、変換後に元の値を復元する方法を見つけました。
ox
、oy
、およびoz
は、元のpitch、yaw、およびroll、変換前。
fx
、fy
、fz
は新しいpitch、yaw、およびroll度単位で、「オイラー->クォータニオン->オイラー」( glm::degrees(glm::eulerAngles(glm::normalize(quaternion)))
)を使用します。
if (oy > 90.f)
{
fx -= 180.f;
fy -= 180.f;
fy *= -1.f;
fz += 180.f;
if (ox > 0.f)
{
fx += 360.f;
}
}
上記のコードは、元の角度値と変換後の角度値を正確に一致させるようです。元の質問には答えますが、実際の問題は解決しません...別の角度にスムーズに補間するために、四元数に変換していました。ただし、glm::mix
変換結果の後のクォータニオン-再び-非常に予測できないローテーション。