Bullet物理引擎的安装与使用
图形赋予游戏一种视觉的吸引力,但是能够让游戏的世界鲜活起来的还应该是内部的物理引擎。物理引擎是游戏引擎中的子模块,是一种软件组件,可仿真物理系统。它根据牛顿力学定律,计算游戏中物体的合理的物理位置,并将计算结果提供给渲染引擎,从而展示出真实的渲染效果。物理引擎的仿真包括柔性体和刚体力学、流体力学以及碰撞检测。以游戏为中心的物理引擎侧重于实时近似,而科学仿真中的物理引擎则更多地侧重于精确计算以获得高准确性。科学物理引擎依赖于超级计算机的处理能力,而游戏物理引擎则可运行于资源受限的平台(比如手持型游戏设备和移动手机)。

图 1. 游戏应用中的物理引擎
Bullet Physics SDK: real-time collision detection and multi-physics simulation for VR, games, visual effects, robotics, machine learning etc.
- Build bullet
下载Bullet的源代码 https://github.com/bulletphysics/bullet3/releases/latest,然后将其解压到合适的路径下。可以选择运行批处理文件生成VisualStudio工程,这里运行build_visual_studio.bat生成VS2010工程。

在Debug模式下生成解决方案,解压后的bullet3-2.86.1目录中会出现bin文件夹,其中包含了生成的静态库文件和可执行文件。

- HelloWorld example
新建一个空的控制台程序,然后在源文件目录中加入HelloWorld.cpp文件:
#include <btBulletDynamicsCommon.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
using namespace std; /// This is a Hello World program for running a basic Bullet physics simulation int main(int argc, char** argv)
{ btBroadphaseInterface* broadphase = new btDbvtBroadphase(); ///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); ///use the default collision dispatcher. For parallel processing you can use a differnt dispatcher
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); ///the default constraint solver. For parallel processing you can use a different solver
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; ///instantiate the dynamics world
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); ///sets the gravity. We have chosen the Y axis to be "up".
dynamicsWorld->setGravity(btVector3(,-,)); btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(, , ), );
btCollisionShape* fallShape = new btSphereShape(); //The btDefaultMotionState provides a common implementation to synchronize world transforms with offsets.
btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(, , , ), btVector3(, -, ))); ///instantiate the ground. Its orientation is the identity, Bullet quaternions are specified in x,y,z,w form.
btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(, groundMotionState, groundShape, btVector3(, , )); ///Bullet considers passing a mass of zero equivalent to making a body with infinite mass - it is immovable
btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI); ///add the ground to the world
dynamicsWorld->addRigidBody(groundRigidBody); //The btTransform class supports rigid transforms with only translation and rotation
btDefaultMotionState* fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(, , , ), btVector3(, , ))); btScalar mass = ;
btVector3 fallInertia(, , );
fallShape->calculateLocalInertia(mass, fallInertia); ///when bodies are constructed, they are passed certain parameters. This is done through a special structure Bullet provides for this.
///rigid body is dynamic if and only if mass is non zero, otherwise static
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, fallMotionState, fallShape, fallInertia);
btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
dynamicsWorld->addRigidBody(fallRigidBody); ofstream outfile("C:\\Users\\KC\\Desktop\\height.csv", ios::out);
for (int i = ; i < ; i++) { /* prototype:
btDynamicsWorld::stepSimulation(btScalar timeStep, int maxSubSteps=1,
btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
*/ //It's important that timeStep is always less than maxSubSteps*fixedTimeStep
//The first and third parameters to stepSimulation are measured in seconds
//By decreasing the size of fixedTimeStep, you are increasing the "resolution" of the simulation.
//When you pass Bullet maxSubSteps > 1, it will interpolate movement for you
dynamicsWorld->stepSimulation( / .f, ); btTransform trans;
fallRigidBody->getMotionState()->getWorldTransform(trans); std::cout << "sphere height: " << trans.getOrigin().getY() << std::endl;
outfile<<trans.getOrigin().getY()<<endl;
} outfile.close(); delete fallShape;
delete groundShape; delete dynamicsWorld;
delete solver;
delete dispatcher;
delete collisionConfiguration;
delete broadphase; printf("Press a key to exit\n");
getchar();
}
在项目属性——>C/C++ ——>常规——>附加包含目录中添加头文件的路径:D:\bullet3-2.86.1\src

