Blender  V2.59
KX_TouchEventManager.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: KX_TouchEventManager.cpp 35171 2011-02-25 13:35:59Z jesterking $
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Contributor(s): none yet.
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include "KX_TouchEventManager.h"
00035 #include "SCA_ISensor.h"
00036 #include "KX_TouchSensor.h"
00037 #include "KX_GameObject.h"
00038 #include "PHY_IPhysicsEnvironment.h"
00039 #include "PHY_IPhysicsController.h"
00040 
00041 
00042 KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr,
00043         PHY_IPhysicsEnvironment* physEnv)
00044         : SCA_EventManager(logicmgr, TOUCH_EVENTMGR),
00045           m_physEnv(physEnv)
00046 {
00047         //notm_scene->addTouchCallback(STATIC_RESPONSE, KX_TouchEventManager::collisionResponse, this);
00048 
00049         //m_scene->addTouchCallback(OBJECT_RESPONSE, KX_TouchEventManager::collisionResponse, this);
00050         //m_scene->addTouchCallback(SENSOR_RESPONSE, KX_TouchEventManager::collisionResponse, this);
00051 
00052         m_physEnv->addTouchCallback(PHY_OBJECT_RESPONSE, KX_TouchEventManager::newCollisionResponse, this);
00053         m_physEnv->addTouchCallback(PHY_SENSOR_RESPONSE, KX_TouchEventManager::newCollisionResponse, this);
00054         m_physEnv->addTouchCallback(PHY_BROADPH_RESPONSE, KX_TouchEventManager::newBroadphaseResponse, this);
00055 
00056 }
00057 
00058 bool    KX_TouchEventManager::NewHandleCollision(void* object1, void* object2, const PHY_CollData *coll_data)
00059 {
00060 
00061         PHY_IPhysicsController* obj1 = static_cast<PHY_IPhysicsController*>(object1);
00062         PHY_IPhysicsController* obj2 = static_cast<PHY_IPhysicsController*>(object2);
00063         
00064         m_newCollisions.insert(std::pair<PHY_IPhysicsController*, PHY_IPhysicsController*>(obj1, obj2));
00065                 
00066         return false;
00067 }
00068 
00069 
00070 bool     KX_TouchEventManager::newCollisionResponse(void *client_data, 
00071                                                         void *object1,
00072                                                         void *object2,
00073                                                         const PHY_CollData *coll_data)
00074 {
00075         KX_TouchEventManager *touchmgr = (KX_TouchEventManager *) client_data;
00076         touchmgr->NewHandleCollision(object1, object2, coll_data);
00077         return false;
00078 }
00079 
00080 bool     KX_TouchEventManager::newBroadphaseResponse(void *client_data, 
00081                                                         void *object1,
00082                                                         void *object2,
00083                                                         const PHY_CollData *coll_data)
00084 {
00085         PHY_IPhysicsController* ctrl = static_cast<PHY_IPhysicsController*>(object1);
00086         KX_ClientObjectInfo* info = (ctrl) ? static_cast<KX_ClientObjectInfo*>(ctrl->getNewClientInfo()) : NULL;
00087         // This call back should only be called for controllers of Near and Radar sensor
00088         if (!info)
00089                 return true;
00090 
00091         switch (info->m_type)
00092         {
00093         case KX_ClientObjectInfo::SENSOR:
00094                 if (info->m_sensors.size() == 1)
00095                 {
00096                         // only one sensor for this type of object
00097                         KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*info->m_sensors.begin());
00098                         return touchsensor->BroadPhaseFilterCollision(object1,object2);
00099                 }
00100                 break;
00101         case KX_ClientObjectInfo::OBSENSOR:
00102         case KX_ClientObjectInfo::OBACTORSENSOR:
00103                 // this object may have multiple collision sensors, 
00104                 // check is any of them is interested in this object
00105                 for(std::list<SCA_ISensor*>::iterator it = info->m_sensors.begin();
00106                         it != info->m_sensors.end();
00107                         ++it)
00108                 {
00109                         if ((*it)->GetSensorType() == SCA_ISensor::ST_TOUCH) 
00110                         {
00111                                 KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*it);
00112                                 if (touchsensor->BroadPhaseSensorFilterCollision(object1, object2))
00113                                         return true;
00114                         }
00115                 }
00116                 return false;
00117 
00118         // quiet the compiler
00119         case KX_ClientObjectInfo::STATIC:
00120         case KX_ClientObjectInfo::ACTOR:
00121         case KX_ClientObjectInfo::RESERVED1:
00122                 /* do nothing*/
00123                 break;
00124         }
00125         return true;
00126 }
00127 
00128 void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
00129 {
00130         KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
00131         if (m_sensors.AddBack(touchsensor))
00132                 // the sensor was effectively inserted, register it
00133                 touchsensor->RegisterSumo(this);
00134 }
00135 
00136 void KX_TouchEventManager::RemoveSensor(SCA_ISensor* sensor)
00137 {
00138         KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
00139         if (touchsensor->Delink())
00140                 // the sensor was effectively removed, unregister it
00141                 touchsensor->UnregisterSumo(this);
00142 }
00143 
00144 
00145 
00146 void KX_TouchEventManager::EndFrame()
00147 {
00148         SG_DList::iterator<KX_TouchSensor> it(m_sensors);
00149         for (it.begin();!it.end();++it)
00150         {
00151                 (*it)->EndFrame();
00152         }
00153 }
00154 
00155 
00156 
00157 void KX_TouchEventManager::NextFrame()
00158 {
00159         if (!m_sensors.Empty())
00160         {
00161                 SG_DList::iterator<KX_TouchSensor> it(m_sensors);
00162                 for (it.begin();!it.end();++it)
00163                         (*it)->SynchronizeTransform();
00164                 
00165                 for (std::set<NewCollision>::iterator cit = m_newCollisions.begin(); cit != m_newCollisions.end(); ++cit)
00166                 {
00167                         PHY_IPhysicsController* ctrl1 = (*cit).first;
00168 //                      PHY_IPhysicsController* ctrl2 = (*cit).second;
00169 //                      KX_GameObject* gameOb1 = ctrl1->getClientInfo();
00170 //                      KX_GameObject* gameOb1 = ctrl1->getClientInfo();
00171 
00172                         KX_ClientObjectInfo *client_info = static_cast<KX_ClientObjectInfo *>(ctrl1->getNewClientInfo());
00173                         list<SCA_ISensor*>::iterator sit;
00174                         if (client_info) {
00175                                 for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) {
00176                                         static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).first, (*cit).second, NULL);
00177                                 }
00178                         }
00179                         client_info = static_cast<KX_ClientObjectInfo *>((*cit).second->getNewClientInfo());
00180                         if (client_info) {
00181                                 for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) {
00182                                         static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).second, (*cit).first, NULL);
00183                                 }
00184                         }
00185                 }
00186                         
00187                 m_newCollisions.clear();
00188                         
00189                 for (it.begin();!it.end();++it)
00190                         (*it)->Activate(m_logicmgr);
00191         }
00192 }