加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Bullet教程(1)

(2011-01-13 20:41:08)
标签:

杂谈

分类: 物理引擎

       编译及环境设置就不说了,我想用bullet的人,肯定都有c++基础以及Vsiualstudio开发的经历。

       这篇文章主要在bullet中实现一下helloworld程序,bullet官网上也有该教程。

      首先在vs2008中建一个win32控制台程序,并增加头文件<btBulletDynamicsCommon.h>及bullet中相应库文件

#include "stdafx.h"
#include <iostream>
#include <btBulletDynamicsCommon.h>
 
#pragma comment (lib,"BulletCollision.lib") //碰撞检测库文件
#pragma comment (lib,"BulletDynamics.lib")  //动力学库文件
#pragma comment (lib,"LinearMath.lib")      //线性代数库文件
 
int _tmain(int argc, _TCHAR* argv[])
10  {
11      std::cout << "Hello World!" << std::endl;
12      return 0;
13  }
14   

       下面先了解一下bullet中刚体物理模拟的Pipeline(管线)

http://s15/middle/61feffe1499b9a1d1214e&amp;690

     可以看到,管线一开始会先对物理模拟世界中的物体施加重力,结束时会计算物体的最终位置,并实位移操作。

     所有的这些管线操作,在bullet中都抽象的称为动力学世界(dynamics world),当我们执行dynamicsWorld->stepSimulation函数时,管线的每个阶段都会执行。缺省的动力学世界是btDiscreteDynamicsWorld,在helloworld程序中,我们也会使用该对象类创建动力学世界。

现在开始helloworld的代码:

     首先需要指定broadphase阶段的算法。假设动力学世界中有n个物体,极端情况下,每两个物体之间都有相互作用关系,问题的复杂度是N^2,broadphase阶段的的作用就是尽量剔除没有相互作用的物体对(pairs)。代码如下:

 btBroadphaseInterface* broadphase = new btDbvtBroadphase();

    接下来创建碰撞配置对象和调度器对象,通过配置对象(CollisionConfiguration),我们可以在管线各个阶段尝试不同的算法组合。

btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
 

   下面创建解算器(solver),解算器就是求解约束方程,得到物体在一些外力约束情况下(比如重力)最终的位置,速度等。

btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

下面实例化一个动态世界对象(dynamics objects),需要用前面创建的几个参数作为输入参数,同时设置动力学世界的重力为y轴向下方向:

 

btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
 
dynamicsWorld->setGravity(btVector3(0,-10,0))
 
 

    接下来的代码就是在动力学世界中创建物体,我们创建一个平面和一个球体。

//第一个参数是平面的法向,第二个参数是在法线方向的偏移

btCollisionShape* groundShape = newtaticPlaneShape(btVector3(0,1,0),1); 

//1为球体的半径

btCollisionShape* fallShape = new btSphereShape(1);
 

   下面代码把球体和平面加到dynamicsWorld中,这要用到btDefaultMotionState对象,该对象包括一个表示旋转的四元数以及一个位移向量。

btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0)));
 
btRigidBody::btRigidBodyConstructionInfo
 
groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));//地面是静态的,所以惯性为0向量,静态物体质量也为0,第一个参数为物体质量,最后一个参数为物体惯性
 
btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);//绑定操作
 
dynamicsWorld->addRigidBody(groundRigidBody);
 
btDefaultMotionState* fallMotionState =
 
new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50,0)));
 
btScalar mass = 1; //质量
 
btVector3 fallInertia(0,0,0);//惯性
 
fallShape->calculateLocalInertia(mass,fallInertia); //通过质量,这个函数计算出运动物体的惯性
 
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass,fallMotionState,fallShape,fallInertia);
 
btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
 
dynamicsWorld->addRigidBody(fallRigidBody);
 
 

    接下来启动物体模拟操作,并打印出球体在各个时刻位置,可以从dos窗口看到物体从高度50米的地方不断下落,最后停留在(0,1,0)的位置。

while(1) {
    dynamicsWorld->stepSimulation(1/60.f,10);
 
    btTransform trans;
    fallRigidBody->getMotionState()->getWorldTransform(trans);
 
    std::cout << "sphere height: " << trans.getOrigin().getY() << std::endl;
}
 
 

    在程序的尾部不要忘记删除创建的对象:

dynamicsWorld->removeRigidBody(fallRigidBody);
delete fallRigidBody->getMotionState();
delete fallRigidBody;
 
dynamicsWorld->removeRigidBody(groundRigidBody);
delete groundRigidBody->getMotionState();
delete groundRigidBody;
 
 
delete fallShape;
 
delete groundShape;
 
 
delete dynamicsWorld;
delete solver;
delete collisionConfiguration;
delete dispatcher;
delete broadphase;
 
 

最终的代码:

#include "stdafx.h"
#include <iostream>
#include <btBulletDynamicsCommon.h>
 
#pragma comment (lib,"BulletCollision.lib") //碰撞检测库文件
#pragma comment (lib,"BulletDynamics.lib")  //动力学库文件
#pragma comment (lib,"LinearMath.lib")      //线性代数库文件
 
int _tmain(int argc, _TCHAR* argv[])
10  {
11      //创建broadphase阶段算法
12      btBroadphaseInterface* broadphase = new btDbvtBroadphase();
13   
14      //创建碰撞碰撞配置对象以及碰撞调度器对象
15      btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
16      btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
17   
18      //创建解算器
19      btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
20   
21      btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
22   
23      dynamicsWorld->setGravity(btVector3(0,-10,0));
24   
25   
26      //第一个参数是平面的法向,第二个参数是在法线方向的偏移
27      btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);
28   
29      //1为球体的半径
30      btCollisionShape* fallShape = new btSphereShape(1);
31   
32   
33      btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0)));
34      btRigidBody::btRigidBodyConstructionInfo
35          groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));
36      btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);//绑定操作
37      dynamicsWorld->addRigidBody(groundRigidBody);
38   
39   
40      btDefaultMotionState* fallMotionState =
41          new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50,0)));
42      btScalar mass = 1; //质量
43      btVector3 fallInertia(0,0,0);//惯性
44      fallShape->calculateLocalInertia(mass,fallInertia);
45      btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass,fallMotionState,fallShape,fallInertia);
46      btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
47      dynamicsWorld->addRigidBody(fallRigidBody);
48   
49   
50      //启动物理模拟
51      while(1) {
52          dynamicsWorld->stepSimulation(1/60.f,10);
53   
54          btTransform trans;
55          fallRigidBody->getMotionState()->getWorldTransform(trans);
56   
57          std::cout << "sphere height: " << trans.getOrigin().getY() << std::endl;
58      }
59   
60      //删除创建的对象
61      dynamicsWorld->removeRigidBody(fallRigidBody);
62      delete fallRigidBody->getMotionState();
63      delete fallRigidBody;
64   
65      dynamicsWorld->removeRigidBody(groundRigidBody);
66      delete groundRigidBody->getMotionState();
67      delete groundRigidBody;
68   
69   
70      delete fallShape;
71   
72      delete groundShape;
73   
74   
75      delete dynamicsWorld;
76      delete solver;
77      delete collisionConfiguration;
78      delete dispatcher;
79      delete broadphase;
80      return 0;
81  }
82   

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有