Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

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 //! this is apparently not needed due to using the 'true' argument to addConstraint to disable collisions between linked objects...
00024 struct CollisionFilter : public btOverlapFilterCallback {
00025   // return true when pairs need collision
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     /*std::string name0 = static_cast<PhysicsBody*>(rb0->getUserPointer())->getPath();
00035     std::string name1 = static_cast<PhysicsBody*>(static_cast<btCollisionObject*>(proxy1->m_clientObject)->getUserPointer())->getPath();
00036     std::cout << "filter " << name0 << ' ' << name1 << " = " << filter << std::endl;*/
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   //delete filter; filter=NULL;
00049 }
00050 
00051 void PhysicsWorld::initWorld() {
00052   //collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
00053   collisionConfiguration = new btDefaultCollisionConfiguration();
00054   collisionConfiguration->setConvexConvexMultipointIterations(4,4);
00055   
00056   //use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
00057   dispatcher = new btCollisionDispatcher(collisionConfiguration);
00058 
00059   // eliminates jitter of small cubes on the ground plane
00060 #  if BT_BULLET_VERSION >= 280
00061   // this function was introduced in 2.79, but initially broken, wait for 2.80
00062   collisionConfiguration->setPlaneConvexMultipointIterations();
00063 #  else
00064   // do setPlaneConvexMultipointIterations() manually:
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   //make sure to disable the special box-box collision detector, replace it by the generic convex version
00075   dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE, collisionConfiguration->getCollisionAlgorithmCreateFunc(CONVEX_HULL_SHAPE_PROXYTYPE,CONVEX_HULL_SHAPE_PROXYTYPE));
00076 
00077   /*
00078    //the maximum size of the collision world. Make sure objects stay within these boundaries
00079    //Don't make the world AABB size too large, it will harm simulation quality and performance
00080    btVector3 worldAabbMin(-1000,-1000,-1000);
00081    btVector3 worldAabbMax(1000,1000,1000);
00082    int  maxProxies = 1024;
00083    broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);*/
00084   broadphase = new btDbvtBroadphase();
00085   
00086   ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
00087   solver = new btSequentialImpulseConstraintSolver;
00088   
00089   dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
00090   dynamicsWorld->setInternalTickCallback(ticCallback,this,true);
00091   
00092   // this is apparently not needed due to using the 'true' argument to addConstraint to disable collisions between linked objects...
00093   //filter = new CollisionFilter;
00094   //dynamicsWorld->getPairCache()->setOverlapFilterCallback(filter);
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   //dynamicsWorld->getSolverInfo().m_linearSlop=1*spaceScale;
00110   //dynamicsWorld->getSolverInfo().m_damping=50;
00111   //dynamicsWorld->getSolverInfo().m_erp2=0.5f;
00112   //dynamicsWorld->getSolverInfo().m_maxErrorReduction=50;
00113   //dynamicsWorld->getSolverInfo().m_globalCfm=0.01f;
00114   //dynamicsWorld->getSolverInfo().m_friction=.3;
00115   //dynamicsWorld->getSolverInfo().m_restitution=0;
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 /*! @file
00152  * @brief 
00153  * @author Ethan Tira-Thompson (ejt) (Creator)
00154  */

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:46 2016 by Doxygen 1.6.3