首页 > 代码库 > Bullet(Cocos2dx)之分析刚体创建与销毁(Primitives)
Bullet(Cocos2dx)之分析刚体创建与销毁(Primitives)
相关链接:http://bulletphysics.org/mediawiki-1.5.8/index.php/Collision_Shapes
Bullet基本图形简介
Bullet提供的基本图形包括球体、长方体、圆柱体、胶囊体、圆锥体、多球体
当然还有一个Plane,一个无限的平面
1.球体是个很简单的形状:
btSphereShape (btScalar radius) 提供一个球体的半径
2.长方体(盒子)
btBoxShape (const btVector3 &boxHalfExtents) 提供盒子的半尺寸(长宽高的一半)
3.圆柱体(类似box shape)
btCylinderShape (const btVector3 &halfExtents) 提供半尺寸 (半径, 高度, 不知)
默认轴为y轴,btCylinderShapeX (x轴), btCylinderShapeZ(z轴)
4.胶囊体
btCapsuleShape (btScalar radius, btScalar height) 提供半球形半径, 圆柱体高度, 实际高度为2*radius + height
默认轴为y轴,btCapsuleShapeX (x轴), btCapsuleShapeZ(z轴)
5.圆锥体
btConeShape (btScalar radius, btScalar height) 提供底面半径, 高度
默认轴为y轴,btConeShapeX (x轴), btConeShapeZ(z轴)
6.多球体(多个球体组合)
btMultiSphereShape (const btVector3 *positions, const btScalar *radi, int numSpheres)
positions每个球体的位置,radi每个球体的半径, 球体个数
创建刚体
1.首先获取要创建的刚体形状,以box为例
btCollisionShape* colShape = new btBoxShape(size * 0.5f); // halfSize
因为btBoxShape继承自btCollisionShape
2.设置刚体的其他基本信息
(1).刚体的变换矩阵
(2).刚体的惯性(动态物体才有)
(3).MotionState提供插值,同步活动的物体等
(4).刚体的材质信息
(5).创建刚体
btTransform startTransform; // 1 startTransform.setIdentity(); startTransform.setOrigin(position); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (material.mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(material.mass, localInertia); // 2 //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); // 3 btRigidBody::btRigidBodyConstructionInfo rbInfo(material.mass, myMotionState,colShape,localInertia); // 4 rbInfo.m_restitution = material.restitution; rbInfo.m_friction = material.friction; rbInfo.m_rollingFriction = material.rollingFriction; btRigidBody* body = new btRigidBody(rbInfo); // 5
3.将刚体添加到world
_world->addRigidBody(body);
销毁刚体
1.因为刚体继承自btCollisionObject所以从world获取_world->getCollisionObjectArray()
2.如果obj为刚体则要转换为刚体btRigidBody* body = btRigidBody::upcast(obj);
因为刚体有可能包含MoitonState,
3.删除刚体的MotionState,和CollisionShape,(CollisionShape不就是obj吗?查看两者的值是不一样的)
4.从世界移除obj,不是应该移除刚体吗?看源码注释可知
///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btCollisionWorld::removeCollisionObject
virtual void removeCollisionObject(btCollisionObject* collisionObject);
5.释放obj,因为是用new 生成的,new实际是Bullet的内存分配方式,重载new
6.释放完毕
//remove the bodies from the dynamics world and delete them for (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(obj); delete obj; }
Bullet(Cocos2dx)之分析刚体创建与销毁(Primitives)