Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp')
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp129
1 files changed, 54 insertions, 75 deletions
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index b773f40650b..dfbcf115fd7 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -368,7 +368,7 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
body->setUserPointer(ctrl);
body->setGravity( m_gravity );
- m_controllers.push_back(ctrl);
+ m_controllers.insert(ctrl);
//use explicit group/filter for finer control over collision in bullet => near/radar sensor
m_dynamicsWorld->addRigidBody(body, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
@@ -434,36 +434,16 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl)
{
-
//also remove constraint
-
-
m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody());
+ m_controllers.erase(ctrl);
-
- {
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_controllers.begin(), m_controllers.end(), ctrl);
- if (!(i == m_controllers.end()))
- {
- std::swap(*i, m_controllers.back());
- m_controllers.pop_back();
- }
- }
+ if (ctrl->m_registerCount != 0)
+ printf("Warning: removing controller with non-zero m_registerCount: %d\n", ctrl->m_registerCount);
//remove it from the triggers
- {
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
- if (!(i == m_triggerControllers.end()))
- {
- std::swap(*i, m_triggerControllers.back());
- m_triggerControllers.pop_back();
- }
- }
-
-
+ m_triggerControllers.erase(ctrl);
}
void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
@@ -487,16 +467,22 @@ void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctr
void CcdPhysicsEnvironment::enableCcdPhysicsController(CcdPhysicsController* ctrl)
{
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_controllers.begin(), m_controllers.end(), ctrl);
- if (i == m_controllers.end())
+ if (m_controllers.insert(ctrl).second)
{
btRigidBody* body = ctrl->GetRigidBody();
+ body->setUserPointer(ctrl);
m_dynamicsWorld->addCollisionObject(body,
ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
}
}
+void CcdPhysicsEnvironment::disableCcdPhysicsController(CcdPhysicsController* ctrl)
+{
+ if (m_controllers.erase(ctrl))
+ {
+ m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody());
+ }
+}
void CcdPhysicsEnvironment::beginFrame()
@@ -507,12 +493,12 @@ void CcdPhysicsEnvironment::beginFrame()
bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
{
+ std::set<CcdPhysicsController*>::iterator it;
+ int i;
- int i,numCtrl = GetNumControllers();
- for (i=0;i<numCtrl;i++)
+ for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
{
- CcdPhysicsController* ctrl = GetPhysicsController(i);
- ctrl->SynchronizeMotionStates(timeStep);
+ (*it)->SynchronizeMotionStates(timeStep);
}
float subStep = timeStep / float(m_numTimeSubSteps);
@@ -521,11 +507,9 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
m_dynamicsWorld->stepSimulation(subStep,0);//perform always a full simulation step
}
- numCtrl = GetNumControllers();
- for (i=0;i<numCtrl;i++)
+ for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
{
- CcdPhysicsController* ctrl = GetPhysicsController(i);
- ctrl->SynchronizeMotionStates(timeStep);
+ (*it)->SynchronizeMotionStates(timeStep);
}
for (i=0;i<m_wrapperVehicles.size();i++)
@@ -852,20 +836,6 @@ CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
}
-int CcdPhysicsEnvironment::GetNumControllers()
-{
- return m_controllers.size();
-}
-
-
-CcdPhysicsController* CcdPhysicsEnvironment::GetPhysicsController( int index)
-{
- return m_controllers[index];
-}
-
-
-
-
void CcdPhysicsEnvironment::setConstraintParam(int constraintId,int param,float value0,float value1)
{
btTypedConstraint* typedConstraint = getConstraintById(constraintId);
@@ -905,12 +875,14 @@ void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
{
CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl;
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_controllers.begin(), m_controllers.end(), ctrl);
- if ((i == m_controllers.end()))
- {
- addCcdPhysicsController(ctrl1);
- }
+ // addSensor() is a "light" function for bullet because it is used
+ // dynamically when the sensor is activated. Use enableCcdPhysicsController() instead
+ //if (m_controllers.insert(ctrl1).second)
+ //{
+ // addCcdPhysicsController(ctrl1);
+ //}
+ enableCcdPhysicsController(ctrl1);
+
//Collision filter/mask is now set at the time of the creation of the controller
//force collision detection with everything, including static objects (might hurt performance!)
//ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterMask = btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::SensorTrigger;
@@ -923,21 +895,19 @@ void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
void CcdPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl)
{
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
- if (!(i == m_triggerControllers.end()))
- {
- std::swap(*i, m_triggerControllers.back());
- m_triggerControllers.pop_back();
- }
+ CcdPhysicsController* ccdCtrl = (CcdPhysicsController*)ctrl;
+ if (ccdCtrl->Unregister())
+ m_triggerControllers.erase(ccdCtrl);
}
void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl)
{
removeCollisionCallback(ctrl);
- //printf("removeSensor\n");
+
+ disableCcdPhysicsController((CcdPhysicsController*)ctrl);
}
+
void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
{
/* printf("addTouchCallback\n(response class = %i)\n",response_class);
@@ -974,11 +944,10 @@ void CcdPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctr
{
CcdPhysicsController* ccdCtrl = static_cast<CcdPhysicsController*>(ctrl);
- //printf("requestCollisionCallback\n");
- m_triggerControllers.push_back(ccdCtrl);
+ if (ccdCtrl->Register())
+ m_triggerControllers.insert(ccdCtrl);
}
-
void CcdPhysicsEnvironment::CallbackTriggers()
{
@@ -987,13 +956,16 @@ void CcdPhysicsEnvironment::CallbackTriggers()
if (m_triggerCallbacks[PHY_OBJECT_RESPONSE] || (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)))
{
//walk over all overlapping pairs, and if one of the involved bodies is registered for trigger callback, perform callback
- int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();
+ btDispatcher* dispatcher = m_dynamicsWorld->getDispatcher();
+ int numManifolds = dispatcher->getNumManifolds();
for (int i=0;i<numManifolds;i++)
{
- btPersistentManifold* manifold = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
+ btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
int numContacts = manifold->getNumContacts();
if (numContacts)
{
+ btRigidBody* rb0 = static_cast<btRigidBody*>(manifold->getBody0());
+ btRigidBody* rb1 = static_cast<btRigidBody*>(manifold->getBody1());
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints))
{
for (int j=0;j<numContacts;j++)
@@ -1004,18 +976,17 @@ void CcdPhysicsEnvironment::CallbackTriggers()
m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
}
}
- btRigidBody* obj0 = static_cast<btRigidBody* >(manifold->getBody0());
- btRigidBody* obj1 = static_cast<btRigidBody* >(manifold->getBody1());
+ btRigidBody* obj0 = rb0;
+ btRigidBody* obj1 = rb1;
//m_internalOwner is set in 'addPhysicsController'
CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->getUserPointer());
CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->getUserPointer());
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl0);
+ std::set<CcdPhysicsController*>::const_iterator i = m_triggerControllers.find(ctrl0);
if (i == m_triggerControllers.end())
{
- i = std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl1);
+ i = m_triggerControllers.find(ctrl1);
}
if (!(i == m_triggerControllers.end()))
@@ -1023,6 +994,15 @@ void CcdPhysicsEnvironment::CallbackTriggers()
m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE],
ctrl0,ctrl1,0);
}
+ // Bullet does not refresh the manifold contact point for object without contact response
+ // may need to remove this when a newer Bullet version is integrated
+ if (!dispatcher->needsResponse(rb0, rb1))
+ {
+ // Refresh algorithm fails sometimes when there is penetration
+ // (usuall the case with ghost and sensor objects)
+ // Let's just clear the manifold, in any case, it is recomputed on each frame.
+ manifold->clearManifold(); //refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform());
+ }
}
}
@@ -1125,7 +1105,6 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radi
CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);
-
return sphereController;
}