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

时间:2022-04-26 05:47:26

 Bullet介绍

       Bullet的主页 。最新版本在这里下载 。简单的中文介绍见百度百科 。一些也许可以促使你选择Bullet的小故事在以前的文章中有提及,参考这里 的开头--为什么选择Bullet。

       主要特征:

       * 代码用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
Bullet物理引擎不完全指南 in Linux


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


Hello World 

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

#include <iostream> 
#include <bullet/btBulletDynamicsCommon.h>

int main (void)
{

btBroadphaseInterface* broadphase = new btDbvtBroadphase();

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

btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

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

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


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

btCollisionShape* fallShape = new btSphereShape(1);


btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0)));
btRigidBody::btRigidBodyConstructionInfo
groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(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);


for (int i=0 ; i<300 ; i++) {
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;

return 0;
}

再创建CMakeLists.txt

cmake_minimum_required(VERSION 2.8)PROJECT (HELLO)SET(SRC_LIST main.cpp)INCLUDE_DIRECTORIES(/usr/local/include/bullet)LINK_LIBRARIES(BulletDynamics    BulletCollision    LinearMath    )ADD_EXECUTABLE(hello ${SRC_LIST})

 终端执行

cmake  .

make

运行效果如下:

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


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

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


术语表

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

基础项

单量 - Scalar

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

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


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

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

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

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

例如:

#define THRESHOLD 20#define THRESHOLD_SQ THRESHOLD*THRESHOLD // Your compiler will optimise this out laterVector3 a(12,14,20);if(THRESHOLD > a.length()) { do_something; } // This one is much slowerif(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(θ)

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

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



欧拉角 - 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

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


参考

Bullet物理引擎不完全指南(Bullet Physics Engine not complete Guide) - http://blog.csdn.net/vagrxie/article/details/5952310

Bullet Tutorial Articles - http://bulletphysics.org/mediawiki-1.5.8/index.php/Tutorial_Articles