まず、この質問がここでいいのか分からず、よくある質問を確認したところ、「他の人に説明してほしい」という質問があることがわかりました。
主な問題は、アプリケーションですべてのオブジェクトの回転を 2 回保存する必要があることです。これは一方で、私がBullet Physicsを使用する物理シミュレーションがその表現を保存するためです。一方、光やクエスト ターゲットなど、物理シミュレーションに含まれているかどうかに関係なく、すべてのオブジェクトに共通する回転を独自に保存します。物理ライブラリに加えて、GLM数学ライブラリを利用しています。
両方の表現を同期する必要があります。ちなみに、位置とスケールは問題ありません。難しいのは、物理シミュレーションは自分の表現が異なるため、単に値をコピーすることはできません。これらの違いをすべて見つけたわけではありませんが、左手と右手の座標系、度とラジアン、および Y 座標のアップと Z アップに関連している可能性があります。
私自身の表現では、オイラー角をglm::vec3
ベクトルに格納するだけです。私は描画に OpenGL を使用しているので、スペースは右利きだと思います。オイラー角の場合、順序が重要です。回転行列を計算するために私がすることは、最初に各成分の行列を作成し、次にそれらをX * Y * Z
順番に乗算することです。さらに、私自身の表現では、正の Y 座標は上向きです。
物理シミュレーションでは、クォータニオンを使用して回転を保存します。いくつかの調査の後、このライブラリではスペースが左利きであるという仮定を読みました。どの座標が上であるか、どの順序でオイラー角が返されるかについての情報はありません。
回転を物理シミュレーションから独自の表現に、またはその逆に変換するコードがここにあります。
#include <GLM/glm.hpp>
#include <GLM/gtc/quaternion.hpp>
#include <BULLET/btBulletDynamicsCommon.h>
/*******************************************************************
* euler angles "glm::vec3 input" from my own representation
* to quaternion "btQuaternion output" of physics simulation
*******************************************************************/
glm::quat quaternion(glm::vec3(input.x, input.z, input.y) * 3.14159f / 180.f);
btQuaternion output(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
/*******************************************************************
* quaternion "btQuaternion input" from physics simulation
* to euler angles "glm::vec3 output" of my own representation
*******************************************************************/
glm::quat quaternion(input.getW(), -input.getX(), -input.getY(), -input.getZ());
glm::vec3 angles = glm::eulerAngles(quaternion);
glm::vec3 output(-angles.x, -angles.y, -angles.z);
試行錯誤でこの汚いコードを見つけましたが、動作します。しかし、ご覧のとおり、否定、コンポーネントのスウィズリング、およびさまざまな四元数型による型変換が見られます。それらの多くは不要であり、タスクははるかに簡単に実行できると思います。
私の変換が機能する理由と、それらを単純化する方法を説明していただけますか? ところで、変換がうまくいかなかった場合にどのように表示されるかを確認したいので、スクリーンショットを示します...