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