doxygen: prevent GPL license block from being parsed as doxygen comment.
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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
37 KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr,
38         PHY_IPhysicsEnvironment* physEnv)
39         : SCA_EventManager(logicmgr, TOUCH_EVENTMGR),
40           m_physEnv(physEnv)
41 {
42         //notm_scene->addTouchCallback(STATIC_RESPONSE, KX_TouchEventManager::collisionResponse, this);
43
44         //m_scene->addTouchCallback(OBJECT_RESPONSE, KX_TouchEventManager::collisionResponse, this);
45         //m_scene->addTouchCallback(SENSOR_RESPONSE, KX_TouchEventManager::collisionResponse, this);
46
47         m_physEnv->addTouchCallback(PHY_OBJECT_RESPONSE, KX_TouchEventManager::newCollisionResponse, this);
48         m_physEnv->addTouchCallback(PHY_SENSOR_RESPONSE, KX_TouchEventManager::newCollisionResponse, this);
49         m_physEnv->addTouchCallback(PHY_BROADPH_RESPONSE, KX_TouchEventManager::newBroadphaseResponse, this);
50
51 }
52
53 bool    KX_TouchEventManager::NewHandleCollision(void* object1, void* object2, const PHY_CollData *coll_data)
54 {
55
56         PHY_IPhysicsController* obj1 = static_cast<PHY_IPhysicsController*>(object1);
57         PHY_IPhysicsController* obj2 = static_cast<PHY_IPhysicsController*>(object2);
58         
59         m_newCollisions.insert(std::pair<PHY_IPhysicsController*, PHY_IPhysicsController*>(obj1, obj2));
60                 
61         return false;
62 }
63
64
65 bool     KX_TouchEventManager::newCollisionResponse(void *client_data, 
66                                                         void *object1,
67                                                         void *object2,
68                                                         const PHY_CollData *coll_data)
69 {
70         KX_TouchEventManager *touchmgr = (KX_TouchEventManager *) client_data;
71         touchmgr->NewHandleCollision(object1, object2, coll_data);
72         return false;
73 }
74
75 bool     KX_TouchEventManager::newBroadphaseResponse(void *client_data, 
76                                                         void *object1,
77                                                         void *object2,
78                                                         const PHY_CollData *coll_data)
79 {
80         PHY_IPhysicsController* ctrl = static_cast<PHY_IPhysicsController*>(object1);
81         KX_ClientObjectInfo* info = (ctrl) ? static_cast<KX_ClientObjectInfo*>(ctrl->getNewClientInfo()) : NULL;
82         // This call back should only be called for controllers of Near and Radar sensor
83         if (!info)
84                 return true;
85
86         switch (info->m_type)
87         {
88         case KX_ClientObjectInfo::SENSOR:
89                 if (info->m_sensors.size() == 1)
90                 {
91                         // only one sensor for this type of object
92                         KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*info->m_sensors.begin());
93                         return touchsensor->BroadPhaseFilterCollision(object1,object2);
94                 }
95                 break;
96         case KX_ClientObjectInfo::OBSENSOR:
97         case KX_ClientObjectInfo::OBACTORSENSOR:
98                 // this object may have multiple collision sensors, 
99                 // check is any of them is interested in this object
100                 for(std::list<SCA_ISensor*>::iterator it = info->m_sensors.begin();
101                         it != info->m_sensors.end();
102                         ++it)
103                 {
104                         if ((*it)->GetSensorType() == SCA_ISensor::ST_TOUCH) 
105                         {
106                                 KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*it);
107                                 if (touchsensor->BroadPhaseSensorFilterCollision(object1, object2))
108                                         return true;
109                         }
110                 }
111                 return false;
112
113         // quiet the compiler
114         case KX_ClientObjectInfo::STATIC:
115         case KX_ClientObjectInfo::ACTOR:
116         case KX_ClientObjectInfo::RESERVED1:
117                 /* do nothing*/
118                 break;
119         }
120         return true;
121 }
122
123 void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
124 {
125         KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
126         if (m_sensors.AddBack(touchsensor))
127                 // the sensor was effectively inserted, register it
128                 touchsensor->RegisterSumo(this);
129 }
130
131 void KX_TouchEventManager::RemoveSensor(SCA_ISensor* sensor)
132 {
133         KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
134         if (touchsensor->Delink())
135                 // the sensor was effectively removed, unregister it
136                 touchsensor->UnregisterSumo(this);
137 }
138
139
140
141 void KX_TouchEventManager::EndFrame()
142 {
143         SG_DList::iterator<KX_TouchSensor> it(m_sensors);
144         for (it.begin();!it.end();++it)
145         {
146                 (*it)->EndFrame();
147         }
148 }
149
150
151
152 void KX_TouchEventManager::NextFrame()
153 {
154         if (!m_sensors.Empty())
155         {
156                 SG_DList::iterator<KX_TouchSensor> it(m_sensors);
157                 for (it.begin();!it.end();++it)
158                         (*it)->SynchronizeTransform();
159                 
160                 for (std::set<NewCollision>::iterator cit = m_newCollisions.begin(); cit != m_newCollisions.end(); ++cit)
161                 {
162                         PHY_IPhysicsController* ctrl1 = (*cit).first;
163 //                      PHY_IPhysicsController* ctrl2 = (*cit).second;
164 //                      KX_GameObject* gameOb1 = ctrl1->getClientInfo();
165 //                      KX_GameObject* gameOb1 = ctrl1->getClientInfo();
166
167                         KX_ClientObjectInfo *client_info = static_cast<KX_ClientObjectInfo *>(ctrl1->getNewClientInfo());
168                         list<SCA_ISensor*>::iterator sit;
169                         if (client_info) {
170                                 for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) {
171                                         static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).first, (*cit).second, NULL);
172                                 }
173                         }
174                         client_info = static_cast<KX_ClientObjectInfo *>((*cit).second->getNewClientInfo());
175                         if (client_info) {
176                                 for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) {
177                                         static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).second, (*cit).first, NULL);
178                                 }
179                         }
180                 }
181                         
182                 m_newCollisions.clear();
183                         
184                 for (it.begin();!it.end();++it)
185                         (*it)->Activate(m_logicmgr);
186         }
187 }