HelloWorld
自由落下のサンプル
ヘッダの読み込み
#include <BulletDynamics/btBulletDynamicsCommon.h> #include <stdio.h>
main関数始まります
int main(int argc, char** argv)
{
int i;
世界(World)の設定の前準備
///衝突設定はデフォルト、自分で設定することもできる btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); ///衝突計算のディスパッチャー // 他のディスパッチャーを用いて並列計算することもできるよ (Extras/BulletMultiThreaded 見てね) btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); ///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep. btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase(); ///the default constraint solver // 他のソルバーを用いて並列計算することもできるよ (Extras/BulletMultiThreaded 見てね) btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; //上記の設定を用いて、世界を作成 btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration); //重力設定 dynamicsWorld->setGravity(btVector3(0,-10,0));
物体(rigid body)の生成
//keep track of the shapes //rigid bodyが存在するあいだは使うよ btAlignedObjectArray<btCollisionShape*> collisionShapes;
受け止める方の物体を生成
{
//とりあえず、50x50x50の立方体を生成(地面用)
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
collisionShapes.push_back(groundShape);
//初期化
btTransform groundTransform;
groundTransform.setIdentity();
//座標の設定
groundTransform.setOrigin(btVector3(0,-56,0));
btScalar mass(0.);
//0ならstatic(静止)、それ以外ならDynamicにする
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
//物体を世界に追加する
dynamicsWorld->addRigidBody(body);
}
落ちてくる方の物体を生成
{//次に、1x1x1の立方体を生成(地面用)
//create a dynamic rigidbody
btCollisionShape* colShape = new btSphereShape(btScalar(1.));
collisionShapes.push_back(colShape);
/// 初期位置を設定
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);//重さ
//0ならstatic(静止)、それ以外ならDynamicにする
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic) colShape->calculateLocalInertia(mass,localInertia);
startTransform.setOrigin(btVector3(2,10,0));//座標の設定
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
dynamicsWorld->addRigidBody(body);
}
シミュレーション開始
for (i=0;i<100;i++)
{
dynamicsWorld->stepSimulation(1.f/60.f,10);
//print positions of all objects
for (int j=dynamicsWorld->getNumCollisionObjects()-1; j>=0 ;j--)
{
btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{//位置を取得して表示
btTransform trans;
body->getMotionState()->getWorldTransform(trans);
printf("world pos = %f,%f,%f\n",float(trans.getOrigin().getX()),float(trans.getOrigin().getY()),float(trans.getOrigin().getZ()));
}
}
}
お片づけ
//remove the rigidbodies from the dynamics world and delete them
for (i=dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
{
btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
dynamicsWorld->removeCollisionObject( obj );
delete obj;
}
//delete collision shapes
for (int j=0;j<collisionShapes.size();j++)
{
btCollisionShape* shape = collisionShapes[j];
collisionShapes[j] = 0;
delete shape;
}
//delete dynamics world
delete dynamicsWorld;
//delete solver
delete solver;
//delete broadphase
delete overlappingPairCache;
//delete dispatcher
delete dispatcher;
delete collisionConfiguration;
//next line is optional: it will be cleared by the destructor when the array goes out of scope
collisionShapes.clear();
}