最新(2017年6月現在)バージョン2.86のBulletPhysicsにはPythonでのBullet利用、VR用のサーバー/クライアントプログラム、新API(Bullet3)の物理計算やOpenCLによる剛体計算などが追加されているようです。Bullet3やOpenCLによる計算はゲームプログラムで使えそうですが、複雑でサンプルも少ないようなので、まずはその前にVisualStudio2017でライブラリのビルドと従来API(Bullet2)の剛体計算、DirectX11を使用したデバッグ表示まで作成してみます。
Bullet Physicsについて
公式ページ http://bulletphysics.org/
リアルタイム物理シミュレーション(物理エンジン)のオープンソースライブラリです。
ダウンロード
http://bulletphysics.org/の左上にある「Download」からgithubに移動します。githubのリポジトリから最新版を取得できますが頻繁に更新されているようなので、公式ページ「Download」の移動先のリリースページからダウンロードできるソースコードを使用します。
※2017年6月現在のダウンロード方法、ダウンロードページが変わることがあります
ビルド
VisualStudioのプロジェクトファイルは、専用ツールを使って生成します。CMakeのほかにpremakeというツールが使えるようになっていてBulletにexeファイルが含まれています。なのでこれを使うことにします。
ライブラリビルドとデモプログラム
まずは、Bulletでどのようなことができるか知ることができるデモプログラムをビルド、実行してみます。ダウンロードしたソースコード(圧縮ファイル)を展開するとbullet3-2.86.1/フォルダに
build_visual_studio.bat
というバッチファイルがあり、実行するとbullet3-2.86.1/build3/vs2010フォルダにVS2010プロジェクトファイルが生成されます。VS2010用ですがVS2017でも利用可能です。premakeのオプション指定がないためデモ、ライブラリ、追加機能、テストなど全プロジェクトが生成されます。
bullet3-2.86.1/build3/vs2010/0_Bullet3Solution.sln
をVS2017で開き(初回のみバージョン変換処理)、ビルド、実行するとデモプログラムが起動します。ライブラリのビルドも行うためbullet3-2.86.1/bin/フォルダにlibファイルが生成されます。
ライブラリのみビルドする場合
Bulletを使用する際は、libファイルを生成するプロジェクトしか必要がないためpremakeにオプション指定して必要なプロジェクトだけ生成させます。デモのビルドを行っている場合は、実行前にbin/フォルダとbuild3/vs2010フォルダを削除してください。
build_visual_studio.batを次のように書き換えて実行します。追加機能を使用する場合は–no-extrasを削除してください。
> cd build3
> premake4 --targetdir="../bin" --noopengl3 --no-demos --no-extras --no-enet --no-test --no-gtest vs2010
start vs2010
生成された bullet3-2.86.1/build3/vs2010/0_Bullet3Solution.sln を開いてビルドするとbin/フォルダにlibファイルが生成されます。
インクルードパスとライブラリパス
インクルードパス= bullet3-2.86.1/src/
ライブラリパス = bullet3-2.86.1/bin/
プログラムビルドに必要なのは、この2つのフォルダにあるファイルのみです。
プログラム作成
Bulletのデモ「Hello World」は、剛体シミュレーションの結果をprintfで出力しているだけなので、DirectX11を使って3D表示するプログラムを作成します。あと剛体が1つだけなので複数追加して、衝突の挙動や計算時間の測定も行います。
デバッグ表示
Bulletにはデバッグ用の表示処理があります。デバッグ表示インターフェイス(btIDebugDraw)の派生クラスで必要な仮想関数を定義することでBulletの内部状態(剛体など)を表示できます。表示は基本ワイヤーフレーム表示なので、ライン描画の仮想関数を実装するだけでデバッグ表示が可能です。
//btIDebugDrawクラス抜粋
class btIDebugDraw
{
public:
//デバッグ表示フラグ
enum DebugDrawModes
{
DBG_NoDebug=0,
DBG_DrawWireframe = 1,
DBG_DrawAabb=2,
};
//必須
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
virtual void setDebugMode(int debugMode) =0;
virtual int getDebugMode() const = 0;
//何もしなくても問題なし {} 必要であれば定義
virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0;
virtual void reportErrorWarning(const char* warningString) = 0;
virtual void draw3dText(const btVector3& location,const char* textString) = 0;
//ライン描画実行
virtual void flushLines();
}
//インターフェイスの指定
btDiscreteDynamicsWorld::setDebugDrawer(btIDebugDraw* debugDrawer);
//描画の実行
//drawLineなどが実行される
btDiscreteDynamicsWorld::debugDrawWorld();
表示処理 剛体とポリゴンメッシュの同期
実際ゲームプログラムなどで使用する場合は、剛体の姿勢情報を取得し、ポリゴンメッシュの姿勢に設定、描画します。ポリゴンメッシュの形状で物理演算を行うと計算に時間がかかるため、できるだけ基本形状(球やボックスなど)の剛体の使用します。人型キャラの移動処理にカプセル形状を使ったりします。
直接、剛体クラスに保存されている情報を取得、書き換えを行うと物理計算に不具合が生じます。そのため、姿勢取得や設定には専用の操作クラス(btDefaultMotionState)を使用します。このクラスは剛体を作成するときに必要になります。btDefaultMotionState*を保存して剛体と対になるポリゴンメッシュとの姿勢の同期処理を行います。
class btDefaultMotionState : public btMotionState
{
public:
virtual void getWorldTransform(btTransform& centerOfMassWorldTrans ) const;
virtual void setWorldTransform(const btTransform& centerOfMassWorldTrans);
}
時間計測
Bulletの物理計算は、stepSimulation(step_time)関数で実行されます。
剛体を600ほど追加して時間計測すると12msでした。とりあえず3Dゲームが遊べる程度のPCで測定しましたが、思ったより性能は悪くないようです。
サンプルプログラム
今回作成したプログラムのソースコードです。Bulletソースコードとライブラリのビルド用VS2017プロジェクトを同梱していますので、VS2017のビルドだけでプログラムを実行できます。
“StartBullet286VS2017” をダウンロード StartBullet286VS2017.zip – 836 回のダウンロード – 2 MB
「Bullet Physicsを使ってみる (Bullet2.86 VS2017 DirectX11)」への2件のフィードバック
コメントは停止中です。