Bullet(Cocos2dx)之封装PhysicsWorld3D
来源:互联网 发布:mysql 查询 编辑:程序博客网 时间:2024/04/28 12:23
Bullet3之封装PhysicsWorld3D
根据bullet3 HelloWorld程序去封装一个PhysicsWorld3D,
首先应该去创建一个物理世界,而对于一个物理世界,默认都有重力,提供一个创建
世界的静态方法(重力默认为(0, -10, 0))
static PhysicsWorld3D* create(const btVector3& gravity = btVector3(0, -10, 0));
负责创建世界,同时对世界初始化
这里创建一个btDiscreteDynamicsWorld
直接复制bullet3 HelloWorld对世界的初始化,并修改
_collisionConfiguration,_dispatcher, _solver, _overlappingPairCache, _drawer均为成员变量,
具体使用参照Bullet的文档
PhysicsWorld3D* PhysicsWorld3D::create(const btVector3& gravity){auto world = new PhysicsWorld3D;if (world && world->initWorld(gravity)){return world;}delete world;return nullptr;}bool PhysicsWorld3D::initWorld(const btVector3& gravity){_collisionConfiguration = new btDefaultCollisionConfiguration();_dispatcher = newbtCollisionDispatcher(_collisionConfiguration);_overlappingPairCache = new btDbvtBroadphase();_solver = new btSequentialImpulseConstraintSolver;_world = new btDiscreteDynamicsWorld(_dispatcher, _overlappingPairCache, _solver, _collisionConfiguration);if (_world == nullptr){return false;}_world->setGravity(gravity);return true;}
销毁一个物理世界
void PhysicsWorld3D::destroy(){this->clear();delete _collisionConfiguration;delete _dispatcher;delete _solver;delete _overlappingPairCache;delete _world;delete this;}void PhysicsWorld3D::clear(){int i;//remove the rigidbodies from the dynamics world and delete themfor (i = _world->getNumCollisionObjects() - 1; i >= 0; i--){btCollisionObject* obj = _world->getCollisionObjectArray()[i];btRigidBody* body = btRigidBody::upcast(obj);if (body && body->getMotionState()){delete body->getMotionState();delete body->getCollisionShape();}_world->removeCollisionObject(body);delete obj;}}
创建一些简单的body
由于每种body都有自己的材质信息
btRigidBodyConstructionInfo是构造一个刚体信息的结构体,
我们只需关心几个参数,
friction; // 摩擦系数
rollingFriction; // 滚动摩擦系数
restitution; // 恢复系数(弹性系数)
mass; // 质量
自己去实现一个简单的材质结构体
struct PhysicsMaterial3D{btScalar friction;btScalar rollingFriction;btScalar restitution;btScalar mass;PhysicsMaterial3D() :friction(0.0f),rollingFriction(0.f),restitution(0.f),mass(0.f){}PhysicsMaterial3D(btScalar aMass, btScalar aFriction, btScalar aRestitution, btScalar aRollingFriction) :friction(aFriction),rollingFriction(aRollingFriction),restitution(aRestitution),mass(aMass){}};
并提供一个默认的材质信息
const PhysicsMaterial3D PHYSICS_MATERIAL3D_DEFAULT(1.f, 0.5f, 0.5f, 0.0f);
实现构造3个基本物体,如下声明
btRigidBody* addPlane(const btVector3& normal, const btVector3& position, const PhysicsMaterial3D& material = PHYSICS_MATERIAL3D_DEFAULT);btRigidBody* addSphere(btScalar radius, const btVector3& position, const PhysicsMaterial3D& material = PHYSICS_MATERIAL3D_DEFAULT);btRigidBody* addBox(const btVector3& halfSize, const btVector3& position, const PhysicsMaterial3D& material = PHYSICS_MATERIAL3D_DEFAULT);
对于一个无限的平面,需要一个法向量决定Plane的朝向,同时position决定plane的位置,当然还有材质,但是mass必须为0
对于一个球体(Sphere)半径,位置,材质
对于一个盒子(Box)尺寸, 位置,材质
btRigidBody* PhysicsWorld3D::addPlane(const btVector3& normal, const btVector3& position, const PhysicsMaterial3D& material){CCAssert(material.mass == 0.f, "plane's mass must be 0."); // 特殊处理,保证mass为0btCollisionShape* groundShape = new btStaticPlaneShape(normal, 0.f);auto body = getBody(groundShape, position, material);_world->addRigidBody(body);return body;}btRigidBody* PhysicsWorld3D::addSphere(btScalar radius, const btVector3& position, const PhysicsMaterial3D& material){btCollisionShape* colShape = new btSphereShape(radius);auto body = getBody(colShape, position, material);_world->addRigidBody(body);return body;}btRigidBody* PhysicsWorld3D::addBox(const btVector3& size, const btVector3& position, const PhysicsMaterial3D& material){btCollisionShape* colShape = new btBoxShape(size * 0.5f); // halfSizeauto body = getBody(colShape, position, material);_world->addRigidBody(body);return body;}
构造一个刚体包含一些共同的步骤collisionShape, position, material
由于Plane,Sphere,Box collisionShape类型不同,所以单独实现,
其他的公共步骤可以抽离出来
btRigidBody* getBody(btCollisionShape* colShape, const btVector3& position, const PhysicsMaterial3D& material);
仿照HelloWorld构造body的方法
btRigidBody* PhysicsWorld3D::getBody(btCollisionShape* colShape, const btVector3& position, const PhysicsMaterial3D& material){/// Create Dynamic ObjectsbtTransform startTransform;startTransform.setIdentity();//rigidbody is dynamic if and only if mass is non zero, otherwise staticbool isDynamic = (material.mass != 0.f);btVector3 localInertia(0,0,0);if (isDynamic)colShape->calculateLocalInertia(material.mass, localInertia); // 计算物体惯性startTransform.setOrigin(position); // 设置物体位置//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objectsbtDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);btRigidBody::btRigidBodyConstructionInfo rbInfo(material.mass, myMotionState,colShape,localInertia);// 使用自定义的材质rbInfo.m_restitution = material.restitution;rbInfo.m_friction = material.friction;rbInfo.m_rollingFriction = material.rollingFriction;// 创建bodybtRigidBody* body = new btRigidBody(rbInfo);return body;}
不要忘了物理世界的更新
void PhysicsWorld3D::update(float dt){_world->stepSimulation(dt);}
完整源码
- Bullet(Cocos2dx)之封装PhysicsWorld3D
- Bullet(Cocos2dx)之使用cocos2dx测试PhysicsWorld3D
- Bullet(Cocos2dx)之使用cocos2dx测试PhysicsWorld3D
- Bullet3之封装PhysicsWorld3D
- Bullet(Cocos2dx)之优化PhysicsDraw3D
- Bullet(Cocos2dx)之创建地形
- Bullet(Cocos2dx)之优化PhysicsDraw3D
- Bullet(Cocos2dx)之创建地形
- Bullet(Cocos2dx)之Hello World(vs2012)
- Bullet(Cocos2dx)之增加调试绘制PhysicsDraw3D
- Bullet(Cocos2dx)之增加调试绘制PhysicsDraw3D
- Bullet(Cocos2dx)之交叉编译Android,集成到cocos2dx3.x
- Bullet(Cocos2dx)之分析刚体创建与销毁(Primitives)
- Bullet(Cocos2dx)之交叉编译Android,集成到cocos2dx3.x
- Bullet(Cocos2dx)之分析刚体创建与销毁(Primitives)
- Bullet(Cocos2dx)之凸多面体形状和组合形状
- Bullet的最小化功能封装
- Bullet(Cocos2dx)之内存泄露检测
- 2015跨年之殇
- linker command failed
- Linux shell 下载某一http页面中引用的jpg和gif文件
- linux下安装jdk7出现unpacking of archive failed on file
- Linux中使用指定用户运行命令
- Bullet(Cocos2dx)之封装PhysicsWorld3D
- LSCOLORS
- Luci
- qsort的用法
- mac with SQLSTATE[HY000] [2002] No such file or directory
- Metal 翻译的一塌糊涂
- java基础第三天、第四天
- MySQL 1067 错误产生的一种原因
- MySQL Workbench不能输入中文的解决