章立てを変更しました。
旧の章立てとの関係はこちらを参照してください。
6.5 (旧3.5) 節から始めます.
6.5 物体を動かしてみよう
キーを押してプログラム上でCG物体が動いているとき、概念としては実際には何を動かしているのでしょうね??
ここからは1年から学習してきた線形代数の理解力が問われます。
OpenGLでの座標変換を正確に知る必要があります。
106-5-MoveTheWorld.c (旧 35-MoveTheWorld.c)
106-4からの差分
キーバインディング
回転・移動・拡大縮小がインタラクティブにできるように上のプログラムは改良されています。
有効なキーボード入力をソースコードから読み取ってリストにしてみましょう。
キーボードからの入力は、OSがトラップして ic2_NormalKeyInput() に渡します。
(glutのgltKeyboardFunc()でのcallback関数の設定に因る)
6.6 補助情報の追加
今後の理解の為の補助として、X/Y/Z軸を表す線を引いてみるように変更します。
ところで、この補助線はいったい「何座標系」を表しているのでしょうね?
この補助線の表示の様子と、ソースコードとを合わせて、各キーが何に相当するか解析してください。
【注意】
書籍・インターネット等でみられるOpenGLに関する説明と7節の説明は矛盾することがあります。
これは、7節では、通常のOpenGL環境と違って、投影方法を明示的に与えないままで説明を行っているためです。
8節以降で投影方法を明示してからは他の一般的なOpenGLに関する情報と一致するようになります。
なお、以降はOpenGL(ver.2.1)の各関数(小文字のglの2文字で始まる関数)の説明は Original を参照してください。
OpenGLのProgramming Guide Book (ver1.1, 通称赤本)も参考になるでしょう。
(Red book にはver 2.1のものもありますが、本学習の範囲であればむしろ ver1.1のほうが読みやすいです)
7.1 カメラと物体との関係
改めて現段階で分かっているカメラと物体との関係を図示してみましょう。
(図は板書予定)
2つの3次元座標系を考えます。
・物体座標系:物体の頂点を表現するのに使われている座標系です。物体局所座標系、物体固有座標系とも呼ばれます。この座標系で座標を表現するときは Plocalと表記します。
・カメラ座標系:カメラの焦点を原点とし、Z軸を光軸と平行に取る座標系です。この座標系で座標を表現するときは Pcameraと表記します。
なお、CGの描画を考えるとき、「世界座標系」なるものはどこにも存在しません。
(以前は概念的に導入していたのですが、どうも誤解を招くことが多いようなので使うことをやめます)
・本節で考える(プログラムで現在用いている)3次元座標系(以後XYZで表記)は?手系→「左手系」
・カメラ座標系は、カメラと同じ方向をユーザが見たとき、右がX軸正、上がY軸正、?がZ軸正である。→「奥」
・初期状態時、カメラはカメラ座標系の中で(?, ?, ?)に位置している。→「(0,0,0)」
・初期状態時、カメラはカメラ座標系の中で(?, ?, ?)の方向ベクトルに沿って光軸を向けている。→「(0,0,1)」
・これまでのプログラムは、??投影を使用している。→「直交投影(正投影)」
・この投影での撮影可能な空間の大きさは、???である。→「X:-1.0〜- 1.0, Y:-1.0〜1.0, Z:-1.0〜1.0 」
※この部分は参考書(OpenGLのRedBook含む)に書いてある内容と異なってる場合がありますが、この授業では説明の通りに解釈しておいてください。
※(しつこいですが、これは7節の説明中、通常のOpenGL環境と違って、投影行列を明示的に与えないままで説明を行っているためです。)
なお、斉次座標表現では参考(Description項の数式)のように変換が行われます。
7.2 移動
まずは一番単純そうな概念の移動から。
7.1節の図で何が起きるのでしょうか?
特に正負がどうなっているか注意してください。
移動変換を表現する4x4行列を T で表記します。
P'local = T Plocal
P'local = T(X,Y,Z) Plocal
プログラム内部ではglTranslatef()関数を利用します。
・第1引数 X はX軸移動量
・第2引数 Y はY軸移動量
・第3引数 Z はZ軸移動量
7.3 回転
次は回転です。これについては慎重に理解する必要があります。
回転変換を表現する行列に関する重要な性質は、演算順序の交換ができないことです。
7.1節の図で何が起きるのでしょうか?
特に正負がどうなっているか注意してください。
回転変換を表現する4x4行列を R で表記します。
OpenGLでは、回転を、軸・角度表現(axis-angle representation)で指定します。
P'local = R Plocal
P'local = R(angle, Ax, Ay, Az) Plocal
プログラム内部ではglRotatef()関数を利用します。
・第1引数 angle は回転角[degree]。
・第2〜4引数 Ax,Ay,Az で回転軸方向ベクトル。
回転は常にその時点での座標系中心を通る回転軸方向ベクトルの回りで行われます。
任意軸まわりの回転ができるよう、この関数が与える行列は一般化されていてわかりにくいですが、例えば(1,0,0)回転軸方向ベクトルまわりの回転はX軸まわりの回転となります。
参考ページのglRotate*(Rx, 1, 0, 0)の式表現も見て確認してください。
7.4 行列のスタック (OpenGL)
OpenGLでは2種類の行列を頻繁に操作します。
この2種類の行列について、OpenGLではスタックを使って操作します。
7.5 演算順序と蓄積行列
ここでは物体座標系から、カメラ座標系に変換する操作を考えます。
カメラ座標系で表現された点が、射影されて撮像面に描画されることになります。
ここで扱う行列をまとめたものが、モデルビュー行列(MODELVIEW_MATRIX)と呼ばれるものです。
物体はもともと、物体座標系内で各頂点が表現されています。
これをPlocalとして表記しています。
この座標値を、カメラ座標系での値Pcameraに変換するのがMODELVIEW行列変換の目的です。
(1)想定する演算順序
Pcamera = R1 T2 R3 Plocal
(2)演算順序の変更
Pcamera = E R1 T2 R3 Plocal
Pcamera = ((((E) R1) T2) R3) Plocal
Pcamera = M Plocal
ただしEは単位行列とする。
M = E R1 T2 R3 を(MODELVIEW変換の)蓄積行列と呼ぶ。
(3)プログラム上の出現順序
1. R1
2. T2
3. R3
glTranslatef(), glRotatef()は、モデルビュー行列用スタックの最上部行列に対して作用します。
最上部行列に(移動and/or回転)行列を右から掛けて、出来上がった行列をもとの最上部行列と置き換えます。
この最上部行列のことを蓄積行列と呼びます。
7.6 蓄積行列とスタックを利用した応用プログラムその1(物体のみ操作)
MODELVIEW行列とスタックの利用法が分かってくると、簡単に(=わずかな変更で)違う機能を提供できます。
次のプログラムは、光源を固定して物体だけが動く状態にしてあります。
これは、光源設置時には初期状態のMODELVIEW行列を使い、物体設置時には現在のMODELVIEW行列を使うことで実現できます。
106-7-MoveObjectOnly.c
106-6からの差分
7.7 蓄積行列とスタックを利用した応用プログラムその2(光源のみ操作)
次のプログラムは、物体を固定して光源だけが動く状態にしてあります。
これは、光源設置時には現在のMODELVIEW行列を使い、物体設置時には初期状態のMODELVIEW行列を使うことで実現できます。
106-7-MoveObjectOnly.c
106-6からの差分
課題はいずれも2011/11/07,13:30 (JST)提出締切である。
来週以降で使うことになるオブジェクトファイルを各自で用意すること。
条件1:オブジェクトファイルには4ポリゴン以上含むこと(多いほうは数千ポリゴンでも可)
条件2:オブジェクトはX=0, Y=0, Z=0の3平面どれに対しても鏡面対称ではないこと(色だけ非対称という形式はOK)。
条件3:3頂点をこの順に(右ネジに)なぞったときに反時計回りに見える側を表とすること(右ネジの先端側が表)。
条件4:今回のオブジェクトを構成する点群は、概ね、どの軸も-1.0〜1.0の範囲に収まること。
条件5:RGBは0.0〜1.0の範囲で記述すること。
1行あたり(1ポリゴンあたり)のフォーマット
X0 Y0 Z0 X1 Y1 Z1 X2 Y2 Z2 R G B |
提出物
MODELVIEW行列について、ユーザのキー入力に連動して、M11、M12、M13、M14の4行列が発生したとする。
ここでは、M11の前は単位行列であったとする。
(1) 蓄積行列Mcumを上記記号を用いて表記せよ。
(2) 蓄積行列を用いる利点を、特にオブジェクトモデル中の点数nが大きくなる場合に言及しながら述べよ。
(3) M11 = Rx(30°), M12 = T(0.0, 0.3, 0.0), M13 = Rx(-30°), M14 = Ry(90°)としたときの、Mcumの行列の内容を4x4で表記せよ。有効数字は小数点以下3桁とする。
(4) 上記(3)のときの106-6-ShowXYZ.cの結果を図で示せ。
(当該WindowのスナップショットはALT+SCREENで保存できる)
提出物
現在のプログラム(106-6-ShowXYZ.c)では、'R'キーによって初期状態に戻すことができる。
発展課題3Xでは、'r'キーを押したときにその状態(MODELVIEW行列)を保存して、'R'キーによってその状態に戻せるようにすること。
提出物