svn merge -r 15392:15551 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / gameengine / Ketsji / KX_TouchEventManager.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include "KX_TouchEventManager.h"
30 #include "SCA_ISensor.h"
31 #include "KX_TouchSensor.h"
32 #include "KX_GameObject.h"
33 #include "PHY_IPhysicsEnvironment.h"
34 #include "PHY_IPhysicsController.h"
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40
41 KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr,
42         PHY_IPhysicsEnvironment* physEnv)
43         : SCA_EventManager(TOUCH_EVENTMGR),
44           m_logicmgr(logicmgr),
45           m_physEnv(physEnv)
46 {
47         //notm_scene->addTouchCallback(STATIC_RESPONSE, KX_TouchEventManager::collisionResponse, this);
48
49         //m_scene->addTouchCallback(OBJECT_RESPONSE, KX_TouchEventManager::collisionResponse, this);
50         //m_scene->addTouchCallback(SENSOR_RESPONSE, KX_TouchEventManager::collisionResponse, this);
51
52         m_physEnv->addTouchCallback(PHY_OBJECT_RESPONSE, KX_TouchEventManager::newCollisionResponse, this);
53         m_physEnv->addTouchCallback(PHY_SENSOR_RESPONSE, KX_TouchEventManager::newCollisionResponse, this);
54         m_physEnv->addTouchCallback(PHY_BROADPH_RESPONSE, KX_TouchEventManager::newBroadphaseResponse, this);
55
56 }
57
58 bool    KX_TouchEventManager::NewHandleCollision(void* object1, void* object2, const PHY_CollData *coll_data)
59 {
60
61         PHY_IPhysicsController* obj1 = static_cast<PHY_IPhysicsController*>(object1);
62         PHY_IPhysicsController* obj2 = static_cast<PHY_IPhysicsController*>(object2);
63         
64         m_newCollisions.insert(std::pair<PHY_IPhysicsController*, PHY_IPhysicsController*>(obj1, obj2));
65                 
66         return false;
67 }
68
69
70 bool     KX_TouchEventManager::newCollisionResponse(void *client_data, 
71                                                         void *object1,
72                                                         void *object2,
73                                                         const PHY_CollData *coll_data)
74 {
75         KX_TouchEventManager *touchmgr = (KX_TouchEventManager *) client_data;
76         touchmgr->NewHandleCollision(object1, object2, coll_data);
77         return false;
78 }
79
80 bool     KX_TouchEventManager::newBroadphaseResponse(void *client_data, 
81                                                         void *object1,
82                                                         void *object2,
83                                                         const PHY_CollData *coll_data)
84 {
85         PHY_IPhysicsController* ctrl = static_cast<PHY_IPhysicsController*>(object1);
86         KX_ClientObjectInfo* info = (ctrl) ? static_cast<KX_ClientObjectInfo*>(ctrl->getNewClientInfo()) : NULL;
87         // This call back should only be called for controllers of Near and Radar sensor
88         if (info &&
89         info->m_sensors.size() == 1 &&
90                 (info->m_type == KX_ClientObjectInfo::NEAR ||
91                  info->m_type == KX_ClientObjectInfo::RADAR))
92         {
93                 // only one sensor for this type of object
94                 KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*info->m_sensors.begin());
95                 return touchsensor->BroadPhaseFilterCollision(object1,object2);
96         }
97         return true;
98 }
99
100 void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
101 {
102         KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
103         m_sensors.push_back(touchsensor);
104
105         touchsensor->RegisterSumo(this);
106 }
107
108
109
110 void KX_TouchEventManager::EndFrame()
111 {
112         vector<SCA_ISensor*>::iterator it;
113         for ( it = m_sensors.begin();
114         !(it==m_sensors.end());it++)
115         {
116                 ((KX_TouchSensor*)*it)->EndFrame();
117
118         }
119 }
120
121
122
123 void KX_TouchEventManager::NextFrame()
124 {
125         if (m_sensors.size() > 0)
126         {
127                 vector<SCA_ISensor*>::iterator it;
128                 
129                 for (it = m_sensors.begin();!(it==m_sensors.end());++it)
130                         static_cast<KX_TouchSensor*>(*it)->SynchronizeTransform();
131                 
132                 for (std::set<NewCollision>::iterator cit = m_newCollisions.begin(); cit != m_newCollisions.end(); ++cit)
133                 {
134                         PHY_IPhysicsController* ctrl1 = (*cit).first;
135 //                      PHY_IPhysicsController* ctrl2 = (*cit).second;
136 //                      KX_GameObject* gameOb1 = ctrl1->getClientInfo();
137 //                      KX_GameObject* gameOb1 = ctrl1->getClientInfo();
138
139                         KX_ClientObjectInfo *client_info = static_cast<KX_ClientObjectInfo *>(ctrl1->getNewClientInfo());
140                         list<SCA_ISensor*>::iterator sit;
141                         if (client_info) {
142                                 for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) {
143                                         static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).first, (*cit).second, NULL);
144                                 }
145                         }
146                         client_info = static_cast<KX_ClientObjectInfo *>((*cit).second->getNewClientInfo());
147                         if (client_info) {
148                                 for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) {
149                                         static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).second, (*cit).first, NULL);
150                                 }
151                         }
152                 }
153                         
154                 m_newCollisions.clear();
155                         
156                 for (it = m_sensors.begin();!(it==m_sensors.end());++it)
157                         (*it)->Activate(m_logicmgr,NULL);
158         }
159 }
160
161
162
163 void KX_TouchEventManager::RemoveSensor(class SCA_ISensor* sensor)
164 {
165         std::vector<SCA_ISensor*>::iterator i =
166         std::find(m_sensors.begin(), m_sensors.end(), sensor);
167         if (!(i == m_sensors.end()))
168         {
169                 std::swap(*i, m_sensors.back());
170                 m_sensors.pop_back();
171         }
172         
173         // remove the sensor forever :)
174         SCA_EventManager::RemoveSensor(sensor);
175 }
176