OpenGL-Assimp-Bullet 座標系マトリクスのコンバート

進まない。ハマり気味です・・・。

マトリクス演算のクラスって便利だけど、種類が多い。
4×4のマトリクスだと、OpenGLではGlfloat[16]で始まり、assimp(3Dモデルローダライブラリ)ではaiMatrix4x4,bullet(物理演算ライブラリ)ではbtTransform。ちなみにopenFrameworksではofMatrix4x4となる。各ライブラリが独自の実装を行なっているから面倒なんだけど、回転移動スケーリング、算術オペレータなど、同じ機能があって同じ使い方ができる。色々使う場合、相互変換がちゃんとできないと困るので、下記にまとめておく。

とにかくGLfloat[16] をベースに変換していけば分かりやすい。内部的に何らかのかたちで4×4で値を保持しているわけだが、OpenGLのマトリクスをtransposeしないと使えないケースが多いので注意が必要。assimpやmascotcapsleなどもtransposeが必要だった。

まず、OpenGLの現在の状態を得る場合下記のようにする。

GLfloat m[16];
glGetFloatv(GL_MODELVIEW_MATRIX, m);

assimpに変換Transposeが必要。a1-d4の並びに注意

aiMatrix4x4 aim= aiMatrix4x4(m[0], m[1], m[2], m[3],
m[4], m[5], m[6], m[7],
m[8], m[9], m[10], m[11],
m[12],m[13], m[14],m[15]);
aim.Transpose();

もしくは

aiMatrix4x4 aim= aiMatrix4x4(m[0], m[4], m[8], m[12],
m[1], m[5], m[9], m[13],
m[2], m[6], m[10], m[14],
m[3],m[7], m[11],m[15]);

bulletに変換。関数があるので楽勝

btTransform btm;
btm.setFromOpenGLMatrix(m);

逆の場合。

assimpからGLfloat[16]

m[0]=aim.a1;
m[1]=aim.b1;
m[2]=aim.c1;
m[3]=aim.d1;
m[4]=aim.a2;
m[5]=aim.b2;
m[6]=aim.c2;
m[7]=aim.d2;
m[8]=aim.a3;
m[9]=aim.b3;
m[10]=aim.c3;
m[11]=aim.d3;
m[12]=aim.a4;
m[13]=aim.b4;
m[14]=aim.c4;
m[15]=aim.d4;

bulletからGLfloat[16]

btm.getOpenGLMatrix(m);

でもってOpenGlに適用する。

glPushMatrix();
glMultMatrixf(m);
/*描画*/
glPopMatrix();

これでbtTransformからのaiMatrix4x4とか、自由自在にできる。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です