Ogre中加入Bullet3物理引擎

一、bullet引擎简介

   Bullet是一个开源的物理模拟计算引擎,世界三大物理引擎模拟之一(另外两种是Havok和PhysX)。广泛应用于游戏开发和电影制作之中。Bullet也是AMD开放物理计划成员之一。

Bullet是一个跨平台的物理模拟计算引擎。支持Windows、Linux、MAC等多个平台。

二、bullet的主要函数

  在bullet中要实现物理世界需要三个函数,initPhysics()、stepSimulation()、exitPhysics()。

1、 initPhysics()函数

initPhysics()函数是初始化物理世界的一个函数。在该函数中首先要创建一个动态世界:btDiscreteDynamicsWorld* dynamicsWorld; 要想创建成功一个动态世界还需要四个参数,

分别为:

btBroadphaseInterface* broadphase;

btDefaultCollisionConfiguration*collisionConfiguration;

btCollisionDispatcher* dispatcher;

btSequentialImpulseConstraintSolver* solver;

这几个参数分别表示:

broadphase:一个阶段算法,目的是尽量剔除没有相互作用的对象对

collisionConfiguration:碰撞配置

dispatcher:碰撞调度器对象

solver:创建解算器,用于求解约束方程。

这四个类只需要实例化当做参数传入创建一个动态物理世界,这就成功的创建了一个空的动态物理世界,

 

     然后再在空的物理世界中加入其它的属性,首先加入一个重力,通过setGravity()设置物理世界的重力。接下来创建两个刚体btRigidBody* fallRigidBody; btRigidBody* groundRigidBody; 第一个刚体作为物理世界中的地面,第二个作为加入物理世界中的物体。创建一个刚要需要给刚体四个属性:mass(质量)、btDefaultMotionState(刚体的位置信息)btCollisionShape(刚体形状)fallInertia(惯性)。创建成功后,addRigidBody()加入到物理世界中。

 

     如此,初始化就完成了。

2、stepSimulation()

该函数主要是负责物理世界的更新,在每个时间段更新物理世界。这是Bullet中基类的一个虚函数,可以根据用户自己的需要进行重写调用。如果只是简单的加入一个物理世界的话,直接在framestarted函数中调用即可,但是要给它一个时间参数,让它知道什么时候更新。

 

3、exitPhysics()函数

该函数负责退出物理世界以及销毁物理世界。

该函数主要是在析构函数中调用。

 

 

三、Ogre中加入bullet物理引擎。

第一步、引用,引用该头文件,创建一个简单的物理世界所需的所有类和接口基本都在这里面。我在Ogre中提供的一个demo中加入了物理世界。首先将以及写好的initPhysics()函数放入setupContext()(建立场景的函数)中调用,(注:在这里调用该函数只是相当于创建了一个变量而没有使用它。)

 

第二步、接下来在ogre中的frameStarted()函数中调用stepSimulation()给它的参数为每一帧渲染完之后的时间(evt.timeSinceLastFrame 这是Ogre中已经封装好的直接用就可以)。

 

第三步、最后调用exitPhysics()函数销毁该物理世界即可。

 

第四步、物理世界只是相当于一种算法,一种规则,是抽象的,我们要想在demo中看到自己所创建的物理世界以及世界中我们创建的地面、物体刚体等需要用到bullet中提供的debugdraw的一个类,该类是bullet封装好让用户可以用来调试物理引擎的一个类。

 

 

 

 

 

 

 

 

 

 

 

 

 

成功加入物理世界后的demo截图:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

四、具体实现代码

定义的几个类,作为参数传入建立动态物理世界

 

    btBroadphaseInterface* broadphase;

    btDefaultCollisionConfiguration* collisionConfiguration;

    btCollisionDispatcher* dispatcher;

    btSequentialImpulseConstraintSolver* solver;

    btDiscreteDynamicsWorld* dynamicsWorld;

    btCollisionShape* groundShape;

    btCollisionShape* fallShape;

    btRigidBody* fallRigidBody;

    btRigidBody* groundRigidBody;

    btRigidBody* fallRigidBody1;

    brPhysicsDebugDrawer* m_pPhysicDebugDraw;

 

 

initPhysics()函数

 

 

 

    void initPhysics()

    {

        //        helper->setUpAxis(1);

        //        helper->createPhysicsDebugDrawer(dynamicsWorld);

        //        if (dynamicsWorld->getDebugDrawer())

        //           dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);

        //创建broadphase阶段算法,目的是尽量的剔除没有相互作用的对象对

        broadphase = new btDbvtBroadphase();

        //创建碰撞配置对象以及碰撞调度器对象,使我们可以再各个阶段尝试不同的算法组合,目的是使用不同的算法和测试相同的碰撞

        collisionConfiguration = new btDefaultCollisionConfiguration();

        dispatcher = new btCollisionDispatcher(collisionConfiguration);

        //创建解算器,用于求解约束方程。得到物体在重力等作用下的最终位置的

        solver = new btSequentialImpulseConstraintSolver;

        //创建一个动态世界

        dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);

        //设置动力学世界的重力为Y轴向下方向

        dynamicsWorld->setGravity(btVector3(0,-10,0));

       

        //创建平面和一个球体,第一个参数是平面的法向,第二个参数是在法线方向的偏移,注意,动力学世界方向是Y轴下方向

        groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);

        //1为球体的半径

        fallShape = new btSphereShape(10);

       

        groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);

        //1为球体的半径

        fallShape = new btSphereShape(10);

       

        //       if (dynamicsWorld->getDebugDrawer())

        //           dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);

       

        //加入一个平面到动力学世界

        btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion<

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值