added support for 'Ghost' object and collision sensor (preliminary)

This commit is contained in:
Erwin Coumans 2006-04-17 01:33:10 +00:00
parent 176641b273
commit 971ee74c84
14 changed files with 421 additions and 70 deletions

@ -113,37 +113,50 @@ void CollisionDispatcher::BuildAndProcessIslands(int numBodies, IslandCallback*
for (int i=0;i<GetNumManifolds();i++)
{
PersistentManifold* manifold = this->GetManifoldByIndexInternal(i);
if ((((CollisionObject*)manifold->GetBody0()) && ((CollisionObject*)manifold->GetBody0())->m_islandTag1 == (islandId)) ||
(((CollisionObject*)manifold->GetBody1()) && ((CollisionObject*)manifold->GetBody1())->m_islandTag1 == (islandId)))
{
//filtering for response
if ((((CollisionObject*)manifold->GetBody0()) && ((CollisionObject*)manifold->GetBody0())->GetActivationState()== ACTIVE_TAG) ||
(((CollisionObject*)manifold->GetBody1()) && ((CollisionObject*)manifold->GetBody1())->GetActivationState() == ACTIVE_TAG))
{
allSleeping = false;
}
if ((((CollisionObject*)manifold->GetBody0()) && ((CollisionObject*)manifold->GetBody0())->GetActivationState()== DISABLE_DEACTIVATION) ||
(((CollisionObject*)manifold->GetBody1()) && ((CollisionObject*)manifold->GetBody1())->GetActivationState() == DISABLE_DEACTIVATION))
{
allSleeping = false;
}
CollisionObject* colObj0 = static_cast<CollisionObject*>(manifold->GetBody0());
CollisionObject* colObj1 = static_cast<CollisionObject*>(manifold->GetBody1());
islandmanifold.push_back(manifold);
}
if (NeedsResponse(*colObj0,*colObj1))
{
if (((colObj0) && (colObj0)->m_islandTag1 == (islandId)) ||
((colObj1) && (colObj1)->m_islandTag1 == (islandId)))
{
if (((colObj0) && (colObj0)->GetActivationState()== ACTIVE_TAG) ||
((colObj1) && (colObj1)->GetActivationState() == ACTIVE_TAG))
{
allSleeping = false;
}
if (((colObj0) && (colObj0)->GetActivationState()== DISABLE_DEACTIVATION) ||
((colObj1) && (colObj1)->GetActivationState() == DISABLE_DEACTIVATION))
{
allSleeping = false;
}
islandmanifold.push_back(manifold);
}
}
}
if (allSleeping)
{
//tag all as 'ISLAND_SLEEPING'
for (size_t i=0;i<islandmanifold.size();i++)
{
PersistentManifold* manifold = islandmanifold[i];
if (((CollisionObject*)manifold->GetBody0()))
PersistentManifold* manifold = islandmanifold[i];
CollisionObject* colObj0 = static_cast<CollisionObject*>(manifold->GetBody0());
CollisionObject* colObj1 = static_cast<CollisionObject*>(manifold->GetBody1());
if ((colObj0))
{
((CollisionObject*)manifold->GetBody0())->SetActivationState( ISLAND_SLEEPING );
(colObj0)->SetActivationState( ISLAND_SLEEPING );
}
if (((CollisionObject*)manifold->GetBody1()))
if ((colObj1))
{
((CollisionObject*)manifold->GetBody1())->SetActivationState( ISLAND_SLEEPING);
(colObj1)->SetActivationState( ISLAND_SLEEPING);
}
}
@ -211,6 +224,15 @@ CollisionAlgorithm* CollisionDispatcher::InternalFindAlgorithm(BroadphaseProxy&
}
bool CollisionDispatcher::NeedsResponse(CollisionObject& colObj0,CollisionObject& colObj1)
{
//here you can do filtering
bool hasResponse =
(!(colObj0.m_collisionFlags & CollisionObject::noContactResponse)) &
(!(colObj1.m_collisionFlags & CollisionObject::noContactResponse));
return hasResponse;
}
bool CollisionDispatcher::NeedsCollision(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
{

@ -123,7 +123,8 @@ public:
CollisionAlgorithm* InternalFindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1);
virtual bool NeedsCollision(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1);
virtual bool NeedsResponse(CollisionObject& colObj0,CollisionObject& colObj1);
virtual int GetUniqueId() { return RIGIDBODY_DISPATCHER;}

@ -15,6 +15,16 @@ subject to the following restrictions:
#include "CollisionObject.h"
CollisionObject::CollisionObject()
: m_collisionFlags(0),
m_activationState1(1),
m_deactivationTime(0.f),
m_broadphaseHandle(0),
m_collisionShape(0),
m_hitFraction(1.f)
{
}
void CollisionObject::SetActivationState(int newState)

@ -37,6 +37,8 @@ struct CollisionObject
enum CollisionFlags
{
isStatic = 1,
noContactResponse = 2,
};
int m_collisionFlags;
@ -55,17 +57,19 @@ struct CollisionObject
bool mergesSimulationIslands() const;
CollisionObject()
: m_collisionFlags(0),
m_activationState1(1),
m_deactivationTime(0.f),
m_broadphaseHandle(0),
m_collisionShape(0),
m_hitFraction(1.f)
{
inline bool IsStatic() {
return m_collisionFlags & isStatic;
}
inline bool HasContactResponse() {
return !(m_collisionFlags & noContactResponse);
}
CollisionObject();
void SetCollisionShape(CollisionShape* collisionShape)
{

@ -73,6 +73,9 @@ void CcdPhysicsController::CreateRigidbody()
//
m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
//setMassProps this also sets collisionFlags
m_body->m_collisionFlags = m_cci.m_collisionFlags;
m_body->setGravity( m_cci.m_gravity);
m_body->setDamping(m_cci.m_linearDamping, m_cci.m_angularDamping);
m_body->setCenterOfMassTransform( trans );
@ -93,9 +96,9 @@ CcdPhysicsController::~CcdPhysicsController()
*/
bool CcdPhysicsController::SynchronizeMotionStates(float time)
{
//don't sync non-dynamic...
//sync non-static to motionstate, and static from motionstate (todo: add kinematic etc.)
if (m_body->getInvMass() != 0.f)
if (!m_body->IsStatic())
{
const SimdVector3& worldPos = m_body->getCenterOfMassPosition();
m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]);
@ -383,6 +386,14 @@ void CcdPhysicsController::getReactionForce(float& forceX,float& forceY,float&
// dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted
void CcdPhysicsController::setRigidBody(bool rigid)
{
if (!rigid)
{
//fake it for now
SimdVector3 inertia = m_body->getInvInertiaDiagLocal();
inertia[1] = 0.f;
m_body->setInvInertiaDiagLocal(inertia);
m_body->updateInertiaTensor();
}
}
// clientinfo for raycasts for example

@ -34,7 +34,8 @@ struct CcdConstructionInfo
m_MotionState(0),
m_physicsEnv(0),
m_inertiaFactor(1.f),
m_scaling(1.f,1.f,1.f)
m_scaling(1.f,1.f,1.f),
m_collisionFlags(0)
{
}
@ -46,6 +47,7 @@ struct CcdConstructionInfo
SimdScalar m_friction;
SimdScalar m_linearDamping;
SimdScalar m_angularDamping;
int m_collisionFlags;
CollisionShape* m_collisionShape;
class PHY_IMotionState* m_MotionState;

@ -17,8 +17,10 @@
#include "ConstraintSolver/OdeConstraintSolver.h"
#include "ConstraintSolver/SimpleConstraintSolver.h"
#ifdef USE_PROFILE
//profiling/timings
#include "quickprof.h"
#endif //USE_PROFILE
#include "IDebugDraw.h"
@ -306,6 +308,10 @@ m_profileTimings(0),
m_enableSatCollisionDetection(false)
{
for (int i=0;i<PHY_NUM_RESPONSE;i++)
{
m_triggerCallbacks[i] = 0;
}
if (!dispatcher)
dispatcher = new CollisionDispatcher();
@ -336,6 +342,9 @@ m_enableSatCollisionDetection(false)
void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
{
RigidBody* body = ctrl->GetRigidBody();
//this m_userPointer is just used for triggers, see CallbackTriggers
body->m_userPointer = ctrl;
body->setGravity( m_gravity );
m_controllers.push_back(ctrl);
@ -446,6 +455,19 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
m_controllers.pop_back();
}
}
//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();
}
}
}
@ -454,9 +476,11 @@ void CcdPhysicsEnvironment::beginFrame()
}
bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
{
#ifdef USE_PROFILE
//toggle Profiler
if ( m_debugDrawer->GetDebugMode() & IDebugDraw::DBG_ProfileTimings)
{
@ -469,6 +493,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
char filename[128];
sprintf(filename,"quickprof_bullet_timings%i.csv",counter++);
Profiler::init(filename, Profiler::BLOCK_CYCLE_SECONDS);//BLOCK_TOTAL_MICROSECONDS
}
} else
{
@ -478,6 +503,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
Profiler::destroy();
}
}
#endif //USE_PROFILE
@ -516,7 +542,9 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
}
#ifdef USE_PROFILE
Profiler::beginBlock("SyncMotionStates");
#endif //USE_PROFILE
//this is needed because scaling is not known in advance, and scaling has to propagate to the shape
@ -526,9 +554,11 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
m_scalingPropagated = true;
}
#ifdef USE_PROFILE
Profiler::endBlock("SyncMotionStates");
Profiler::beginBlock("predictIntegratedTransform");
#endif //USE_PROFILE
{
// std::vector<CcdPhysicsController*>::iterator i;
@ -551,7 +581,9 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
}
}
#ifdef USE_PROFILE
Profiler::endBlock("predictIntegratedTransform");
#endif //USE_PROFILE
BroadphaseInterface* scene = GetBroadphase();
@ -561,8 +593,9 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
//
#ifdef USE_PROFILE
Profiler::beginBlock("DispatchAllCollisionPairs");
#endif //USE_PROFILE
int numsubstep = m_numIterations;
@ -576,7 +609,9 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
scene->DispatchAllCollisionPairs(*GetDispatcher(),dispatchInfo);///numsubstep,g);
#ifdef USE_PROFILE
Profiler::endBlock("DispatchAllCollisionPairs");
#endif //USE_PROFILE
int numRigidBodies = m_controllers.size();
@ -586,8 +621,9 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
//contacts
#ifdef USE_PROFILE
Profiler::beginBlock("SolveConstraint");
#endif //USE_PROFILE
//solve the regular constraints (point 2 point, hinge, etc)
@ -597,9 +633,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
//
// constraint solving
//
Profiler::beginBlock("Solve1Constraint");
int i;
int numConstraints = m_constraints.size();
@ -613,13 +647,13 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
constraint->SolveConstraint( timeStep );
}
Profiler::beginBlock("Solve1Constraint");
}
#ifdef USE_PROFILE
Profiler::endBlock("SolveConstraint");
#endif //USE_PROFILE
//solve the vehicles
@ -671,18 +705,28 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
m_solver,
m_debugDrawer);
#ifdef USE_PROFILE
Profiler::beginBlock("BuildAndProcessIslands");
#endif //USE_PROFILE
/// solve all the contact points and contact friction
GetDispatcher()->BuildAndProcessIslands(numRigidBodies,&solverCallback);
#ifdef USE_PROFILE
Profiler::endBlock("BuildAndProcessIslands");
Profiler::beginBlock("CallbackTriggers");
#endif //USE_PROFILE
CallbackTriggers();
#ifdef USE_PROFILE
Profiler::endBlock("CallbackTriggers");
Profiler::beginBlock("proceedToTransform");
#endif //USE_PROFILE
{
@ -855,17 +899,20 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
}
#ifdef USE_PROFILE
Profiler::endBlock("proceedToTransform");
Profiler::beginBlock("SyncMotionStates");
#endif //USE_PROFILE
SyncMotionStates(timeStep);
#ifdef USE_PROFILE
Profiler::endBlock("SyncMotionStates");
Profiler::endProfilingCycle();
#endif //USE_PROFILE
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//sync wheels for vehicles
@ -1413,6 +1460,101 @@ TypedConstraint* CcdPhysicsEnvironment::getConstraintById(int constraintId)
}
void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
{
printf("addSensor\n");
}
void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl)
{
printf("removeSensor\n");
}
void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
{
printf("addTouchCallback\n(response class = %i)\n",response_class);
//map PHY_ convention into SM_ convention
switch (response_class)
{
case PHY_FH_RESPONSE:
printf("PHY_FH_RESPONSE\n");
break;
case PHY_SENSOR_RESPONSE:
printf("PHY_SENSOR_RESPONSE\n");
break;
case PHY_CAMERA_RESPONSE:
printf("PHY_CAMERA_RESPONSE\n");
break;
case PHY_OBJECT_RESPONSE:
printf("PHY_OBJECT_RESPONSE\n");
break;
case PHY_STATIC_RESPONSE:
printf("PHY_STATIC_RESPONSE\n");
break;
default:
assert(0);
return;
}
m_triggerCallbacks[response_class] = callback;
m_triggerCallbacksUserPtrs[response_class] = user;
}
void CcdPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl)
{
CcdPhysicsController* ccdCtrl = static_cast<CcdPhysicsController*>(ctrl);
printf("requestCollisionCallback\n");
m_triggerControllers.push_back(ccdCtrl);
}
void CcdPhysicsEnvironment::CallbackTriggers()
{
CcdPhysicsController* ctrl0=0,*ctrl1=0;
if (m_triggerCallbacks[PHY_OBJECT_RESPONSE])
{
int numManifolds = m_collisionWorld->GetDispatcher()->GetNumManifolds();
for (int i=0;i<numManifolds;i++)
{
PersistentManifold* manifold = m_collisionWorld->GetDispatcher()->GetManifoldByIndexInternal(i);
int numContacts = manifold->GetNumContacts();
if (numContacts)
{
RigidBody* obj0 = static_cast<RigidBody* >(manifold->GetBody0());
RigidBody* obj1 = static_cast<RigidBody* >(manifold->GetBody1());
//m_userPointer is set in 'addPhysicsController
CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->m_userPointer);
CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->m_userPointer);
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl0);
if (i == m_triggerControllers.end())
{
i = std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl1);
}
if (!(i == m_triggerControllers.end()))
{
m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE],
ctrl0,ctrl1,0);
}
}
}
}
//walk over all overlapping pairs, and if
}
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//complex constraint for vehicles

