/// 剛体を質量(mass)、動作状態の初期ベクター(motion_transform_origin_vector)、 衝突形状(collision_shape)を元に生成し、 /// 動力学の世界へ追加します。 void create_rigidbody ( btScalar mass , const btVector3& motion_transform_origin_vector , const std::unique_ptr<btCollisionShape>& collision_shape ) { // 動作状態を生成し、初期化し、motion_transform_origin_vectorを適用します btTransform motion_transform; motion_transform.setIdentity(); motion_transform.setOrigin(motion_transform_origin_vector); // 剛体は、もしmassが非ゼロならば動的だし、そうでなければ静的なのだ bool isDynamic = (mass != 0.f); // 物体に働く局所的な慣性を定義します btVector3 localInertia(0, 0, 0); // 剛体が動的な場合には、衝突形状から局所的な慣性を計算します if (isDynamic) collision_shape->calculateLocalInertia(mass, localInertia); // motionstateの使用を推奨するよ、なぜなら'active'なオブジェクト群だけとの同期と補間機能を提供してくれるからだ std::unique_ptr<btDefaultMotionState> myMotionState( new btDefaultMotionState(motion_transform) ); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState.get(), collision_shape.get(), localInertia); std::unique_ptr<btRigidBody> body( new btRigidBody(rbInfo) ); // 物体を動力学の世界へ追加します world->addRigidBody( body.get() ); // ローカルスコープのmyMotionStateオブジェクトの管理をmotion_statesへstd::moveしクラススコープに移管します motion_states.emplace_front(std::move(myMotionState)); // ローカルスコープのbodyオブジェクトの管理をbodiesへstd::moveしクラススコープに移管します bodies.emplace_front(std::move(body)); }
int main(int argc, char** argv) { sf::RenderWindow* RenderWin = new sf::RenderWindow(sf::VideoMode(WIDTH, HEIGHT, 32), "lol test"); RenderWin->UseVerticalSync(true); // Collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration. boost::shared_ptr<btDefaultCollisionConfiguration> collisionConfiguration(new btDefaultCollisionConfiguration()); // Use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded). boost::shared_ptr<btCollisionDispatcher> dispatcher(new btCollisionDispatcher(collisionConfiguration.get())); // btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep. boost::shared_ptr<btBroadphaseInterface> broadphase(new btDbvtBroadphase()); // The default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded). boost::shared_ptr<btVoronoiSimplexSolver> simplex(new btVoronoiSimplexSolver()); boost::shared_ptr<btMinkowskiPenetrationDepthSolver> pd_solver(new btMinkowskiPenetrationDepthSolver()); boost::shared_ptr<btSequentialImpulseConstraintSolver> solver(new btSequentialImpulseConstraintSolver()); boost::shared_ptr<btDiscreteDynamicsWorld> dynamicsWorld(new btDiscreteDynamicsWorld(dispatcher.get(), broadphase.get(), solver.get(), collisionConfiguration.get())); boost::shared_ptr<btConvex2dConvex2dAlgorithm::CreateFunc> convex_algo_2d(new btConvex2dConvex2dAlgorithm::CreateFunc(simplex.get(),pd_solver.get())); dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE, convex_algo_2d.get()); dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE, convex_algo_2d.get()); dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE, convex_algo_2d.get()); dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE, new btBox2dBox2dCollisionAlgorithm::CreateFunc()); // Set gravity to 9.8m/s² along y-axis. dynamicsWorld->setGravity(btVector3(0, 1, 0)); // Get us some debug output. Without this, we'd see nothing at all. boost::shared_ptr<DebugDraw> debugDraw(new DebugDraw(RenderWin)); debugDraw->setDebugMode(btIDebugDraw::DBG_DrawWireframe); dynamicsWorld->setDebugDrawer(debugDraw.get()); // Keep track of the shapes, we release memory at exit. // Make sure to re-use collision shapes among rigid bodies whenever possible! btAlignedObjectArray<btCollisionShape*> collisionShapes; // Create a ground body. btScalar thickness(0.2); boost::shared_ptr<btCollisionShape> groundShape(new btBoxShape(btVector3(btScalar(WIDTH / 2 * METERS_PER_PIXEL), thickness, btScalar(10)))); collisionShapes.push_back(groundShape.get()); btTransform groundTransform(btQuaternion(0, 0, 0, 1), btVector3(WIDTH / 2 * METERS_PER_PIXEL, HEIGHT * METERS_PER_PIXEL, 0)); // Using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects. boost::shared_ptr<btDefaultMotionState> groundMotionState(new btDefaultMotionState(groundTransform)); btRigidBody::btRigidBodyConstructionInfo ground_rbInfo(0, groundMotionState.get(), groundShape.get(), btVector3(0, 0, 0)); boost::shared_ptr<btRigidBody> ground_body(new btRigidBody(ground_rbInfo)); ground_body->setLinearFactor(btVector3(1,1,0)); ground_body->setAngularFactor(btVector3(0,0,1)); // Add the body to the dynamics world. dynamicsWorld->addRigidBody(ground_body.get()); // Create left wall. btTransform leftWallTransform(btQuaternion(0, 0, 1, 1), btVector3(0, HEIGHT / 2 * METERS_PER_PIXEL, 0)); boost::shared_ptr<btDefaultMotionState> leftWallMotionState(new btDefaultMotionState(leftWallTransform)); btRigidBody::btRigidBodyConstructionInfo leftWall_rbInfo(0, leftWallMotionState.get(), groundShape.get(), btVector3(0, 0, 0)); boost::shared_ptr<btRigidBody> leftwall_body(new btRigidBody(leftWall_rbInfo)); leftwall_body->setLinearFactor(btVector3(1,1,0)); leftwall_body->setAngularFactor(btVector3(0,0,1)); // Add the body to the dynamics world. dynamicsWorld->addRigidBody(leftwall_body.get()); // Create right wall. btTransform rightWallTransform(btQuaternion(0, 0, 1, 1), btVector3(WIDTH * METERS_PER_PIXEL, HEIGHT / 2 * METERS_PER_PIXEL, 0)); boost::shared_ptr<btDefaultMotionState> rightWallMotionState(new btDefaultMotionState(rightWallTransform)); btRigidBody::btRigidBodyConstructionInfo rightWall_rbInfo(0, rightWallMotionState.get(), groundShape.get(), btVector3(0, 0, 0)); boost::shared_ptr<btRigidBody> rightwall_body(new btRigidBody(rightWall_rbInfo)); rightwall_body->setLinearFactor(btVector3(1,1,0)); rightwall_body->setAngularFactor(btVector3(0,0,1)); // Add the body to the dynamics world. dynamicsWorld->addRigidBody(rightwall_body.get()); // Create ceiling btTransform topWallTransform(btQuaternion(0, 0, 0, 1), btVector3(WIDTH / 2 * METERS_PER_PIXEL, 0, 0)); boost::shared_ptr<btDefaultMotionState> topWallMotionState(new btDefaultMotionState(topWallTransform)); btRigidBody::btRigidBodyConstructionInfo topWall_rbInfo(0, topWallMotionState.get(), groundShape.get(), btVector3(0, 0, 0)); boost::shared_ptr<btRigidBody> topwall_body(new btRigidBody(topWall_rbInfo)); topwall_body->setLinearFactor(btVector3(1,1,0)); topwall_body->setAngularFactor(btVector3(0,0,1)); // Add the body to the dynamics world. dynamicsWorld->addRigidBody(topwall_body.get()); // Create dynamic rigid body. //btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); boost::shared_ptr<btCollisionShape> colShape(new btSphereShape(btScalar(0.6))); collisionShapes.push_back(colShape.get()); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0, 0, 0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); startTransform.setOrigin(btVector3(2, 5, 0)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects boost::shared_ptr<btDefaultMotionState> myMotionState(new btDefaultMotionState(startTransform)); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState.get(),colShape.get(),localInertia); boost::shared_ptr<btRigidBody> body(new btRigidBody(rbInfo)); body->setLinearFactor(btVector3(1,1,0)); body->setAngularFactor(btVector3(0,0,1)); dynamicsWorld->addRigidBody(body.get()); // Create lulz boost::ptr_list<btRigidBody> body_list; boost::ptr_list<btDefaultMotionState> motionstate_list; boost::ptr_list<btCollisionShape> colshape_list; for (int i=0;i <= 10; ++i) { if (i < 5) colshape_list.push_back(new btSphereShape(btScalar(sf::Randomizer::Random(0.1f, 0.8f)))); else colshape_list.push_back(new btBoxShape(btVector3(sf::Randomizer::Random(0.1f,0.8f), sf::Randomizer::Random(0.1f,0.8f), 10))); if (isDynamic) colshape_list.back().calculateLocalInertia(mass,localInertia); collisionShapes.push_back(&(colshape_list.back())); startTransform.setIdentity(); startTransform.setOrigin(btVector3(i,i,0)); motionstate_list.push_back(new btDefaultMotionState(startTransform)); btRigidBody* lol = new btRigidBody(btRigidBody::btRigidBodyConstructionInfo(mass,&(motionstate_list.back()),&(colshape_list.back()),localInertia)); lol->setLinearFactor(btVector3(1,1,0)); lol->setAngularFactor(btVector3(0,0,1)); body_list.push_back(lol); } BOOST_FOREACH (btRigidBody& body, body_list) { dynamicsWorld->addRigidBody(&body); }