本文述说物理引擎bullet3-2.83.5的环境搭建及Hello World程序说明。

Bullet简介

Bullet 物理引擎是一个专业的开放源码的碰撞检测,刚体和柔体动力学库。Bullet 物理引擎目标是实时和交互使用在游戏,电影和机器人的视觉效果。自由zlib授权的商业使用库。

主要特点:

  • 开源C ++代码下的zlib许可证,并自由使用在所有的平台,包括PLAYSTATION3,,XBOX 360,Wii,PC,Linux,Mac OSX,Android和iPhone。
  • 离散和连续碰撞检测包括射线和凸扫描测试。碰撞的形状包括凹凸面网格和所有基本图元。

  • 快速稳定的刚体动力学约束求解器,车辆动力学,角色控制滑块,铰链,通用的六自由度和扭转约束锥的布娃娃。

  • 布柔体动力学,绳和变形量与刚体双向互动,包括相互约束支持。

  • 本地二进制文件格式的例子。.bullet文件格式 和典型格式例如:URDF,Wavefront OBJ和Quake BSP。

搭建Bullet SDK和demos

源码下载:https://github.com/bulletphysics/bullet3/releases

使用Premake

windows系统:双击build3/vs2010.bat脚本自动生成vs2010 sln文件。

使用cmake

cmake下载安装地址http://www.cmake.org。打开cmake,source code:bullet3-2.83.5牧,binaries:bullet3-2.83.5/build。点击configure,你可以选择vs2010 ~vs2013。build目录下就会产生对应的vs版本BULLET_PHYSICS.sln文件。

Hello World

讨论基本Bullet物理模拟,通过控制台输出模拟结果。源码在examples/HelloWorld/HelloWorld.cpp。

HelloWorld.cpp包含头文件

#include "btBulletDynamicsCommon.h"
#include <stdio.h>

/// 最基本的Bullet物理模拟Hello Word 程序

int main(int argc, char** argv)
{

HelloWorld.cpp 初始化世界

  ///-----初始化开始-----

    //配置碰撞默认内存设置,碰撞,高级用户可创建自己的配置。
    btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();

    ///使用默认调度.为并行处理使用不同的调度做 (参考Extras / BulletMultiThreaded)
    btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);

    ///btDbvtBroadphase 是个很好通用粗测阶段. 你也可以尝试btAxis3Sweep.
    btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase();

    ///默认约束求解器. 为并行处理可以使用不同求解器 (参考Extras/BulletMultiThreaded)
    btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

    btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration);

 步进模拟

  for (i=0;i<100;i++)
    {
        dynamicsWorld->stepSimulation(1.f/60.f,10);

        //打印对象的坐标
        for (int j=dynamicsWorld->getNumCollisionObjects()-1; j>=0 ;j--)
        {
            btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j];
            btRigidBody* body = btRigidBody::upcast(obj);
            btTransform trans;
            if (body && body->getMotionState())
            {
                body->getMotionState()->getWorldTransform(trans);

            } else
            {
                trans = obj->getWorldTransform();
            }
            printf("world pos object %d = %f,%f,%fn",j,float(trans.getOrigin().getX()),float(trans.getOrigin().getY()),float(trans.getOrigin().getZ()));
        }
    }

 HelloWorld.cpp 清理

  //清理动态世界里的刚体
    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;
    }

    //清理碰撞形状
    for (int j=0;j<collisionShapes.size();j++)
    {
        btCollisionShape* shape = collisionShapes[j];
        collisionShapes[j] = 0;
        delete shape;
    }

    //清理动态世界
    delete dynamicsWorld;

    //清理求解器
    delete solver;

    //清理粗测阶段
    delete overlappingPairCache;

    //清理调度
    delete dispatcher;
    delete collisionConfiguration ;
     // 它将会被清理通过析构函数
    collisionShapes . clear ();