@ -90,6 +90,10 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
float axisX,float axisY,float axisZ);
virtual void removeConstraint(int constraintid);
virtual void CallbackTriggers();
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//complex constraint for vehicles
virtual PHY_IVehicle* getVehicleConstraint(int constraintId);
@ -107,11 +111,10 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
//Methods for gamelogic collision/physics callbacks
//todo:
virtual void addSensor(PHY_IPhysicsController* ctrl) {};
virtual void removeSensor(PHY_IPhysicsController* ctrl){};
virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user){};
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl){};
virtual void addSensor(PHY_IPhysicsController* ctrl);
virtual void removeSensor(PHY_IPhysicsController* ctrl);
virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user);
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl);
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;};
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight){ return 0;};
@ -160,9 +163,12 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
void SyncMotionStates(float timeStep);
std::vector<CcdPhysicsController*> m_controllers;
std::vector<CcdPhysicsController*> m_triggerControllers;
PHY_ResponseCallback m_triggerCallbacks[PHY_NUM_RESPONSE];
void* m_triggerCallbacksUserPtrs[PHY_NUM_RESPONSE];
std::vector<WrapperVehicle*> m_wrapperVehicles;
class CollisionWorld* m_collisionWorld;

@ -1004,15 +1004,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
return meshobj;
}
static PHY_MaterialProps g_materialProps = {
1.0, // restitution
2.0, // friction
0.0, // fh spring constant
0.0, // fh damping
0.0, // fh distance
false // sliding material?
};
static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject,
@ -1036,7 +1027,14 @@ static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blender
materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0;
}
else {
*materialProps = g_materialProps;
//give some defaults
materialProps->m_restitution = 0.f;
materialProps->m_friction = 0.5;
materialProps->m_fh_spring = 0.f;
materialProps->m_fh_damping = 0.f;
materialProps->m_fh_distance = 0.f;
materialProps->m_fh_normal = false;
}
return materialProps;

