Blender V2.61 - r43446

KX_TouchEventManager.cpp

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