やあ子どもたち。関東では大雪になったけどスタッドレスちゃんと履いてたか?スタッドレス履いてても降った翌朝なんかは道ボコボコだからどの道気をつけて運転しないとだめだぞ。今日はglm::mat4の話だよ。
glmって何?っていう人は帰ってくれ。さてさて、mat4を使うわけだが、どうもドキュメントが舌足らずな気がしてしまうのはおじさんだけだろうか。GLSLの仕様見ろってことなのかな。だとしてもそれもあまりに乱暴な話だろとも思うのだが。。
今回はビューマトリックスを作ろうとしていろいろやっているうちに結果的にmat4に関する理解が深まってしまうコードができたので紹介しておくぞ。(ビューマトリックスの作り方については今回の話しからはそれるので書かないけど、興味のある人はその考え方について過去日記に書いたので見てみてくれ)
さて以下の書き方その1〜4は、最終的にどれも同じ内容を、view_mat変数の中に構築したよ。
#include "../glm-0.9.4.0/glm/glm.hpp" #include "../glm-0.9.4.0/glm/gtc/type_ptr.hpp" #include "../glm-0.9.4.0/glm/gtx/transform.hpp" // // .. // glm::mat4 view_mat(1.0);// ←今回は関係ないけどこれで単位行列になるらしい #if 01 // 書き方その1(全16成分を指定) view_mat[0][0] = b.x; view_mat[1][0] = c.x; view_mat[2][0] = -dir.x; view_mat[0][1] = b.y; view_mat[1][1] = c.y; view_mat[2][1] = -dir.y; view_mat[0][2] = b.z; view_mat[1][2] = c.z; view_mat[2][2] = -dir.z; view_mat[0][3] = view_mat[1][3] = view_mat[2][3] = .0; view_mat[3][0] = cur_pos.x; view_mat[3][1] = cur_pos.y + .07; view_mat[3][2] = cur_pos.z; view_mat[3][3] = 1.0; view_mat = glm::inverse( view_mat ); #elif 01 // 書き方その2(旧OpenGLの行列要素の並び順m1-m16で初期化) view_mat = glm::mat4( b.x, b.y, b.z, .0, c.x, c.y, c.z, .0, -dir.x, -dir.y, -dir.z,.0, cur_pos.x, cur_pos.y+.07, cur_pos.z, 1.0 ); view_mat = glm::inverse( view_mat ); #elif 01 // 書き方その3(軸方向成分ごとに指定) view_mat[0] = glm::vec4( b, .0 );// レンダリング座標系のx軸相当精分 view_mat[1] = glm::vec4( c, .0 );// y軸相当精分 view_mat[2] = glm::vec4( -dir, .0 );// z軸相当精分 view_mat[3] = glm::vec4( cur_pos, 1.0 ); // 並進移動成分 view_mat[3][1] = cur_pos.y + .07; view_mat = glm::inverse( view_mat ); #else // 書き方その4(glm::lookAt()を使う) glm::vec3 curpos2 = cur_pos; curpos2.y += .07; view_mat = glm::lookAt( curpos2, curpos2+dir, glm::vec3(0,1,0) ); #endif
glm::mat4のソースを見ればわかることなんだけど結局列ベクトルを4つ持たせるという構造になってるんだね。だから、演算子で書いた場合は、[列ID][行ID]ということになります。(上記書き方その1)
その意味では書き方その3も同じことだけどな。OpenGLの行列の書き方として一番すっきり来るのが書き方その2かも知れないな。コンストラクタだからまるごと初期化って話になっちゃうけどな。まあ、ビューマトリックスなのであれば、書き方その4で行くのが一番なんだろうとおじさんは思うぞ。
じゃ今日はそんなとこで失礼するぞ。チャオ!