在C/C++ ——>常规——>代码生成——>运行库选项中选择:多线程调试(/MTd)。Make sure the run-time library is the same as in your project. By default it is set to the multi-threaded, static version. 即之前在build bullet时默认生成的是静态库,则在编译debug程序时应选择/MTd。一个程序中若混合了不同的运行时库(静态库和动态库,调试库和非调试库),可能会产生冲突,所以一个程序中应该使用相同的运行时库。

在链接器——>常规——>附加库目录中输入静态库路径:D:\bullet3-2.86.1\bin

然后在链接器——>输入——>附加依赖项中添加必须的静态库(release版的静态库文件名中没有_debug后缀)

设置完成开始运行。上面的代码将创建一个半径为1的球体和一个静态地面,球中心距地面高度为50m,球的质量为1Kg。然后模拟重力(重力加速度沿Y轴负方向,大小为10m/s2)作用下的自由落体运动,仿真步长为1/60s,即每秒计算60次,运行300步(5s)。虽然仿真需要大量的设置,但是当定义了仿真环境之后,物理引擎就会在幕后为你完成全部的繁重工作。仿真时每运行一步输出球中心的高度数据:

将数据记录在CSV文件中,画出高度随时间变化的曲线如下图所示:
- Build and install pybullet
pybullet is an easy to use Python module for physics simulation, robotics and machine learning based on the Bullet Physics SDK. With pybullet you can load articulated bodies from URDF, SDF and other file formats. pybullet provides forward dynamics simulation, inverse dynamics computation, forward and inverse kinematics and collision detection and ray intersection queries. Aside from physics simulation, pybullet supports to rendering, with a CPU renderer and OpenGL visualization and support for virtual reality headsets. 安装pybullet有好几种方式,下面在https://pypi.python.org/pypi/pybullet网站上下载源文件pybullet-0.1.6.tar.gz并解压,切换到原文件目录中运行:python setup.py install。不过这时提示:Microsoft Visual C++ 9.0 is required Unable to find vcvarsall.bat,解决办法是可以安装一个Micorsoft Visual C++ Compiler for Python 2.7的包。经过一段时间编译(中途会弹出好多警告),在源文件目录的build\lib.win-amd64-2.7文件夹下可以找到pybullet.pyd,将其复制到C:\Python27\Lib\site-packages中。
下面的Python代码运行时作为客户端与Physics Engine服务端进行通信(pybullet is designed around a command-status driven API, with a client sending commands and a physics server returning the status. pybullet has some build-in physics servers: DIRECT and GUI. The DIRECT connection sends the commands directly to the physics engine, without using any transport layer, and directly returns the status after executing the command. The GUI connection will create a new graphical user interface with OpenGL rendering, within the same process space as pybullet)
import pybullet as p
from time import sleep physicsClient = p.connect(p.GUI)
p.setGravity(0,0,-10) # The loadURDF will send a command to the physics server to load a physics model from a URDF File
planeId = p.loadURDF("D:/bullet3-2.86.1/data/plane.urdf") cubeStartPos = [0,0,2]
cubeStartOrientation = p.getQuaternionFromEuler([0,0,0]) # The pybullet API uses quaternions to represent orientations.
boxId = p.loadURDF("D:/bullet3-2.86.1/data/sphere2.urdf",cubeStartPos, cubeStartOrientation) while 1:
# stepSimulation will perform all the actions in a single forward dynamics simulation step such as collision detection,
# constraint solving and integration. By default, the physics server will not step the simulation, unless you explicitly
# send a 'stepSimulation' command. This way you can maintain control determinism of the simulation.
p.stepSimulation() # reports the current position and orientation of the base of the body in Cartesian world coordinates
# returns the position list of 3 floats and orientation as list of 4 floats in [x,y,z,w] order.
# Use getEulerFromQuaternion to convert the quaternion to Euler if needed.
cubePos, cubeOrn = p.getBasePositionAndOrientation(boxId)
print(cubePos,cubeOrn)
sleep(0.01) # Time in seconds. p.disconnect() # disconnect from a physics server. A 'DIRECT' or 'GUI' physics server will shutdown
运行时服务端将显示对应的图形界面,仿真每进行一步输出球的质心位置和姿态


