From 63656781098e1443cd3f89fa435688727076eb33 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 14 Sep 2013 02:02:58 +0000 Subject: BGE: Adding a Python collision API. The initial patch was provided by agoose77, with some edits by me. KX_GameObject now has a collisionCallbacks list which is a list of callables that are called when a collision occurs. The callables will be called with an argument that contains a reference to the other object involved in the collision (i.e., not self). --- source/gameengine/Ketsji/KX_TouchEventManager.cpp | 65 ++++++++++++++++------- 1 file changed, 45 insertions(+), 20 deletions(-) (limited to 'source/gameengine/Ketsji/KX_TouchEventManager.cpp') diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp index 96872f4e6fd..fcb09ebfec6 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp +++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp @@ -81,28 +81,42 @@ bool KX_TouchEventManager::newBroadphaseResponse(void *client_data, void *object2, const PHY_CollData *coll_data) { - PHY_IPhysicsController* ctrl = static_cast(object1); - KX_ClientObjectInfo *info = (ctrl) ? static_cast(ctrl->getNewClientInfo()) : NULL; + PHY_IPhysicsController* ctrl1 = static_cast(object1); + PHY_IPhysicsController* ctrl2 = static_cast(object2); + + KX_ClientObjectInfo *info1 = (ctrl1) ? static_cast(ctrl1->getNewClientInfo()) : NULL; + KX_ClientObjectInfo *info2 = (ctrl1) ? static_cast(ctrl2->getNewClientInfo()) : NULL; + // This call back should only be called for controllers of Near and Radar sensor - if (!info) + if (!info1) return true; - switch (info->m_type) + // Get KX_GameObjects for callbacks + KX_GameObject* gobj1 = info1->m_gameobject; + KX_GameObject* gobj2 = (info2) ? info1->m_gameobject : NULL; + + bool has_py_callbacks = false; + + // Consider callbacks for broadphase inclusion if it's a sensor object type + if (gobj1 && gobj2) + has_py_callbacks = gobj1->m_collisionCallbacks || gobj2->m_collisionCallbacks; + + switch (info1->m_type) { case KX_ClientObjectInfo::SENSOR: - if (info->m_sensors.size() == 1) + if (info1->m_sensors.size() == 1) { // only one sensor for this type of object - KX_TouchSensor* touchsensor = static_cast(*info->m_sensors.begin()); - return touchsensor->BroadPhaseFilterCollision(object1,object2); + KX_TouchSensor* touchsensor = static_cast(*info1->m_sensors.begin()); + return touchsensor->BroadPhaseFilterCollision(object1, object2); } break; case KX_ClientObjectInfo::OBSENSOR: case KX_ClientObjectInfo::OBACTORSENSOR: // this object may have multiple collision sensors, // check is any of them is interested in this object - for (std::list::iterator it = info->m_sensors.begin(); - it != info->m_sensors.end(); + for (std::list::iterator it = info1->m_sensors.begin(); + it != info1->m_sensors.end(); ++it) { if ((*it)->GetSensorType() == SCA_ISensor::ST_TOUCH) @@ -112,7 +126,8 @@ bool KX_TouchEventManager::newBroadphaseResponse(void *client_data, return true; } } - return false; + + return has_py_callbacks; // quiet the compiler case KX_ClientObjectInfo::STATIC: @@ -155,32 +170,43 @@ void KX_TouchEventManager::EndFrame() void KX_TouchEventManager::NextFrame() { - if (!m_sensors.Empty()) - { SG_DList::iterator it(m_sensors); for (it.begin();!it.end();++it) (*it)->SynchronizeTransform(); for (std::set::iterator cit = m_newCollisions.begin(); cit != m_newCollisions.end(); ++cit) { + // Controllers PHY_IPhysicsController* ctrl1 = (*cit).first; -// PHY_IPhysicsController* ctrl2 = (*cit).second; -// KX_GameObject* gameOb1 = ctrl1->getClientInfo(); -// KX_GameObject* gameOb1 = ctrl1->getClientInfo(); + PHY_IPhysicsController* ctrl2 = (*cit).second; - KX_ClientObjectInfo *client_info = static_cast(ctrl1->getNewClientInfo()); + // Sensor iterator list::iterator sit; + + // First client info + KX_ClientObjectInfo *client_info = static_cast(ctrl1->getNewClientInfo()); + // First gameobject + KX_GameObject *kxObj1 = KX_GameObject::GetClientObject(client_info); + // Invoke sensor response for each object if (client_info) { for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) { - static_cast(*sit)->NewHandleCollision((*cit).first, (*cit).second, NULL); + static_cast(*sit)->NewHandleCollision(ctrl1, ctrl2, NULL); } } - client_info = static_cast((*cit).second->getNewClientInfo()); + + // Second client info + client_info = static_cast(ctrl2->getNewClientInfo()); + // Second gameobject + KX_GameObject *kxObj2 = KX_GameObject::GetClientObject(client_info); if (client_info) { for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) { - static_cast(*sit)->NewHandleCollision((*cit).second, (*cit).first, NULL); + static_cast(*sit)->NewHandleCollision(ctrl2, ctrl1, NULL); } } + // Run python callbacks + kxObj1->RunCollisionCallbacks(kxObj2); + kxObj2->RunCollisionCallbacks(kxObj1); + } m_newCollisions.clear(); @@ -188,4 +214,3 @@ void KX_TouchEventManager::NextFrame() for (it.begin();!it.end();++it) (*it)->Activate(m_logicmgr); } -} -- cgit v1.2.3