From 971ee74c845e31cec49e428877fbdc6315dda0ed Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Mon, 17 Apr 2006 01:33:10 +0000 Subject: added support for 'Ghost' object and collision sensor (preliminary) --- .../Converter/BL_BlenderDataConversion.cpp | 18 ++- .../gameengine/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 ++- 6 files changed, 175 insertions(+), 22 deletions(-) (limited to 'source') 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; -- cgit v1.2.3