doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / gameengine / Ketsji / KX_SceneActuator.cpp
1 /*
2 * Set scene/camera stuff
3 *
4 * $Id$
5 *
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30 */
31
32 #include "SCA_IActuator.h"
33 #include "KX_SceneActuator.h"
34 #include <iostream>
35 #include "KX_Scene.h"
36 #include "KX_Camera.h"
37 #include "KX_KetsjiEngine.h"
38
39 /* ------------------------------------------------------------------------- */
40 /* Native functions                                                          */
41 /* ------------------------------------------------------------------------- */
42
43 KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj, 
44                                                                    int mode,
45                                                                    KX_Scene *scene,
46                                                                    KX_KetsjiEngine* ketsjiEngine,
47                                                                    const STR_String& nextSceneName,
48                                                                    KX_Camera* camera)
49                                                                    : SCA_IActuator(gameobj, KX_ACT_SCENE)
50 {
51         m_mode = mode;
52         m_scene  = scene;
53         m_KetsjiEngine=ketsjiEngine;
54         m_camera = camera;
55         m_nextSceneName = nextSceneName;
56         if (m_camera)
57                 m_camera->RegisterActuator(this);
58 } /* End of constructor */
59
60
61
62 KX_SceneActuator::~KX_SceneActuator()
63
64         if (m_camera)
65                 m_camera->UnregisterActuator(this);
66 } /* end of destructor */
67
68
69
70 CValue* KX_SceneActuator::GetReplica()
71 {
72         KX_SceneActuator* replica = new KX_SceneActuator(*this);
73         replica->ProcessReplica();
74         return replica;
75 }
76
77 void KX_SceneActuator::ProcessReplica()
78 {
79         if (m_camera)
80                 m_camera->RegisterActuator(this);
81         SCA_IActuator::ProcessReplica();
82 }
83
84 bool KX_SceneActuator::UnlinkObject(SCA_IObject* clientobj)
85 {
86         if (clientobj == (SCA_IObject*)m_camera)
87         {
88                 // this object is being deleted, we cannot continue to track it.
89                 m_camera = NULL;
90                 return true;
91         }
92         return false;
93 }
94
95 void KX_SceneActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
96 {
97         void **h_obj = (*obj_map)[m_camera];
98         if (h_obj) {
99                 if (m_camera)
100                         m_camera->UnregisterActuator(this);
101                 m_camera = (KX_Camera*)(*h_obj);
102                 m_camera->RegisterActuator(this);
103         }
104 }
105
106
107 bool KX_SceneActuator::Update()
108 {
109         // bool result = false; /*unused*/
110         bool bNegativeEvent = IsNegativeEvent();
111         RemoveAllEvents();
112
113         if (bNegativeEvent)
114                 return false; // do nothing on negative events
115
116         switch (m_mode)
117         {
118         case KX_SCENE_RESTART:
119                 {
120                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_scene->GetName());
121                         break;
122                 }
123         case KX_SCENE_SET_CAMERA:
124                 if (m_camera)
125                 {
126                         m_scene->SetActiveCamera(m_camera);
127                 }
128                 else
129                 {
130                         // if no camera is set and the parent object is a camera, use it as the camera
131                         SCA_IObject* parent = GetParent();
132                         if (parent->GetGameObjectType()==SCA_IObject::OBJ_CAMERA)
133                         {
134                                 m_scene->SetActiveCamera((KX_Camera*)parent);
135                         }
136                 }
137                 break;
138         default:
139                 break;
140         }
141         
142         if (!m_nextSceneName.Length())
143                 return false;
144         
145         switch (m_mode)
146         {
147         case KX_SCENE_SET_SCENE:
148                 {
149                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_nextSceneName);
150                         break;
151                 }
152         case KX_SCENE_ADD_FRONT_SCENE:
153                 {
154                         bool overlay=true;
155                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
156                         break;
157                 }
158         case KX_SCENE_ADD_BACK_SCENE:
159                 {
160                         bool overlay=false;
161                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
162                         break;
163                 }
164         case KX_SCENE_REMOVE_SCENE:
165                 {
166                         m_KetsjiEngine->RemoveScene(m_nextSceneName);
167                         break;
168                 }
169         case KX_SCENE_SUSPEND:
170                 {
171                         m_KetsjiEngine->SuspendScene(m_nextSceneName);
172                         break;
173                 }
174         case KX_SCENE_RESUME:
175                 {
176                         m_KetsjiEngine->ResumeScene(m_nextSceneName);
177                         break;
178                 }
179         default:
180                 ; /* do nothing? this is an internal error !!! */
181         }
182         
183         return false;
184 }
185
186
187
188 /*  returns a camera if the name is valid */
189 KX_Camera* KX_SceneActuator::FindCamera(char *camName)
190 {
191         KX_SceneList* sl = m_KetsjiEngine->CurrentScenes();
192         STR_String name = STR_String(camName);
193         KX_SceneList::iterator it = sl->begin();
194         KX_Camera* cam = NULL;
195
196         while ((it != sl->end()) && (!cam))
197         {
198                 cam = (*it)->FindCamera(name);
199                 it++;
200         }
201
202         return cam;
203 }
204
205
206
207 KX_Scene* KX_SceneActuator::FindScene(char * sceneName)
208 {
209         return m_KetsjiEngine->FindScene(sceneName);
210 }
211
212
213 #ifdef WITH_PYTHON
214
215 /* ------------------------------------------------------------------------- */
216 /* Python functions                                                          */
217 /* ------------------------------------------------------------------------- */
218
219 /* Integration hooks ------------------------------------------------------- */
220 PyTypeObject KX_SceneActuator::Type = {
221         PyVarObject_HEAD_INIT(NULL, 0)
222         "KX_SceneActuator",
223         sizeof(PyObjectPlus_Proxy),
224         0,
225         py_base_dealloc,
226         0,
227         0,
228         0,
229         0,
230         py_base_repr,
231         0,0,0,0,0,0,0,0,0,
232         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
233         0,0,0,0,0,0,0,
234         Methods,
235         0,
236         0,
237         &SCA_IActuator::Type,
238         0,0,0,0,0,0,
239         py_base_new
240 };
241
242 PyMethodDef KX_SceneActuator::Methods[] =
243 {
244         {NULL,NULL} //Sentinel
245 };
246
247 PyAttributeDef KX_SceneActuator::Attributes[] = {
248         KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName),
249         KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera),
250         KX_PYATTRIBUTE_BOOL_RW("useRestart", KX_SceneActuator, m_restart),
251         KX_PYATTRIBUTE_INT_RW("mode", KX_SCENE_NODEF+1, KX_SCENE_MAX-1, true, KX_SceneActuator, m_mode),
252         { NULL }        //Sentinel
253 };
254
255 PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
256 {
257         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
258         if (!actuator->m_camera)
259                 Py_RETURN_NONE;
260         
261         return actuator->m_camera->GetProxy();
262 }
263
264 int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
265 {
266         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
267         KX_Camera *camOb;
268         
269         if (!ConvertPythonToCamera(value, &camOb, true, "actu.camera = value: KX_SceneActuator"))
270                 return PY_SET_ATTR_FAIL;
271         
272         if (actuator->m_camera)
273                 actuator->m_camera->UnregisterActuator(actuator);
274         
275         if(camOb==NULL) {
276                 actuator->m_camera= NULL;
277         }
278         else {  
279                 actuator->m_camera = camOb;
280                 actuator->m_camera->RegisterActuator(actuator);
281         }
282         
283         return PY_SET_ATTR_SUCCESS;
284 }
285
286 #endif // WITH_PYTHON
287
288 /* eof */