merging trunk 19093:19274
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 /* ------------------------------------------------------------------------- */
44 /* Native functions                                                          */
45 /* ------------------------------------------------------------------------- */
46
47 KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj, 
48                                                                    int mode,
49                                                                    KX_Scene *scene,
50                                                                    KX_KetsjiEngine* ketsjiEngine,
51                                                                    const STR_String& nextSceneName,
52                                                                    KX_Camera* camera,
53                                                                    PyTypeObject* T)
54                                                                    : SCA_IActuator(gameobj, T)
55 {
56         m_mode = mode;
57         m_scene  = scene;
58         m_KetsjiEngine=ketsjiEngine;
59         m_camera = camera;
60         m_nextSceneName = nextSceneName;
61         if (m_camera)
62                 m_camera->RegisterActuator(this);
63 } /* End of constructor */
64
65
66
67 KX_SceneActuator::~KX_SceneActuator()
68
69         if (m_camera)
70                 m_camera->UnregisterActuator(this);
71 } /* end of destructor */
72
73
74
75 CValue* KX_SceneActuator::GetReplica()
76 {
77         KX_SceneActuator* replica = new KX_SceneActuator(*this);
78         replica->ProcessReplica();
79         // this will copy properties and so on...
80         CValue::AddDataToReplica(replica);
81         
82         return replica;
83 }
84
85 void KX_SceneActuator::ProcessReplica()
86 {
87         if (m_camera)
88                 m_camera->RegisterActuator(this);
89         SCA_IActuator::ProcessReplica();
90 }
91
92 bool KX_SceneActuator::UnlinkObject(SCA_IObject* clientobj)
93 {
94         if (clientobj == (SCA_IObject*)m_camera)
95         {
96                 // this object is being deleted, we cannot continue to track it.
97                 m_camera = NULL;
98                 return true;
99         }
100         return false;
101 }
102
103 void KX_SceneActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
104 {
105         void **h_obj = (*obj_map)[m_camera];
106         if (h_obj) {
107                 if (m_camera)
108                         m_camera->UnregisterActuator(this);
109                 m_camera = (KX_Camera*)(*h_obj);
110                 m_camera->RegisterActuator(this);
111         }
112 }
113
114
115 bool KX_SceneActuator::Update()
116 {
117         // bool result = false; /*unused*/
118         bool bNegativeEvent = IsNegativeEvent();
119         RemoveAllEvents();
120
121         if (bNegativeEvent)
122                 return false; // do nothing on negative events
123
124         switch (m_mode)
125         {
126         case KX_SCENE_RESTART:
127                 {
128                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_scene->GetName());
129                         break;
130                 }
131         case KX_SCENE_SET_CAMERA:
132                 if (m_camera)
133                 {
134                         m_scene->SetActiveCamera(m_camera);
135                 }
136                 else
137                 {
138                         // if no camera is set and the parent object is a camera, use it as the camera
139                         SCA_IObject* parent = GetParent();
140                         if (parent->isA(&KX_Camera::Type))
141                         {
142                                 m_scene->SetActiveCamera((KX_Camera*)parent);
143                         }
144                 }
145                 break;
146         default:
147                 break;
148         }
149         
150         if (!m_nextSceneName.Length())
151                 return false;
152         
153         switch (m_mode)
154         {
155         case KX_SCENE_SET_SCENE:
156                 {
157                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_nextSceneName);
158                         break;
159                 }
160         case KX_SCENE_ADD_FRONT_SCENE:
161                 {
162                         bool overlay=true;
163                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
164                         break;
165                 }
166         case KX_SCENE_ADD_BACK_SCENE:
167                 {
168                         bool overlay=false;
169                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
170                         break;
171                 }
172         case KX_SCENE_REMOVE_SCENE:
173                 {
174                         m_KetsjiEngine->RemoveScene(m_nextSceneName);
175                         break;
176                 }
177         case KX_SCENE_SUSPEND:
178                 {
179                         m_KetsjiEngine->SuspendScene(m_nextSceneName);
180                         break;
181                 }
182         case KX_SCENE_RESUME:
183                 {
184                         m_KetsjiEngine->ResumeScene(m_nextSceneName);
185                         break;
186                 }
187         default:
188                 ; /* do nothing? this is an internal error !!! */
189         }
190         
191         return false;
192 }
193
194
195
196 /*  returns a camera if the name is valid */
197 KX_Camera* KX_SceneActuator::FindCamera(char *camName)
198 {
199         KX_SceneList* sl = m_KetsjiEngine->CurrentScenes();
200         STR_String name = STR_String(camName);
201         KX_SceneList::iterator it = sl->begin();
202         KX_Camera* cam = NULL;
203
204         while ((it != sl->end()) && (!cam))
205         {
206                 cam = (*it)->FindCamera(name);
207                 it++;
208         }
209
210         return cam;
211 }
212
213
214
215 KX_Scene* KX_SceneActuator::FindScene(char * sceneName)
216 {
217         return m_KetsjiEngine->FindScene(sceneName);
218 }
219
220
221
222
223 /* ------------------------------------------------------------------------- */
224 /* Python functions                                                          */
225 /* ------------------------------------------------------------------------- */
226
227 /* Integration hooks ------------------------------------------------------- */
228 PyTypeObject KX_SceneActuator::Type = {
229         PyObject_HEAD_INIT(&PyType_Type)
230                 0,
231                 "KX_SceneActuator",
232                 sizeof(KX_SceneActuator),
233                 0,
234                 PyDestructor,
235                 0,
236                 __getattr,
237                 __setattr,
238                 0, //&MyPyCompare,
239                 __repr,
240                 0, //&cvalue_as_number,
241                 0,
242                 0,
243                 0,
244                 0
245 };
246
247
248
249 PyParentObject KX_SceneActuator::Parents[] =
250 {
251         &KX_SceneActuator::Type,
252                 &SCA_IActuator::Type,
253                 &SCA_ILogicBrick::Type,
254                 &CValue::Type,
255                 NULL
256 };
257
258
259
260 PyMethodDef KX_SceneActuator::Methods[] =
261 {
262         {"setUseRestart", (PyCFunction) KX_SceneActuator::sPySetUseRestart, METH_VARARGS, (PY_METHODCHAR)SetUseRestart_doc},
263         {"setScene",      (PyCFunction) KX_SceneActuator::sPySetScene, METH_VARARGS, (PY_METHODCHAR)SetScene_doc},
264         {"setCamera",     (PyCFunction) KX_SceneActuator::sPySetCamera, METH_VARARGS, (PY_METHODCHAR)SetCamera_doc},
265         {"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_VARARGS, (PY_METHODCHAR)GetUseRestart_doc},
266         {"getScene",      (PyCFunction) KX_SceneActuator::sPyGetScene, METH_VARARGS, (PY_METHODCHAR)GetScene_doc},
267         {"getCamera",     (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_VARARGS, (PY_METHODCHAR)GetCamera_doc},
268         {NULL,NULL} //Sentinel
269 };
270
271 PyAttributeDef KX_SceneActuator::Attributes[] = {
272         { NULL }        //Sentinel
273 };
274
275 PyObject* KX_SceneActuator::_getattr(const char *attr)
276 {
277         _getattr_up(SCA_IActuator);
278 }
279
280
281
282 /* 2. setUseRestart--------------------------------------------------------- */
283 const char KX_SceneActuator::SetUseRestart_doc[] = 
284 "setUseRestart(flag)\n"
285 "\t- flag: 0 or 1.\n"
286 "\tSet flag to 1 to restart the scene.\n" ;
287 PyObject* KX_SceneActuator::PySetUseRestart(PyObject* self, 
288                                                                                         PyObject* args, 
289                                                                                         PyObject* kwds)
290 {
291         int boolArg;
292         
293         if (!PyArg_ParseTuple(args, "i", &boolArg))
294         {
295                 return NULL;
296         }
297         
298         m_restart = boolArg != 0;
299         
300         Py_RETURN_NONE;
301 }
302
303
304
305 /* 3. getUseRestart:                                                         */
306 const char KX_SceneActuator::GetUseRestart_doc[] = 
307 "getUseRestart()\n"
308 "\tReturn whether the scene will be restarted.\n" ;
309 PyObject* KX_SceneActuator::PyGetUseRestart(PyObject* self, 
310                                                                                         PyObject* args, 
311                                                                                         PyObject* kwds)
312 {
313         return PyInt_FromLong(!(m_restart == 0));
314 }
315
316
317
318 /* 4. set scene------------------------------------------------------------- */
319 const char KX_SceneActuator::SetScene_doc[] = 
320 "setScene(scene)\n"
321 "\t- scene: string\n"
322 "\tSet the name of scene the actuator will switch to.\n" ;
323 PyObject* KX_SceneActuator::PySetScene(PyObject* self, 
324                                                                            PyObject* args, 
325                                                                            PyObject* kwds)
326 {
327         /* one argument: a scene, ignore the rest */
328         char *scene_name;
329
330         if(!PyArg_ParseTuple(args, "s", &scene_name))
331         {
332                 return NULL;
333         }
334
335         /* Scene switch is done by name. */
336         m_nextSceneName = scene_name;
337
338         Py_RETURN_NONE;
339 }
340
341
342
343 /* 5. getScene:                                                              */
344 const char KX_SceneActuator::GetScene_doc[] = 
345 "getScene()\n"
346 "\tReturn the name of the scene the actuator wants to switch to.\n" ;
347 PyObject* KX_SceneActuator::PyGetScene(PyObject* self, 
348                                                                            PyObject* args, 
349                                                                            PyObject* kwds)
350 {
351         return PyString_FromString(m_nextSceneName);
352 }
353
354
355
356 /* 6. set camera------------------------------------------------------------ */
357 const char KX_SceneActuator::SetCamera_doc[] = 
358 "setCamera(camera)\n"
359 "\t- camera: string\n"
360 "\tSet the camera to switch to.\n" ;
361 PyObject* KX_SceneActuator::PySetCamera(PyObject* self, 
362                                                                                 PyObject* args, 
363                                                                                 PyObject* kwds)
364 {
365         PyObject *cam;
366         if (PyArg_ParseTuple(args, "O!", &KX_Camera::Type, &cam))
367         {
368                 if (m_camera)
369                         m_camera->UnregisterActuator(this);
370                 m_camera = (KX_Camera*) cam;
371                 if (m_camera)
372                         m_camera->RegisterActuator(this);
373                 Py_RETURN_NONE;
374         }
375         PyErr_Clear();
376
377         /* one argument: a scene, ignore the rest */
378         char *camName;
379         if(!PyArg_ParseTuple(args, "s", &camName))
380         {
381                 return NULL;
382         }
383
384         KX_Camera *camOb = FindCamera(camName);
385         if (camOb) 
386         {
387                 if (m_camera)
388                         m_camera->UnregisterActuator(this);
389                 m_camera = camOb;
390                 m_camera->RegisterActuator(this);
391         }
392
393         Py_RETURN_NONE;
394 }
395
396
397
398 /* 7. getCamera:                                                             */
399 const char KX_SceneActuator::GetCamera_doc[] = 
400 "getCamera()\n"
401 "\tReturn the name of the camera to switch to.\n" ;
402 PyObject* KX_SceneActuator::PyGetCamera(PyObject* self, 
403                                                                                 PyObject* args, 
404                                                                                 PyObject* kwds)
405 {
406         return PyString_FromString(m_camera->GetName());
407 }
408 /* eof */