From 971ee74c845e31cec49e428877fbdc6315dda0ed Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Mon, 17 Apr 2006 01:33:10 +0000 Subject: [PATCH] added support for 'Ghost' object and collision sensor (preliminary) --- .../CollisionDispatch/CollisionDispatcher.cpp | 62 ++++--- .../CollisionDispatch/CollisionDispatcher.h | 3 +- .../CollisionDispatch/CollisionObject.cpp | 10 ++ .../CollisionDispatch/CollisionObject.h | 22 ++- .../CcdPhysics/CcdPhysicsController.cpp | 15 +- .../CcdPhysics/CcdPhysicsController.h | 4 +- .../CcdPhysics/CcdPhysicsEnvironment.cpp | 160 +++++++++++++++++- .../CcdPhysics/CcdPhysicsEnvironment.h | 18 +- .../Converter/BL_BlenderDataConversion.cpp | 18 +- .../Ketsji/KX_ConvertPhysicsObjects.cpp | 17 +- .../Physics/Bullet/CcdPhysicsController.cpp | 15 +- .../Physics/Bullet/CcdPhysicsController.h | 4 +- .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 125 ++++++++++++++ .../Physics/Bullet/CcdPhysicsEnvironment.h | 18 +- 14 files changed, 421 insertions(+), 70 deletions(-) diff --git a/extern/bullet/Bullet/CollisionDispatch/CollisionDispatcher.cpp b/extern/bullet/Bullet/CollisionDispatch/CollisionDispatcher.cpp index 7981ef252e4..565045b39a3 100644 --- a/extern/bullet/Bullet/CollisionDispatch/CollisionDispatcher.cpp +++ b/extern/bullet/Bullet/CollisionDispatch/CollisionDispatcher.cpp @@ -113,37 +113,50 @@ void CollisionDispatcher::BuildAndProcessIslands(int numBodies, IslandCallback* for (int i=0;iGetManifoldByIndexInternal(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(manifold->GetBody0()); + CollisionObject* colObj1 = static_cast(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;iGetBody0())) + PersistentManifold* manifold = islandmanifold[i]; + + CollisionObject* colObj0 = static_cast(manifold->GetBody0()); + CollisionObject* colObj1 = static_cast(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) { diff --git a/extern/bullet/Bullet/CollisionDispatch/CollisionDispatcher.h b/extern/bullet/Bullet/CollisionDispatch/CollisionDispatcher.h index ced71a63287..91cacccc52d 100644 --- a/extern/bullet/Bullet/CollisionDispatch/CollisionDispatcher.h +++ b/extern/bullet/Bullet/CollisionDispatch/CollisionDispatcher.h @@ -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;} diff --git a/extern/bullet/Bullet/CollisionDispatch/CollisionObject.cpp b/extern/bullet/Bullet/CollisionDispatch/CollisionObject.cpp index 191bd8e1c71..33c45179104 100644 --- a/extern/bullet/Bullet/CollisionDispatch/CollisionObject.cpp +++ b/extern/bullet/Bullet/CollisionDispatch/CollisionObject.cpp @@ -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) diff --git a/extern/bullet/Bullet/CollisionDispatch/CollisionObject.h b/extern/bullet/Bullet/CollisionDispatch/CollisionObject.h index 9a74954d36f..09b346c0372 100644 --- a/extern/bullet/Bullet/CollisionDispatch/CollisionObject.h +++ b/extern/bullet/Bullet/CollisionDispatch/CollisionObject.h @@ -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) { diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp index 6b892655300..57f29575569 100644 --- a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp @@ -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 diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h index 04d34fb1200..2c5e01dd4b0 100644 --- a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h @@ -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; diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp index 6e5dcfbb91a..7f9bbd62ceb 100644 --- a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp @@ -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;iGetRigidBody(); + + //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::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::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(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;iGetDispatcher()->GetManifoldByIndexInternal(i); + int numContacts = manifold->GetNumContacts(); + if (numContacts) + { + RigidBody* obj0 = static_cast(manifold->GetBody0()); + RigidBody* obj1 = static_cast(manifold->GetBody1()); + + //m_userPointer is set in 'addPhysicsController + CcdPhysicsController* ctrl0 = static_cast(obj0->m_userPointer); + CcdPhysicsController* ctrl1 = static_cast(obj1->m_userPointer); + + std::vector::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 diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h index 116e3d984df..2a4396d8c78 100644 --- a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h @@ -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 m_controllers; - + std::vector m_triggerControllers; + PHY_ResponseCallback m_triggerCallbacks[PHY_NUM_RESPONSE]; + void* m_triggerCallbacksUserPtrs[PHY_NUM_RESPONSE]; + std::vector m_wrapperVehicles; class CollisionWorld* m_collisionWorld; diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index d994fe2a7d1..0399d4e61c1 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -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; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 3e5f71c63d8..f35ba115e2c 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -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); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 6b892655300..57f29575569 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -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 diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 04d34fb1200..2c5e01dd4b0 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -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; diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index ff0880b5c2e..7f9bbd62ceb 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -308,6 +308,10 @@ m_profileTimings(0), m_enableSatCollisionDetection(false) { + for (int i=0;iGetRigidBody(); + + //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::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(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;iGetDispatcher()->GetManifoldByIndexInternal(i); + int numContacts = manifold->GetNumContacts(); + if (numContacts) + { + RigidBody* obj0 = static_cast(manifold->GetBody0()); + RigidBody* obj1 = static_cast(manifold->GetBody1()); + + //m_userPointer is set in 'addPhysicsController + CcdPhysicsController* ctrl0 = static_cast(obj0->m_userPointer); + CcdPhysicsController* ctrl1 = static_cast(obj1->m_userPointer); + + std::vector::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 diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index 116e3d984df..2a4396d8c78 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -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 m_controllers; - + std::vector m_triggerControllers; + PHY_ResponseCallback m_triggerCallbacks[PHY_NUM_RESPONSE]; + void* m_triggerCallbacksUserPtrs[PHY_NUM_RESPONSE]; + std::vector m_wrapperVehicles; class CollisionWorld* m_collisionWorld;