参考:
Creating a project from scratch
Visual Studio运行时库MT、MTd、MD、MDd的研究
Bullet物理引擎的安装与使用的更多相关文章
- Bullet物理引擎在OpenGL中的应用
Bullet物理引擎在OpenGL中的应用 在开发OpenGL的应用之时, 难免要遇到使用物理来模拟OpenGL中的场景内容. 由于OpenGL仅仅是一个关于图形的开发接口, 因此需要通过第三方库来实 ...
- 将 Android* Bullet 物理引擎移植至英特尔® 架构
简单介绍 因为眼下的移动设备上可以使用更高的计算性能.移动游戏如今也可以提供震撼的画面和真实物理(realistic physics). 枪战游戏中的手雷爆炸效果和赛车模拟器中的汽车漂移效果等便是由物 ...
- 转:Bullet物理引擎不完全指南(Bullet Physics Engine not complete Guide)
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie 讨论新闻组及文件 前言 Bullet据称为游戏世界占有率为第三的物理引擎,也是前几大引擎目前唯一能够 ...
- bullet物理引擎与OpenGL结合 导入3D模型进行碰撞检测 以及画三角网格的坑
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/11681069.html 一.初始化世界以及模型 /// 冲突配置包含内存的默认设置,冲突设置. ...
- 【Bullet引擎】Bullet物理引擎简单说明
说明 Bullet是一款开源的物理模拟计算引擎,包括刚体.柔体.弹性体等,是世界三大物理模拟引擎之一(包括Havok和PhysX),被广泛应用于游戏开发(GTA5等)和电影(2012等)制作中. Bu ...
- 链接收藏:bullet物理引擎不完全指南
这个也是博客园的文章,编辑得也很好,就不copy了,结尾还有PDF: https://www.cnblogs.com/skyofbitbit/p/4128347.html 完结
- 【AwayPhysics学习笔记】:Away3D物理引擎的简介与使用
首先我们要了解的是AwayPhysics这个物理引擎并不是重头开始写的新物理引擎,而是使用Flascc技术把一个已经很成熟的Bullet物理引擎引入到了Flash中,同时为了让as3可以使用这个C++ ...
- HTML5之2D物理引擎 Box2D for javascript Games 系列 第一部分
我要的是能在H5页面上跑的javascript版的Box2D啊!!! 最近想学习Javascript版本的Box2D JS物理引擎,无奈搜了半天也没找到相对比较系统的资料 官方网站也只是简单的介绍,A ...
- ROS数据可视化工具Rviz和三维物理引擎机器人仿真工具V-rep Morse Gazebo Webots USARSimRos等概述
ROS数据可视化工具Rviz和三维物理引擎机器人仿真工具V-rep Morse Gazebo Webots USARSimRos等概述 Rviz Rviz是ROS数据可视化工具,可以将类似字符串文本等 ...
随机推荐
- 【C++】拷贝构造函数(深拷贝,浅拷贝)详解
一.什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: ; int b = a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量. 下面看一个类对 ...
- hdu 1575 求一个矩阵的k次幂 再求迹 (矩阵快速幂模板题)
Problem DescriptionA为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input数据的第一行是一个T,表示有T组数据.每组数据的第一行有 ...
- day15--JavaScript
上节作业回顾 <style></style>代表的是CSS样式 <script></script>代表的是JavaScript样式 1. ...
- What Are You Talking About HDU1075
一开始我也想用map 但是处理不好其他字符.. 看了题解 多多学习! 很巧妙 就是粗暴的一个字符一个字符的来 分为小写字母和非小写字母两个部分 一但单词结束的时候就开始判断. #includ ...
- python使用 requirements.txt 管理所需的包
使用 requirements.txt 管理所需的包 2019/01/28 作者 若要与其他人共享项目.使用生成系统,或打算将项目复制到需要在其中还原环境的其他任何位置,必须指定项目需要的外部包. 建 ...
- 爬虫之Resquests模块的使用(二)
Requests Requests模块 Requests模块是一个用于网络访问的模块,其实类似的模块有很多,比如urllib,urllib2,httplib,httplib2,他们基本都提供相似的功能 ...
- 对扫描的pdf文件生成目录
很多pdf文件是直接扫描生成的,于是它的内容都是一张张的图片,当然就更没有目录索引了. 有的时候想找某些内容,只能一点点的移动滚动条,非常不方便. 那么有什么方法能生成目录呢? 方法一:使用福昕pdf ...
- Python 函数装饰器
首次接触到装饰器的概念,太菜啦! Python 装饰器可以大大节省代码的编写量,提升代码的重复使用率.函数装饰器其本质也是一个函数,我们可以把它理解为函数中定义了一个子函数. 例如我们有这么一个需求, ...
- hashCode方法的作用?
(1)前言,想要明白hashCode的作用,你必须要先知道Java中的集合. Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复 ...
- L1 与 L2 正则化
参考这篇文章: https://baijiahao.baidu.com/s?id=1621054167310242353&wfr=spider&for=pc https://blog. ...