物理エンジンODEで学ぶC言語 [STEP3:関数]動力学計算

落下する赤い球

落下する赤い球

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を描画する.
  • ソースコード
        次に、詳しいコメントのついたソースコードを以下に示します。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)を元に作成したものです.
  • ホームワーク
    1. step3-160615.zipをダウンロードして実行しよう!
    2. 次の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を追加しています。
    3. 今度は緑色の円柱を位置(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]
    4. 最後に,黄色のカプセルを位置(-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]

 

コメント

タイトルとURLをコピーしました