ODEで学ぶC言語のStep3です.今回は私がODEのAPIを元に作成した関数を使い,赤い球を落下させるプログラムを説明します.
今までのプログラムでは描画だけでしたが,今回からシミュレーションやゲームを作るために必要な動力学計算や衝突検出計算も含んでいます.サンプルプログラムとしては,物理シミュレーションで最も簡単な物体の落下を取り上げます.C言語などのプログラミングの教科書では初めの例題はHello Worldを表示する例が定番です。ここではHello Worldの物理シミュレーション版を紹介します.
- API
ここでは簡単にするためにODEのAPIを元に,超簡単なAPIを作成しました.ただし、ODEのAPIのように細かいことはできません。
- void dmInit();
シミュレーションを初期化します. - void dmCreateSphere(dmObject *obj, double p[3], double R[12], double m, double r, double color[3]);
球を作成します.引数のp[3]は位置(x,y,z)[m],R[12]は姿勢(回転行列), mは質量[kg],rは半径[m],color[3]は色(赤,緑,青各成分、値は0以上1以下)です. - void dmSimStep();
シミュレーションを1ステップ進めます. - dmDraw(MyObject obj);
引数のオブジェクトobjを描画する.
- void dmInit();
- ソースコード
- 次に、詳しいコメントのついたソースコードを以下に示します。main関数から読んでください。
/* step3 リンゴ(林檎)の落下 */ #include "dm3.h" dmObject apple; // リンゴ void simLoop(int pause) /*** シミュレーションループ ***/ { dmSimStep(); // シミュレーションを1ステップ進める dmDraw(apple); // リンゴの描画 } int main() /*** main関数 ***/ { double p1[3] = {0.0, 0.0, 2.0}; // 位置 [m] double R[12] = {1,0,0,0, 0,1,0,0, 0,0,1,0}; // 姿勢(回転行列) double red[3] = {1.0, 0.0, 0.0}; // 赤色 double r = 0.2, m = 1.0; // 半径[m],質量[kg] dmInit(); // 初期化 dmCreateSphere(&apple, p1, R, m, r, red); // 球の作成 dmLoop(800, 600, simLoop, NULL); // ウインドウの幅,高, ループ関数,コマンド関数 dmClose(); // 終了処理 return 0; }
- これは赤い玉の自由落下のプログラムです。まず、dmInit()でシミュレーションを初期化します。
- 次に物体を作ります.球を作るAPIはdmCreateSphere()です.
- 物体の生成が終わったら、次はシミュレーションを1ステップ進めます。dmLoop()の中身はwhileループになっていて、繰り返しsimLoop関数が呼び出しています。dmLoop()の一番最後の引数がNULLになっているのは、このサンプルプログラムではキー操作可能なcommand関数がないからです。前回の例のようにcommand関数がある場合はNULLの代わりにcommandを入れてください。
- お次は物体の描画です.dmDraw(apple)で落下する球を表示しています。dmDraw()の引数は表示したい物体をいれてください。
- 最後にシミュレーションをdmClose()で終了します.なお、小文字のdmで始まる関数は私がこの講義用にODEのAPI(application interface)を元に作成したものです.
- ホームワーク
- step3-160615.zipをダウンロードして実行しよう!
- 次のAPIを使い青いボックスを位置p[3]={0.0, 1.0, 2.0}に作成し,落下させるプログラムを作ってください.
- void dmCreateBox(dmObject *obj, double p[3], double R[12], double m, double side[3], double color[3]);
- 物体 obj, 位置 p[3], 姿勢(回転行列)R[12], 質量 m, サイズ(x,y,z) side[3], 色 color[3]
- なお、回転行列は3×3行列ですが、ODEでは高速化のために3×4行列として各行の最後に0を追加しています。
- 今度は緑色の円柱を位置(0.0, -1.0, 2.0)に作成し,落下させなさい.
- void dmCreateCylinder(dmObject *obj, double p[3], double R[12], double m, double r, double l, double color[3]);
- 物体 obj, 位置 p[3], 姿勢 R[12], サイズ sides[3], 半径 r, 長さ l, 質量 m, 色 color[3]
- 最後に,黄色のカプセルを位置(-1, 0, 2)に作成し,落下させなさい.
- dBodyID dmCreateCapsule(dmObject *obj, double p[3], double R[12], double m, double r, double l, double color[3]);
- 物体 obj, 位置 p[3], 姿勢 R[12], サイズ sides[3], 半径 r, 長さ l, 質量 m, 色 color[3]
コメント