Bullet物理引擎不完全指南 in Linux

发表于2017-09-12
评论0 2.4k浏览

 Bullet介绍

       Bullet 是一个比较流行的3D物理引擎,在游戏开发中会需要用到。

       主要特征:

       * 代码用C 构建,遵守zlib开源协议,可免费用于各种商业目的。跨平台支持,包括PS3,XBox 360...

       * 离散或是持续的碰撞检测。碰撞模型包括不规则物体和基本的图形;

       *  快速而稳定的刚体动力学约束求解,滑块和较链的模拟;

        * 衣服,绳子等柔软物体的模拟,支持约束 ;

        * 丰富的插件支持,包括maya,Blender...

      环境:ubuntu12.04 gcc4.6

安装

首先用svn把代码checkout下来

svn checkout http://bullet.googlecode.com/svn/trunk/

然后终端cd到目录,还是那一套:

./configure

make

sudo make install

执行完之后Demos也编译好了,终端运行

./AllBulletDemos/AppAllBulletDemos


可以点击右边的next scene 来切换demo。


Hello World 

参考官方wiki的helloworld教程,创建main.cpp

  1. #include   
  2.    
  3. #include   
  4.    
  5. int main (void)  
  6. {  
  7.    
  8.         btBroadphaseInterface* broadphase = new btDbvtBroadphase();  
  9.    
  10.         btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();  
  11.         btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);  
  12.    
  13.         btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;  
  14.    
  15.         btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);  
  16.    
  17.         dynamicsWorld->setGravity(btVector3(0,-10,0));  
  18.    
  19.    
  20.         btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);  
  21.    
  22.         btCollisionShape* fallShape = new btSphereShape(1);  
  23.    
  24.    
  25.         btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0)));  
  26.         btRigidBody::btRigidBodyConstructionInfo  
  27.                 groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));  
  28.         btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);  
  29.         dynamicsWorld->addRigidBody(groundRigidBody);  
  30.    
  31.    
  32.         btDefaultMotionState* fallMotionState =  
  33.                 new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50,0)));  
  34.         btScalar mass = 1;  
  35.         btVector3 fallInertia(0,0,0);  
  36.         fallShape->calculateLocalInertia(mass,fallInertia);  
  37.         btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass,fallMotionState,fallShape,fallInertia);  
  38.         btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);  
  39.         dynamicsWorld->addRigidBody(fallRigidBody);  
  40.    
  41.    
  42.         for (int i=0 ; i<300 ; i ) {  
  43.                 dynamicsWorld->stepSimulation(1/60.f,10);  
  44.    
  45.                 btTransform trans;  
  46.                 fallRigidBody->getMotionState()->getWorldTransform(trans);  
  47.    
  48.                 std::cout << "sphere height: " << trans.getOrigin().getY() << std::endl;  
  49.         }  
  50.    
  51.         dynamicsWorld->removeRigidBody(fallRigidBody);  
  52.         delete fallRigidBody->getMotionState();  
  53.         delete fallRigidBody;  
  54.    
  55.         dynamicsWorld->removeRigidBody(groundRigidBody);  
  56.         delete groundRigidBody->getMotionState();  
  57.         delete groundRigidBody;  
  58.    
  59.    
  60.         delete fallShape;  
  61.    
  62.         delete groundShape;  
  63.    
  64.    
  65.         delete dynamicsWorld;  
  66.         delete solver;  
  67.         delete collisionConfiguration;  
  68.         delete dispatcher;  
  69.         delete broadphase;  
  70.    
  71.         return 0;  
  72. }  

再创建CMakeLists.txt
  1. cmake_minimum_required(VERSION 2.8)  
  2. PROJECT (HELLO)  
  3. SET(SRC_LIST main.cpp)  
  4. INCLUDE_DIRECTORIES(  
  5.     /usr/local/include/bullet  
  6.     )  
  7. LINK_LIBRARIES(  
  8.     BulletDynamics  
  9.     BulletCollision  
  10.     LinearMath  
  11.     )  
  12.   
  13. ADD_EXECUTABLE(hello ${SRC_LIST})  

 终端执行

cmake  .

make

运行效果如下:



从wiki上看得出,这是模拟一个球体的抛物线。

