Opengl でキャラクターを表示し、クォータニオンを使用して軸を中心に回転させます。達成したいのは、それらを独自の軸を中心に回転させることですが、クォータニオンを使用する場合、1 つの軸に従ってオブジェクトを回転させると、他のオブジェクトは取り込まれませんこの回転は固定ワールド軸を中心に回転することを考慮してください。Quaternion Qaccumulative (元の回転) と 3 つの角度の AngleX、AngleY、AngleZ が与えられます。最初に、オイラーの回転が試すべきだと思い、いくつかの手法を試しました:
Quaternion rot1;
Quaternion rot2;
Quaternion rot3;
Vector3 axis ;
float angle;
QAccumulative.getAxisAngle(&axis, &angle);
// first try : around fix axes
cout << "axis : " << axis << endl;
rot1.FromAxis(Vector3(1.0,0.0,0.0),angleX);
rot2.FromAxis(Vector3(0.0,1.0,0.0),angleY);
rot3.FromAxis(Vector3(0.0,0.0,1.0),angleZ);
QAccumulative = QAccumulative * rot1;
QAccumulative = QAccumulative * rot2;
QAccumulative = QAccumulative * rot3;
/*
// second try, around current modified axes
rot1.FromAxis(Vector3(axis.x,0.0,0.0),angleX);
rot2.FromAxis(Vector3(0.0,axis.y,0.0),angleY);
rot3.FromAxis(Vector3(0.0,0.0,axis.z),angleZ);
QAccumulative = QAccumulative * rot1;
QAccumulative = QAccumulative * rot2;
QAccumulative = QAccumulative * rot3;
*/
/*
// third try with Euler rotation
Quaternion rotation;
rotation.FromEuler(10*angleX,10*angleY,10*angleZ);
QAccumulative = QAccumulative * rotation;
*/
QAccumulative.normalise();
これまでのところ、それらのどれも機能していません...ローテーションの実装が問題だとは思いませんが、誰かが問題を抱えている場合は、コードを投稿します。オイラーは私が思っていたものではありませんか?目標を達成するためにどの回転缶を使用すればよいですか?
編集:投稿で提案された、これを試しました:
rotate(float angleX,float angleY,float angleZ) {
Vector3 axis = Vector3(angleX,angleY,angleZ);
Vector3 worldAxis = QAccumulative * axis;
Quaternion worldRotation( worldAxis.x,worldAxis.y,worldAxis.z, 10 );
QAccumulative = worldRotation * QAccumulative;
QAccumulative.normalise();
キャラクターは引き続き固定軸を中心に回転します。
編集:投稿で指定された疑似コードを適用したところ、機能しました:
rotate(float angleX,float angleY,float angleZ) {
Vector3 axis = Vector3(angleX,angleY,angleZ);
Vector3 worldAxis = QAccumulative * axis;
Quaternion worldRotationx( 1.0,0,0, angleZ );
Quaternion worldRotationy( 0,1.0,0, angleX);
Quaternion worldRotationz( 0,0,1.0, -angleY );
QAccumulative = worldRotationx * worldRotationy * worldRotationz * QAccumulative;
QAccumulative.normalise();