衝突検出のサンプルコード

変数の定義

dWorldID world;                   // ワールド
dJointGroupID contactjointGroup;  // 接触ジョイントのジョイント グループ

衝突検出時に呼び出されるコールバック関数の定義

// 衝突検出時に呼び出されるコールバック関数
void nearCallback( void *data, dGeomID o1, dGeomID o2 )
{
    // o1、o2のいずれかがスペースであるか判定する
    if( dGeomIsSpace( o1 ) || dGeomIsSpace( o2 ) )
    {
        // o1、o2が異なるスペースであることも考慮して、衝突検出を行う
        dSpaceCollide2( o1, o2, data, &nearCallback );

        if( dGeomIsSpace( o1 ) )
        {
            // o1がスペースならば、そこに含まれるすべてのジオメトリを対象に衝突検出をする
            dSpaceCollide( o1, data, &nearCallback );
        }

        if( dGeomIsSpace( o2 ) )
        {
            // o2がスペースならば、そこに含まれるすべてのジオメトリを対象に衝突検出をする
            dSpaceCollide( o2, data, &nearCallback );
        }
    }
    else
    {
        const int max_contacts = 256;
        dContact contact[ max_contacts ];  // 接触情報を格納する配列

        // ジオメトリo1、o2の間の接触情報を作成する
        intnum_contact = dCollide(
            o1,
            o2,
            max_contacts,        // 接触点の最大数
            &contact[ 0 ].geom,  // 接触情報を格納するdContactGeom構造体
            sizeof( dContact )
            );

        for( int i = 0; i < intnum_contact; i++ )
        {
            // 接触面の性質を設定する
            contact[ i ].surface.mode = dContactBounce;
            contact[ i ].surface.bounce = 1.0;
            contact[ i ].surface.bounce_vel = 0.0;

            // 接触ジョイントを作成する
            dJointID joint = dJointCreateContact(
                world,
                contactjointGroup,
                &contact[ i ]    // 接触情報
                );

            // 接触情報に含まれれるジオメトリのボディを取得する
            dBodyID body1 = dGeomGetBody( contact[ i ].geom.g1 );
            dBodyID body2 = dGeomGetBody( contact[ i ].geom.g2 );

            // 接触したボディを接触ジョイントにより接続する
            dJointAttach( joint, body1, body2 );
        }
    }
}
※コールバック関数内では、スペースに変更を加えてはなりません。

シミュレーションループ内の処理

// シミュレーションのステップごとに、トップレベルのスペースを対象に
// すべてのジオメトリ同士の衝突をテストする
dSpaceCollide( top_level_space, 0, &nearCallback );

// シミュレーションのステップを進める
dWorldStep( world, 0.01 );

// 接触ジョイントのグループに含まれるすべてのジョイントを破棄する
dJointGroupEmpty( contactjointGroup );

ジョイントの破棄は処理の最後に行います。さもなくばシミュレーションを終了するときに、「destroying world containing grouped joints」との警告が表示されます。