|
Blender
V2.59
|
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 }