Springhead Users Manual

6.2 形状の作成

衝突判定形状は次の手順で作成・登録します.

以下に順を追って説明します.

まず形状を作成するには次のようにします.

// given PHSdkIf* phSdk


CDBoxDesc desc;
desc.boxsize = Vec3d(1.0, 1.0, 1.0);


CDBoxIf* box = phSdk->CreateShape(desc)->Cast();

衝突判定形状のオブジェクトはPhysicsモジュールが管理します. このため,形状を作成するにはPHSdkクラスのCreateShape関数を使います. PHSdkについては7章を参照してください. 形状を作成するには,まず種類に応じたディスクリプタを作成し,寸法などのパラメータを設定します. この例では直方体クラスCDBoxのディスクリプタを作 成して一辺が\( 1.0 \)の立方体を作成します. ディスクリプタを指定してCreateShapeを呼び出すと,対応す る種類の形状が作成され, そのインタフェースが返されます. ただし戻り値は形状の基底クラスであるCDShapeのインタフェースですので,派生クラス(ここではCDBox)のインタフェースを得るには 上 のようにCast関数で動的キャストする必要があります.

形状を作成したら,次にその形状を与えたい剛体に登録します.

// given PHSolidIf* solid


solid->AddShape(box);                  // first box

剛体クラスPHSolidについては7章を参照してください. ここで重要なことは,一度作成した形状は1つの剛体にいくつでも登録でき,また異なる複数の剛体にも登録できるという ことです. つまり,同じ形状を複数の剛体間で共有することで,形状の作成コストやメモリ消費を抑えることができます.

AddShape関数で登録した直後の形状は,剛体のローカル座標系の原点に位置しています. これを変更したい場合はSetShapePose関数を使います.

solid->AddShape(box);                  // second box
solid->AddShape(box);                  // third box


// move first shape 1.0 in x-direction
solid->SetShapePose(0, Posed(Vec3d(1.0, 0.0, 0.0), Quaterniond());


// rotate second shape 30 degrees along y-axis
solid->SetShapePose(1, Posed(Vec3d(),
                          Quaterniond::Rot(Rad(30.0), ’y’)));

SetShapePoseの第1引数は操作する形状の番号です.最初にAddShapeした形状の番号が\( 0 \)で,AddShapeするたびに\( 1 \)増加します. 形状の位置や向きは剛体のローカル座標系で指定します. また,形状の位置・向きを取得するにはGetShapePose関数を使います.

以下ではSpringheadでサポートされている形状を種類別に解説します.

直方体

Fig. 6.2: Box geometry

直方体(Fig. 6.2)のクラスはCDBoxです.

CDBoxDesc
Vec3f boxsize 各辺の長さ
CDBoxIf
Vec3f GetBoxSize()
void SetBoxSize(Vec3f)

Fig. 6.3: Sphere geometry

球(Fig. 6.3)のクラスはCDSphereです.

CDSphereDesc
float radius 半径
CDSphereIf
float GetRadius()
void SetRadius(float)
カプセル

Fig. 6.4: Capsule geometry

カプセル(Fig. 6.4)のクラスはCDCapsuleです. カプセルは円柱の両端に半球がついた形をしています.

CDCapsuleDesc
float radius 半球の半径
float length 円柱の長さ
CDCapsuleIf
float GetRadius()
void SetRadius(float)
float GetLength()
void SetLength(float)
丸コーン

Fig. 6.5: Round cone geometry

丸コーン(Fig. 6.5)のクラスはCDRoundConeです. 丸コーンはカプセルの両端の半径が非対称になったものです.

CDRoundConeDesc
Vec2f radius 各半球の半径
float length 半球間の距離
CDRoundConeIf
Vec2f GetRadius()
void SetRadius(Vec2f)
float GetLength()
void SetLength(float)
void SetWidth(Vec2f)

SetWidth関数は,丸コーンの全長を保存したまま半径を変更します.

凸メッシュ

Fig. 6.6: Convex mesh geometry

凸メッシュ(Fig. 6.6)のクラスはCDConvexMeshです. 凸メッシュとは凹みや穴を持たない多面体です. 頂点座標を指定することで自由な形を作成することができます.

CDConvexMeshDesc
vector<Vec3f> vertices 頂点座標の配列
CDConvexMeshIf
Vec3f* GetVertices() 頂点配列の先頭アドレス
int NVertex() 頂点数
CDFaceIf* GetFace(int i) \( i \)番目の面
int NFace() 面数

凸メッシュが作成される際,CDConvexMeshDesc::verticesに格納された頂点を内包する最小の凸多面体(凸包)が作成されます. 多面体の面を表すCDFaceのインタフェースを以下に示します.

CDFaceIf
int* GetIndices() 頂点インデックス配列の先頭アドレス
int NIndex() 面の頂点数

NIndexは面を構成する頂点の数を返します(通常\( 3 \)\( 4 \)です) るには

// given CDConvexMeshIf* mesh
CDFaceIf* face = mesh->GetFace(0);                    // get 0-th face
int* idx = face->GetIndices();
Vec3f v = mesh->GetVertices()[idx[0]];                // get 0-th vertex

とします.