这里需要注意一下,bullet只是负责计算!(据说最新的bullet已经使用OpenCL,将计算的任务放到了GPU),而图形渲染需要用到其他渲染引擎,比如OpenGL,Ogre等等。


术语表

下面的属于表也是来自bullet的官方wiki。

基础项

单量 - Scalar

单量其实就是数字,一个线性的值。比如1.0,1.23.单量可以用来构成其他的项。

比如,两点之间的距离就是一个单量,速度也是一个单量。


向量,3维向量,4维向量 - Vector

向量就是有方向的一段距离。

根据空间的维度,向量可分为2维,3维,4维。

三维向量的长度根据勾股定理可以用来计算,对应的就是向量的lengh方法,求根的算法非常消耗复杂,所以向量类有length2(),得到的就是没有开根的结果。

例如:

  1. #define THRESHOLD 20  
  2. #define THRESHOLD_SQ THRESHOLD*THRESHOLD // Your compiler will optimise this out later  
  3.   
  4. Vector3 a(12,14,20);  
  5. if(THRESHOLD > a.length()) { do_something; } // This one is much slower  
  6. if(THRESHOLD_SQ > a.length2()) {do_something; } // Use this version if you can  

欧拉坐标 - Euler co-ordinates

就是三维坐标,vector3(x,y,z)表示的就是三维空间中的一个点。


极坐标 - Polar co-ordinates

在 平面内取一个定点O, 叫极点,引一条射线Ox,叫做极轴,再选定一个长度单位和角度的正方向(通常取逆时针方向)。对于平面内任何一点M,用ρ表示线段OM的长度,θ表示从Ox到OM的角度,ρ叫做点M的极径,θ叫做点M的极角,有序数对 (ρ,θ)就叫点M的极坐标,这样建立的坐标系叫做极坐标系。

平面中圆的极坐标表达式是:

x  = ρ cos(θ) ;  y = ρ sin(θ)

空间球体的极坐标表达式是:




欧拉角 - Euler Angle

欧拉角主要用于描述一个旋转,对空间中的一个点进行旋转通常可以描述为:先绕 x 旋转一个角,再绕 y 轴旋转一个角,再绕 z 轴旋转一个角,最后得到最终坐标。

由于电脑是一只只会线性计算的怪兽,嗷唔~ 在使用欧拉角进行旋转的时候可能会出现一种很蛋疼的情况 - 万圣节锁 youtube video explaining gimbal lock


为了避免万圣节锁,一个方法是设定好旋转轴的旋转顺序。

另一中方法是使用四元组。


四元组 - Quaternion

四元数一般定义如下:
q=w xi yj zk

其中v=(x,y,z)是矢量,w是标量,虽然v是矢量,但不能简单的理解为3D空间的矢量,它是4维空间中的的矢量,也是非常不容易想像的。
通俗的讲,一个四元数(Quaternion)描述了一个旋转轴和一个旋转角度。这个旋转轴和这个角度可以通过 Quaternion::ToAngleAxis转换得到。当然也可以随意指定一个角度一个旋转轴来构造一个Quaternion。这个角度是相对于单位四元数而言的,也可以说是相对于物体的初始方向而言的。
当用一个四元数乘以一个向量时,实际上就是让该向量围绕着这个四元数所描述的旋转轴,转动这个四元数所描述的角度而得到的向量。


轴角 - AxisAngle

也是用来描述一个旋转。

旋转的轴角表示用两个值参数化了旋转: 一个轴或向量,和描述绕这个轴的旋转量的一个角。它也叫做旋转的指数坐标。
有时也叫做旋转向量表示,因为这两个参数(轴和角)可用在这个轴上的其模是旋转角的一个向量来表示。


合成项

变换 - Transform

变换就是一个位移加上一个旋转。


矩阵 - Matrix

所有的变换都可以用矩阵的运算来实现。但是要注意渲染系统的矩阵算法的实现和bullet中的是否是一样的。


物理项

刚体 - Rigid Body

刚体有着固定的质量、尺寸和其他的物理属性,它时物理模拟中最基础的项。


节点约束 - Joint,constraint

节点约束就是用于连接两个物体的地方,连接的方式又很多中,一种是简单的连接,连接的地方可以旋转,还有一种是绞接,只能单向运动。


世界 - World

所有的物体,所有的刚体,软体都在世界中,整个模拟系统就是一个世界。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论