资源描述
bullet物理引擎教程hello world【译】 2008年 10 月 28 日 星期二 09:51教程: Hello World 实例水平原因 不足之处 还望指出更多信息请关注物理弓丨擎中文社区 欢迎加qq群52821727讨论更多关于Bullet的东西这篇文章里我们将尽可能简单的向你展示怎么使用 Bullet, 怎样初始化Bullet,设置一个动力学世界,还有一个球落向地表这个对鉴别你的build是 否成功非常有用并且也能够让你快速的学习到Bullet的API.首先,我们假设 你的Bullet已经正确安装并且正确设置了 Bullet的include路径(例如. /usr/local/include/bullet) 确保能连接到正确的 lib. 否则请参阅Installation安装.如果你用的是gcc来编译,请确保你的静态库反序,就是说. dynamics, collision, math.在本页底部给出了所有的源代码edit初始化程序以一个标准的 hello world 程序开始:#include int main ()std:cout Hello World! std:endl; return 0;edit创建世界现在我们要添加一个子弹(Bullet)模拟.首先写入以下语句:#include 我们想把 btDiscreteDynamicsWorld 实例化但是在做此之前我们还需要解决一 些其他事情.对于一个“hello world”例子来说它太复杂我们并不需要.但 是,为了能更符合我们自己的工程,他们可以用来微调(fine-tuning)模拟环 境.我们需要指出使用什么样的Broadphase algorithm (宽相算法).选择什么样 的泛型算法很总要,如果有许多刚体在绘制场景里,since it has to somehow check every pair which when impleme nted naivel y(天真)is an 0(n2) problem.宽相(broadphase)使用 传统的近似物体形状并且被称之为代理.我们需要提前 告诉子弹最大的代理数, 所以才能很好的分配内存避免浪费.下面就是世界里 任何时候的最大刚体数.int maxProxies = 1024;一些broadphases使用特殊的结构要求世界的尺度提前被告知,就像我们现在 遇到的情况一样.该broadphase可能开始严重故障,如果离开这个物体体积.因为 the AxisSweep broadphase quantizes 空间基于我们使用的整个空间的大 小, 您想这差不多等于你的世界.使它小于你的世界将导致重大问题, 使它大于你的世界将导致低劣的性能.这是 你程序调整的一个简单部分, 所以为了确保数字的正确多花点时间也不防.在这个例子中,世界从起点开始延伸10公里远。btVector3 worldAabbMin(-10000,-10000,-10000);btVector3 worldAabbMax(10000,10000,10000);这个broadphase是我们将要使用的,这个执行的是扫描和裁剪,这里可以看到 更多解释 Broadphase .btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);该broadphase是一个极好的空间以消除不应碰撞的成队物体.这是为了提高运 行效率.您可以使用碰撞调度注册一个回调,过滤器重置broadphase代理,使碰撞系统 不处理系统的其它无用部分. 更多信息请看 Collision Things 碰撞配置可以让你微调算法用于全部(而不是不是broadphase )碰撞检测。这个方面现在还属于研究阶段 btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);我们还需要一个solver.这是什么原因导致物体进行互动得当,考虑到重力, 游戏逻辑等的影响,碰撞,会被制约.它工作的很好,只要你不把它推向极端,对于在任何高性能仿真都有瓶颈. 有一些相似的可以线程模型:.btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;终于我们可以初始化了世界了:btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfigu ration);很明显我们把重力方向设置成了Y轴的负方向,即Y轴是像上的dynamicsWorld-setGravity(btVector3(0,-10,0);子弹的政策是“谁分配,也删除” 记住,必须符合这样的结果在main ()后记的删除.我们提供了一个通用的结果. 代码如下:#include #include int main () std:cout Hello World! addRigidBody(groundRigidBody);新增下跌领域非常相似。我们将其置于 50米以上的地面.btDefaultMotionState* fallMotionState =new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50 ,0);由于它是动态刚体,我们将给予质量 1 公斤。我不记得如何计算一个球体的惯性, 但是,这并不重要,因为子弹提供它的实现 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);一个快速的解释 btRigidBody:btRigidBodyConstructionInfo 是为了; 物体的 构建是通过某些参数的. 这是通过一个特殊的结构实现的。 该部分的 btRigidBodyConstructionInfo 被复制到物体当你建造的时候,并只用于在初始 化的时候. 如果你想创建几千个属性一样的物体, 你只需要建立一个 btRigidBodyConstructionInfo, 并通过它创建所有的.edit开始模拟这就是有趣的开始。我们会加强模拟 200 倍,间隔 60赫兹. 这使它有足够的时 间降落的地面上. 每一步, 我们都会打印出它离地面的高度.这stepSimulation在做你所期待,不过他的接口确实很复杂.读Stepping The World以获得更多消息.进后,我们审查的状态下降领域. 位置和方向都封装在 btTranform 对象,我们摘 录下降领域的运动状态. 我们只关心位置,我们退出变换 getOrigin ( ) 。 然后,我们打印 y 组成部分的立场载体.for (int i=0 ; istepSimulation(1/60.f,10);btTransform trans;fallRigidBody-getMotionState()-getWorldTransform(trans);std:cout sphere height: trans.getOrigin().getY() std:endl;这应该产生一个输出看起来像这样的东西: sphere height: 49.9917sphere height: 49.9833sphere height: 49.9722sphere height: 49.9583sphere height: 49.9417sphere height: 49.9222sphere height: 49.9 sphere height: 1sphere height: 1sphere height: 1sphere height: 1sphere height: 1看起来不错迄今。如果你图这对输出迭代次数,你就会得到这个:这个球体开始于地表的一米处. 这是因为取的是几何中心并且它的半径为 1 米. 这个球刚开始会有一个大的反弹然后渐渐的减缓弹起高度.这是可以预料的实时物理引擎,但它可以尽量减少,增加频率的模拟步骤. 试试再说 !现在你可以把这个动态世界代入你的程序 实时绘制出这个球体. 也可以看看其 他的Collision Shapes .试试一堆盒子 或者圆柱体然后用一个球去扔向他们.edit#include #include int main (void)btVector3 worldAabbMin(-10000,-10000,-10000);btVector3 worldAabbMax(10000,10000,10000);int maxProxies = 1024;btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfigu ration);dynamicsWorld-setGravity(btVector3(0,-10,0); btCollisionShape* groundShape = newbtStaticPlaneShape(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:btRigidBodyConstructionInfogroundRigidBodyCI(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 ; istepSimulation(1/60.f,10);btTransform trans;fallRigidBody-getMotionState()-getWorldTransform(trans);std:cout sphere height: trans.getOrigin().getY() 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;
展开阅读全文