物理エンジンODEを使い,ゲームを作りながらC言語をマスターすることを目指して連載します。ODEのバージョンは0.13に対応しています。なお、KITロボティクス学科の講義「コンピュータ工学Ⅰ」と連動しており、昨年度から学習の進んだアドバンストコース向けです。我こそはと思う学生は是非、チャレンジしてください。
今回は何もなかった仮想空間に物体を表示させてみましょう.ODEではいろいろな形状がサポートされています.ここではその中でも使い方が最も簡単な球を表示させます.
/* step1 球の表示 */ #include "dm1.h" dMatrix3 R; // ODEの3x3行列の型 回転行列(姿勢) double r = 0.2; // 半径 [m] double p[3] = {0.0, 0.0, 1.0}; // 位置(x,y,z)[m] double p2[3] = {0.0, 1.0, 1.0}; // 位置(x,y,z)[m] double sides[3] ={0.1, 0.2, 0.3}; // サイズ(x,y,z)[m] void simLoop(int pause) /*** シミュレーションループ ***/ { dsSetColor(1.0, 0.0, 0.0); // 赤色の設定(赤成分,緑成分,青成分) dsDrawSphere(p,R,r); // 球の描画 dsSetColor(0.0, 0.0, 1.0); dsDrawBox(p2, R, sides); // 直方体の描画 } int main() /*** main関数 ***/ { dmLoop(800, 600, simLoop); // シミュレーションループ ウインドウの幅,高 return 0; }
まず,2行目のdm1.hはODEをより簡単に使うためのヘッダーファイルです.Step1ではまだ説明しません.
一般的に物体を3次元空間上に表示させるためには,物体の位置と姿勢を決める必要があります.ODEでは姿勢を回転行列とよばれる行列で表しています.その行列の要素を格納するのが配列R[12]です.回転行列は3×3の行列なので,1次元配列では要素数が9個で十分ですが,ODEでは高速化のために要素数12個の配列を用意します.配列の4, 8, 12番目の様子は0になっています.なお,R[12]には謎のヘッダファイルdm1.hの中で単位行列が設定されています.
また,位置は要素数3個のdouble型の配列p[3]に格納しています.位置のx座標(手前方向)を表す変数pの1番目の要素p[0]には0.0[m],y座標(右方向), z座標(高さ方向)を表すp[1], p[2]には0.0[m], 1.0[m]が設定されています.座標系は右手系です。上の図では中心から赤いピラミッドの方向がx軸の正,青いピラミッドの方向がy軸の正,上空方向がz軸の正です.ODEでは単位系はSI単位系で,長さはm,質量はkg,力はNとなります.
ソースコードのなかほどにあるsimLoop関数にシミュレーションでやりたいことを書きます.
12行目のdsSetColor()は色を設定する関数です.引数は光の3原色の値を3個取り,1番目は赤,2番目は緑,3番目は青成分で0以上1以下の値となります.ちなみに,全部0だと黒,全部1.0だと白です.
13行目は,球を表示したいのでdsDrawSphere関数を使って,位置p,姿勢R, 半径rの球を描画しています.なお、このソースコードだけではわかりませんが、simLoop関数はdmLoop関数の中で毎回呼び出されています。
同様にして15行目で青色を設定し、16行目で直方体を描画しています。
今回はこれで終わりです.簡単でしたね.なお,この説明でわからない場合は,わからない部分をコメントに書いて頂けると補足説明します.
- 演習
- step1-160525.zipをダウンロードし,実行してください.
- 手順
- ode-0.13がインストールされていなかったらこの説明に従いインストールする.
- ダウンロードしたファイルをc:\ode-0.13\myprogの中に保存する.デスクトップではなく、このフォルダに保存しないと失敗するので注意.
- そこで解凍する.c:\ode-0.13\myprog\step1というフォルダが作られます.
- c:\ode-0.13\myprog\step1\step1.cbpをダブルクリックしてcodeblocksを起動しビルド・実行する.ダブルクリックするファイルの拡張子はcbpです.間違ってcppをダブルクリックしないように!
- 問題
- Prob.1 球の位置と大きさを変更してみましょう.
- プロトタイプ宣言
- void dsDrawSphere(const double p[3], const double R[12], double r)
- 引数p[3]は位置,R[12]は姿勢,rは半径.
- ヒント
- プロトタイプ宣言では仮引数は宣言していますが,呼び出す(使う)ときは宣言してはいけません.ソースコードsimLoop内のdsDrawSphereの使い方を参考にしてください.また,姿勢を表す回転行列Rは見えないところで単位行列に初期化しています.現時点では配列の各要素に値を代入する必要はないので配列名Rを引数として使ってください.
- プロトタイプ宣言
- Prob.2 直方体の位置と大きさを変更してみよう.
- プロトタイプ宣言
- void dsDrawBox(const double p[3], const double R[12], const double sides[3])
- 上は関数のプロトタイプ宣言の形式なので,呼び出すときはconst doubleなどの型名を入れてはいけません.引数が配列の場合は,サンプルプログラムのように配列名だけを入れてください.
例 dsDrawBox(p, R, sides); // 呼び出す場合は配列名だけ - 1, 2番目の引数はdsDrawSphereのときと同じです.3番目の引数は直方体のx,y,z方向のサイズ[m]が入っている要素数3個の配列です.位置を表す配列pと同じように初期化すれば大丈夫です.
- なお, doubleの前にあるconstは値を変えてはいけないという意味です。円柱を表示させてください
- プロトタイプ宣言
- Prob. 3 円柱を表示させましょう.
- プロトタイプ宣言
- void dsDrawCylinder(const double p[3], const double R[12], double l, double r );
- ここで,lは長さ,rは半径です.
- プロトタイプ宣言
- Prob. 4 カプセルを表示させてください.
- プロトタイプ宣言
- void dsDrawCapsule(const double p[3], const double R[12], double l, float r );
- プロトタイプ宣言
- Prob.5 Prob.3で制作した球の色を黄色に替えよう
- プロトタイプ宣言
- void dsSetColor(float r, float g, float b)
r, g, bは光の3原色の赤、緑、青成分。値は0以上1以下のfloat型。例えば、緑にしたかったらrとbは0.0、gには1.0を代入する。
- void dsSetColor(float r, float g, float b)
- プロトタイプ宣言
- Prob.1 球の位置と大きさを変更してみましょう.
以上
コメント