@ -896,12 +896,22 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
CcdConstructionInfo ci;
class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
if (objprop->m_ghost)
{
ci.m_collisionFlags |= CollisionObject::noContactResponse;
}
if (!objprop->m_dyna)
{
ci.m_collisionFlags |= CollisionObject::isStatic;
}
ci.m_MotionState = motionstate;
ci.m_gravity = SimdVector3(0,0,0);
ci.m_localInertiaTensor =SimdVector3(0,0,0);
ci.m_mass = objprop->m_dyna ? shapeprops->m_mass : 0.f;
isbulletdyna = objprop->m_dyna;
ci.m_localInertiaTensor = SimdVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
SimdTransform trans;
@ -1079,8 +1089,9 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
bool isActor = objprop->m_isactor;
gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC);
// store materialname in auxinfo, needed for touchsensors
//gameobj->getClientInfo()->m_auxilary_info = 0;//(matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
//gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
const STR_String& matname=meshobj->GetMaterialName(0);
gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
gameobj->GetSGNode()->AddSGController(physicscontroller);

@ -73,6 +73,9 @@ void CcdPhysicsController::CreateRigidbody()
//
m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
//setMassProps this also sets collisionFlags
m_body->m_collisionFlags = m_cci.m_collisionFlags;
m_body->setGravity( m_cci.m_gravity);
m_body->setDamping(m_cci.m_linearDamping, m_cci.m_angularDamping);
m_body->setCenterOfMassTransform( trans );
@ -93,9 +96,9 @@ CcdPhysicsController::~CcdPhysicsController()
*/
bool CcdPhysicsController::SynchronizeMotionStates(float time)
{
//don't sync non-dynamic...
//sync non-static to motionstate, and static from motionstate (todo: add kinematic etc.)
if (m_body->getInvMass() != 0.f)
if (!m_body->IsStatic())
{
const SimdVector3& worldPos = m_body->getCenterOfMassPosition();
m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]);
@ -383,6 +386,14 @@ void CcdPhysicsController::getReactionForce(float& forceX,float& forceY,float&
// dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted
void CcdPhysicsController::setRigidBody(bool rigid)
{
if (!rigid)
{
//fake it for now
SimdVector3 inertia = m_body->getInvInertiaDiagLocal();
inertia[1] = 0.f;
m_body->setInvInertiaDiagLocal(inertia);
m_body->updateInertiaTensor();
}
}
// clientinfo for raycasts for example

@ -34,7 +34,8 @@ struct CcdConstructionInfo
m_MotionState(0),
m_physicsEnv(0),
m_inertiaFactor(1.f),
m_scaling(1.f,1.f,1.f)
m_scaling(1.f,1.f,1.f),
m_collisionFlags(0)
{
}
@ -46,6 +47,7 @@ struct CcdConstructionInfo
SimdScalar m_friction;
SimdScalar m_linearDamping;
SimdScalar m_angularDamping;
int m_collisionFlags;
CollisionShape* m_collisionShape;
class PHY_IMotionState* m_MotionState;

@ -308,6 +308,10 @@ m_profileTimings(0),
m_enableSatCollisionDetection(false)
{
for (int i=0;i<PHY_NUM_RESPONSE;i++)
{
m_triggerCallbacks[i] = 0;
}
if (!dispatcher)
dispatcher = new CollisionDispatcher();
@ -338,6 +342,9 @@ m_enableSatCollisionDetection(false)
void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
{
RigidBody* body = ctrl->GetRigidBody();
//this m_userPointer is just used for triggers, see CallbackTriggers
body->m_userPointer = ctrl;
body->setGravity( m_gravity );
m_controllers.push_back(ctrl);
@ -448,6 +455,19 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
m_controllers.pop_back();
}
}
//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();
}
}
}
@ -694,6 +714,16 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
#ifdef USE_PROFILE
Profiler::endBlock("BuildAndProcessIslands");
Profiler::beginBlock("CallbackTriggers");
#endif //USE_PROFILE
CallbackTriggers();
#ifdef USE_PROFILE
Profiler::endBlock("CallbackTriggers");
Profiler::beginBlock("proceedToTransform");
#endif //USE_PROFILE
@ -1430,6 +1460,101 @@ TypedConstraint* CcdPhysicsEnvironment::getConstraintById(int constraintId)
}
void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
{
printf("addSensor\n");
}
void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl)
{
printf("removeSensor\n");
}
void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
{
printf("addTouchCallback\n(response class = %i)\n",response_class);
//map PHY_ convention into SM_ convention
switch (response_class)
{
case PHY_FH_RESPONSE:
printf("PHY_FH_RESPONSE\n");
break;
case PHY_SENSOR_RESPONSE:
printf("PHY_SENSOR_RESPONSE\n");
break;
case PHY_CAMERA_RESPONSE:
printf("PHY_CAMERA_RESPONSE\n");
break;
case PHY_OBJECT_RESPONSE:
printf("PHY_OBJECT_RESPONSE\n");
break;
case PHY_STATIC_RESPONSE:
printf("PHY_STATIC_RESPONSE\n");
break;
default:
assert(0);
return;
}
m_triggerCallbacks[response_class] = callback;
m_triggerCallbacksUserPtrs[response_class] = user;
}
void CcdPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl)
{
CcdPhysicsController* ccdCtrl = static_cast<CcdPhysicsController*>(ctrl);
printf("requestCollisionCallback\n");
m_triggerControllers.push_back(ccdCtrl);
}
void CcdPhysicsEnvironment::CallbackTriggers()
{
CcdPhysicsController* ctrl0=0,*ctrl1=0;
if (m_triggerCallbacks[PHY_OBJECT_RESPONSE])
{
int numManifolds = m_collisionWorld->GetDispatcher()->GetNumManifolds();
for (int i=0;i<numManifolds;i++)
{
PersistentManifold* manifold = m_collisionWorld->GetDispatcher()->GetManifoldByIndexInternal(i);
int numContacts = manifold->GetNumContacts();
if (numContacts)
{
RigidBody* obj0 = static_cast<RigidBody* >(manifold->GetBody0());
RigidBody* obj1 = static_cast<RigidBody* >(manifold->GetBody1());
//m_userPointer is set in 'addPhysicsController
CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->m_userPointer);
CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->m_userPointer);
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl0);
if (i == m_triggerControllers.end())
{
i = std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl1);
}
if (!(i == m_triggerControllers.end()))
{
m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE],
ctrl0,ctrl1,0);
}
}
}
}
//walk over all overlapping pairs, and if
}
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//complex constraint for vehicles

@ -90,6 +90,10 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
float axisX,float axisY,float axisZ);
virtual void removeConstraint(int constraintid);
virtual void CallbackTriggers();
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//complex constraint for vehicles
virtual PHY_IVehicle* getVehicleConstraint(int constraintId);
@ -107,11 +111,10 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
//Methods for gamelogic collision/physics callbacks
//todo:
virtual void addSensor(PHY_IPhysicsController* ctrl) {};
virtual void removeSensor(PHY_IPhysicsController* ctrl){};
virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user){};
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl){};
virtual void addSensor(PHY_IPhysicsController* ctrl);
virtual void removeSensor(PHY_IPhysicsController* ctrl);
virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user);
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl);
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;};
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight){ return 0;};
@ -160,9 +163,12 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
void SyncMotionStates(float timeStep);
std::vector<CcdPhysicsController*> m_controllers;
std::vector<CcdPhysicsController*> m_triggerControllers;
PHY_ResponseCallback m_triggerCallbacks[PHY_NUM_RESPONSE];
void* m_triggerCallbacksUserPtrs[PHY_NUM_RESPONSE];
std::vector<WrapperVehicle*> m_wrapperVehicles;
class CollisionWorld* m_collisionWorld;