1

私は 3D レンダリングのセットアップ (OpenGL の GLM で行われたすべての数学) に取り組んでおり、変換をどのように機能させたいかを除いて、すべて正しく機能します。次のように、エンティティごとにマトリックスを作成します。

matrix = mat4(1);
vec3 scale = GetWorldScale();
vec3 pos = GetWorldPosition(); // Returns pos + parent->pos
quat rot = GetWorldRotationQuat(); // Returns parent->rot * rot

matrix = glm::translate(matrix, pos);
matrix *= mat4_cast(rot);
matrix = glm::scale(matrix, scale);

right = matrix[0].xyz;
up = matrix[1].xyz;
direction = matrix[2].xyz;

これを使用すると、好みに合わせて一部を調整する方法がわからないことを除いて、通常は正しく機能します。つまり、これを使用すると、X 軸の平行移動が反転し (たとえば、左が正、Z 軸の前方が正ですが、私はそれをあまり区別しません)、Y 軸の回転が反転します。

この目的のための他のコードを見ると、多くの人が私が方向 (カメラ) に使用したものを否定しているようです。私もそれを行っており、変換は正しいですが、回転のすべての軸は推奨されるものとは反対です (ただし、方向が否定されているかどうかにかかわらず、X の回転は同じです)。

使用前に X 軸の平行移動と Y 軸の回転を無効にすることを除いて、これを修正するために何をすべきかよくわかりませんが、それは最善の方法ではないと感じています。考え?

4

1 に答える 1

0

問題は、変換、特に平行移動と回転の順序を混在させることにあると思います。これらの各変換 (スケール、平行移動、および回転) は、ある座標系を別の座標系に変換する方法を定義します。

例を見てみましょう: 1 つの子オブジェクト c とその親 p があります。それらはそれぞれ、平行移動 t、回転 r、およびスケール s を持っています。簡単にするために、これらはそれぞれ 4x4 行列です。現在、あなたは

matrix = p.t * c.t * p.r * c.r * p.s * c.s

この行列 (長さ 1 の xyz 軸) によって変換される子のローカル座標系を想像してみてください。ポイントは右から乗算されるため、右から左に読む必要があります。まず、座標系が子によってスケーリングされ、次に親によってスケーリングされます。次に、子供によって回転されます。次に、親による。そして今、子供の翻訳が適用されます。つまり、回転した座標系で子の移動が適用されます。子と親の両方の回転を既に適用しているため、親の座標系に回転します。そのため、子の座標は、親の座標であるかのように解釈されます。

したがって、何をすべきか: メソッドで、オブジェクトの行列を計算しますm = c.t * c.r * c.s。次に、オブジェクトのワールド マトリックスは次のように定義されますwm = pm * m。ここで、親マトリックスpmは親のワールド マトリックスです。そうすれば、世界の行列になります。

c.wm = (c.pm) * (c.o) = (p.t * p.r * p.s) * (c.t * c.r * c.s)

つまり、子の平行移動は子の座標系にあり、親の平行移動は親の座標系にあります。

于 2013-06-12T19:03:47.197 に答える