Hopefully a working merge with trunk (could be one error left in raytrace.c - will...
[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(NULL)
230                 0,
231                 "KX_SceneActuator",
232                 sizeof(PyObjectPlus_Proxy),
233                 0,
234                 py_base_dealloc,
235                 0,
236                 0,
237                 0,
238                 0,
239                 py_base_repr,
240                 0,0,0,0,0,0,
241                 py_base_getattro,
242                 py_base_setattro,
243                 0,0,0,0,0,0,0,0,0,
244                 Methods
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         //Deprecated functions ------>
263         {"setUseRestart", (PyCFunction) KX_SceneActuator::sPySetUseRestart, METH_VARARGS, (PY_METHODCHAR)SetUseRestart_doc},
264         {"setScene",      (PyCFunction) KX_SceneActuator::sPySetScene, METH_VARARGS, (PY_METHODCHAR)SetScene_doc},
265         {"setCamera",     (PyCFunction) KX_SceneActuator::sPySetCamera, METH_VARARGS, (PY_METHODCHAR)SetCamera_doc},
266         {"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_NOARGS, (PY_METHODCHAR)GetUseRestart_doc},
267         {"getScene",      (PyCFunction) KX_SceneActuator::sPyGetScene, METH_NOARGS, (PY_METHODCHAR)GetScene_doc},
268         {"getCamera",     (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_NOARGS, (PY_METHODCHAR)GetCamera_doc},
269         //<----- Deprecated
270         {NULL,NULL} //Sentinel
271 };
272
273 PyAttributeDef KX_SceneActuator::Attributes[] = {
274         KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName),
275         KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera),
276         { NULL }        //Sentinel
277 };
278
279 PyObject* KX_SceneActuator::py_getattro(PyObject *attr)
280 {
281         py_getattro_up(SCA_IActuator);
282 }
283
284 int KX_SceneActuator::py_setattro(PyObject *attr, PyObject *value)
285 {
286         py_setattro_up(SCA_IActuator);
287 }
288
289 PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
290 {
291         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
292         if (!actuator->m_camera)
293                 Py_RETURN_NONE;
294         
295         return actuator->m_camera->GetProxy();
296 }
297
298 int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
299 {
300         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
301         KX_Camera *camOb;
302         
303         if(value==Py_None)
304         {
305                 if (actuator->m_camera)
306                         actuator->m_camera->UnregisterActuator(actuator);
307                 
308                 actuator->m_camera= NULL;
309                 return 0;
310         }
311         
312         if (PyObject_TypeCheck(value, &KX_Camera::Type)) 
313         {
314                 KX_Camera *camOb= static_cast<KX_Camera*>BGE_PROXY_REF(value);
315                 
316                 if(camOb==NULL)
317                 {
318                         PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG);
319                         return 1;
320                 }
321                 
322                 if (actuator->m_camera)
323                         actuator->m_camera->UnregisterActuator(actuator);
324                 
325                 actuator->m_camera = camOb;
326                 actuator->m_camera->RegisterActuator(actuator);
327                 return 0;
328         }
329
330         if (PyString_Check(value))
331         {
332                 char *camName = PyString_AsString(value);
333
334                 camOb = actuator->FindCamera(camName);
335                 if (camOb) 
336                 {
337                         if (actuator->m_camera)
338                                 actuator->m_camera->UnregisterActuator(actuator);
339                         actuator->m_camera = camOb;
340                         actuator->m_camera->RegisterActuator(actuator);
341                         return 0;
342                 }
343                 PyErr_SetString(PyExc_TypeError, "not a valid camera name");
344                 return 1;
345         }
346         PyErr_SetString(PyExc_TypeError, "expected a string or a camera object reference");
347         return 1;
348 }
349
350
351 /* 2. setUseRestart--------------------------------------------------------- */
352 const char KX_SceneActuator::SetUseRestart_doc[] = 
353 "setUseRestart(flag)\n"
354 "\t- flag: 0 or 1.\n"
355 "\tSet flag to 1 to restart the scene.\n" ;
356 PyObject* KX_SceneActuator::PySetUseRestart(PyObject* args)
357 {
358         ShowDeprecationWarning("setUseRestart()", "(no replacement)");
359         int boolArg;
360         
361         if (!PyArg_ParseTuple(args, "i:setUseRestart", &boolArg))
362         {
363                 return NULL;
364         }
365         
366         m_restart = boolArg != 0;
367         
368         Py_RETURN_NONE;
369 }
370
371
372
373 /* 3. getUseRestart:                                                         */
374 const char KX_SceneActuator::GetUseRestart_doc[] = 
375 "getUseRestart()\n"
376 "\tReturn whether the scene will be restarted.\n" ;
377 PyObject* KX_SceneActuator::PyGetUseRestart()
378 {
379         ShowDeprecationWarning("getUseRestart()", "(no replacement)");
380         return PyInt_FromLong(!(m_restart == 0));
381 }
382
383
384
385 /* 4. set scene------------------------------------------------------------- */
386 const char KX_SceneActuator::SetScene_doc[] = 
387 "setScene(scene)\n"
388 "\t- scene: string\n"
389 "\tSet the name of scene the actuator will switch to.\n" ;
390 PyObject* KX_SceneActuator::PySetScene(PyObject* args)
391 {
392         ShowDeprecationWarning("setScene()", "the scene property");
393         /* one argument: a scene, ignore the rest */
394         char *scene_name;
395
396         if(!PyArg_ParseTuple(args, "s:setScene", &scene_name))
397         {
398                 return NULL;
399         }
400
401         /* Scene switch is done by name. */
402         m_nextSceneName = scene_name;
403
404         Py_RETURN_NONE;
405 }
406
407
408
409 /* 5. getScene:                                                              */
410 const char KX_SceneActuator::GetScene_doc[] = 
411 "getScene()\n"
412 "\tReturn the name of the scene the actuator wants to switch to.\n" ;
413 PyObject* KX_SceneActuator::PyGetScene()
414 {
415         ShowDeprecationWarning("getScene()", "the scene property");
416         return PyString_FromString(m_nextSceneName);
417 }
418
419
420
421 /* 6. set camera------------------------------------------------------------ */
422 const char KX_SceneActuator::SetCamera_doc[] = 
423 "setCamera(camera)\n"
424 "\t- camera: string\n"
425 "\tSet the camera to switch to.\n" ;
426 PyObject* KX_SceneActuator::PySetCamera(PyObject* args)
427 {
428         ShowDeprecationWarning("setCamera()", "the camera property");
429         PyObject *cam;
430         if (PyArg_ParseTuple(args, "O!:setCamera", &KX_Camera::Type, &cam))
431         {
432                 KX_Camera *new_camera;
433                 
434                 new_camera = static_cast<KX_Camera*>BGE_PROXY_REF(cam);
435                 if(new_camera==NULL)
436                 {
437                         PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG);
438                         return NULL;
439                 }
440                 
441                 if (m_camera)
442                         m_camera->UnregisterActuator(this);
443                 
444                 m_camera= new_camera;
445                 
446                 m_camera->RegisterActuator(this);
447                 Py_RETURN_NONE;
448         }
449         PyErr_Clear();
450
451         /* one argument: a scene, ignore the rest */
452         char *camName;
453         if(!PyArg_ParseTuple(args, "s:setCamera", &camName))
454         {
455                 return NULL;
456         }
457
458         KX_Camera *camOb = FindCamera(camName);
459         if (camOb) 
460         {
461                 if (m_camera)
462                         m_camera->UnregisterActuator(this);
463                 m_camera = camOb;
464                 m_camera->RegisterActuator(this);
465         }
466
467         Py_RETURN_NONE;
468 }
469
470
471
472 /* 7. getCamera:                                                             */
473 const char KX_SceneActuator::GetCamera_doc[] = 
474 "getCamera()\n"
475 "\tReturn the name of the camera to switch to.\n" ;
476 PyObject* KX_SceneActuator::PyGetCamera()
477 {
478         ShowDeprecationWarning("getCamera()", "the camera property");
479         if (m_camera) {
480                 return PyString_FromString(m_camera->GetName());
481         }
482         else {
483                 Py_RETURN_NONE;
484         }
485 }
486 /* eof */