PhysicsWorld.cc
Go to the documentation of this file.00001 #ifdef HAVE_BULLET
00002
00003 #include "PhysicsWorld.h"
00004 #include "PhysicsBody.h"
00005 #include "MotorControllers.h"
00006 #include "Shared/debuget.h"
00007
00008 #ifdef __APPLE__
00009 #include <BulletDynamics/btBulletDynamicsCommon.h>
00010 #else
00011 #include <btBulletDynamicsCommon.h>
00012 #endif
00013 #if BT_BULLET_VERSION < 280
00014 # include <BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h>
00015 #endif
00016
00017 using namespace std;
00018
00019 static void ticCallback(btDynamicsWorld *world, btScalar timeStep) {
00020 static_cast<PhysicsWorld*>(world->getWorldUserInfo())->updateControllers(timeStep);
00021 }
00022
00023
00024 struct CollisionFilter : public btOverlapFilterCallback {
00025
00026 virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const {
00027 if( (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask)==0 || (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask)==0)
00028 return false;
00029
00030 btRigidBody* rb0 = btRigidBody::upcast(static_cast<btCollisionObject*>(proxy0->m_clientObject));
00031 if(rb0==NULL)
00032 return true;
00033 bool filter = rb0->checkCollideWithOverride(static_cast<btCollisionObject*>(proxy1->m_clientObject));
00034
00035
00036
00037 return filter;
00038 }
00039 };
00040
00041 PhysicsWorld::~PhysicsWorld() {
00042 ASSERT(bodies.size()==0,"PhysicsWorld still has bodies at destruction");
00043 delete dynamicsWorld; dynamicsWorld=NULL;
00044 delete solver; solver=NULL;
00045 delete broadphase; broadphase=NULL;
00046 delete dispatcher; dispatcher=NULL;
00047 delete collisionConfiguration; collisionConfiguration=NULL;
00048
00049 }
00050
00051 void PhysicsWorld::initWorld() {
00052
00053 collisionConfiguration = new btDefaultCollisionConfiguration();
00054 collisionConfiguration->setConvexConvexMultipointIterations(4,4);
00055
00056
00057 dispatcher = new btCollisionDispatcher(collisionConfiguration);
00058
00059
00060 # if BT_BULLET_VERSION >= 280
00061
00062 collisionConfiguration->setPlaneConvexMultipointIterations();
00063 # else
00064
00065 typedef btConvexPlaneCollisionAlgorithm::CreateFunc CF;
00066 CF* cpCF = (CF*)collisionConfiguration->getCollisionAlgorithmCreateFunc(BOX_SHAPE_PROXYTYPE,STATIC_PLANE_PROXYTYPE);
00067 cpCF->m_numPerturbationIterations = 3;
00068 cpCF->m_minimumPointsPerturbationThreshold = 3;
00069 CF* pcCF = (CF*)collisionConfiguration->getCollisionAlgorithmCreateFunc(STATIC_PLANE_PROXYTYPE,BOX_SHAPE_PROXYTYPE);
00070 pcCF->m_numPerturbationIterations = 3;
00071 pcCF->m_minimumPointsPerturbationThreshold = 3;
00072 # endif
00073
00074
00075 dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE, collisionConfiguration->getCollisionAlgorithmCreateFunc(CONVEX_HULL_SHAPE_PROXYTYPE,CONVEX_HULL_SHAPE_PROXYTYPE));
00076
00077
00078
00079
00080
00081
00082
00083
00084 broadphase = new btDbvtBroadphase();
00085
00086
00087 solver = new btSequentialImpulseConstraintSolver;
00088
00089 dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
00090 dynamicsWorld->setInternalTickCallback(ticCallback,this,true);
00091
00092
00093
00094
00095
00096 updateGravity();
00097 updateSolverInfo();
00098 }
00099
00100 void PhysicsWorld::updateGravity() {
00101 dynamicsWorld->setGravity(btVector3(0,0,gravity*1000*spaceScale));
00102 }
00103
00104 void PhysicsWorld::updateSolverInfo() {
00105 dynamicsWorld->getSolverInfo().m_erp=erp;
00106 dynamicsWorld->getSolverInfo().m_numIterations=solverIter;
00107 dynamicsWorld->getSolverInfo().m_splitImpulse=splitImpulse;
00108
00109
00110
00111
00112
00113
00114
00115
00116 }
00117
00118 void PhysicsWorld::updateControllers(float t) {
00119 for(std::set<MotorController*>::const_iterator it=motorControllers.begin(); it!=motorControllers.end(); ++it)
00120 (*it)->updateControllerResponse(t);
00121 }
00122
00123 size_t PhysicsWorld::step(float t) {
00124 return dynamicsWorld->stepSimulation(t, 0, t);
00125 }
00126
00127 size_t PhysicsWorld::step(float t, unsigned int max, float freq) {
00128 return dynamicsWorld->stepSimulation(t, max, freq);
00129 }
00130
00131
00132 PhysicsBody* PhysicsWorld::getBody(const LinkComponent& info) {
00133 std::map<LinkComponent*, PhysicsBody*>::const_iterator it = bodies.find(const_cast<LinkComponent*>(&info));
00134 if(it!=bodies.end())
00135 return it->second;
00136 return NULL;
00137 }
00138
00139 PhysicsWorld::PointConstraint* PhysicsWorld::addPointConstraint(PhysicsBody* body, const fmat::Column<3>& worldPt) {
00140 PointConstraint * cn = new PointConstraint(*body->body,(worldPt*spaceScale).exportTo<btVector3>() - body->centerOffset);
00141 dynamicsWorld->addConstraint(cn, true);
00142 return cn;
00143 }
00144
00145 void PhysicsWorld::removeConstraint(PhysicsWorld::PointConstraint* cn) {
00146 dynamicsWorld->removeConstraint(cn);
00147 }
00148
00149 #endif // HAVE_BULLET
00150
00151
00152
00153
00154