Merge with -r 22620:23107.
[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                                                                    : SCA_IActuator(gameobj)
54 {
55         m_mode = mode;
56         m_scene  = scene;
57         m_KetsjiEngine=ketsjiEngine;
58         m_camera = camera;
59         m_nextSceneName = nextSceneName;
60         if (m_camera)
61                 m_camera->RegisterActuator(this);
62 } /* End of constructor */
63
64
65
66 KX_SceneActuator::~KX_SceneActuator()
67
68         if (m_camera)
69                 m_camera->UnregisterActuator(this);
70 } /* end of destructor */
71
72
73
74 CValue* KX_SceneActuator::GetReplica()
75 {
76         KX_SceneActuator* replica = new KX_SceneActuator(*this);
77         replica->ProcessReplica();
78         return replica;
79 }
80
81 void KX_SceneActuator::ProcessReplica()
82 {
83         if (m_camera)
84                 m_camera->RegisterActuator(this);
85         SCA_IActuator::ProcessReplica();
86 }
87
88 bool KX_SceneActuator::UnlinkObject(SCA_IObject* clientobj)
89 {
90         if (clientobj == (SCA_IObject*)m_camera)
91         {
92                 // this object is being deleted, we cannot continue to track it.
93                 m_camera = NULL;
94                 return true;
95         }
96         return false;
97 }
98
99 void KX_SceneActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
100 {
101         void **h_obj = (*obj_map)[m_camera];
102         if (h_obj) {
103                 if (m_camera)
104                         m_camera->UnregisterActuator(this);
105                 m_camera = (KX_Camera*)(*h_obj);
106                 m_camera->RegisterActuator(this);
107         }
108 }
109
110
111 bool KX_SceneActuator::Update()
112 {
113         // bool result = false; /*unused*/
114         bool bNegativeEvent = IsNegativeEvent();
115         RemoveAllEvents();
116
117         if (bNegativeEvent)
118                 return false; // do nothing on negative events
119
120         switch (m_mode)
121         {
122         case KX_SCENE_RESTART:
123                 {
124                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_scene->GetName());
125                         break;
126                 }
127         case KX_SCENE_SET_CAMERA:
128                 if (m_camera)
129                 {
130                         m_scene->SetActiveCamera(m_camera);
131                 }
132                 else
133                 {
134                         // if no camera is set and the parent object is a camera, use it as the camera
135                         SCA_IObject* parent = GetParent();
136                         if (parent->GetGameObjectType()==SCA_IObject::OBJ_CAMERA)
137                         {
138                                 m_scene->SetActiveCamera((KX_Camera*)parent);
139                         }
140                 }
141                 break;
142         default:
143                 break;
144         }
145         
146         if (!m_nextSceneName.Length())
147                 return false;
148         
149         switch (m_mode)
150         {
151         case KX_SCENE_SET_SCENE:
152                 {
153                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_nextSceneName);
154                         break;
155                 }
156         case KX_SCENE_ADD_FRONT_SCENE:
157                 {
158                         bool overlay=true;
159                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
160                         break;
161                 }
162         case KX_SCENE_ADD_BACK_SCENE:
163                 {
164                         bool overlay=false;
165                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
166                         break;
167                 }
168         case KX_SCENE_REMOVE_SCENE:
169                 {
170                         m_KetsjiEngine->RemoveScene(m_nextSceneName);
171                         break;
172                 }
173         case KX_SCENE_SUSPEND:
174                 {
175                         m_KetsjiEngine->SuspendScene(m_nextSceneName);
176                         break;
177                 }
178         case KX_SCENE_RESUME:
179                 {
180                         m_KetsjiEngine->ResumeScene(m_nextSceneName);
181                         break;
182                 }
183         default:
184                 ; /* do nothing? this is an internal error !!! */
185         }
186         
187         return false;
188 }
189
190
191
192 /*  returns a camera if the name is valid */
193 KX_Camera* KX_SceneActuator::FindCamera(char *camName)
194 {
195         KX_SceneList* sl = m_KetsjiEngine->CurrentScenes();
196         STR_String name = STR_String(camName);
197         KX_SceneList::iterator it = sl->begin();
198         KX_Camera* cam = NULL;
199
200         while ((it != sl->end()) && (!cam))
201         {
202                 cam = (*it)->FindCamera(name);
203                 it++;
204         }
205
206         return cam;
207 }
208
209
210
211 KX_Scene* KX_SceneActuator::FindScene(char * sceneName)
212 {
213         return m_KetsjiEngine->FindScene(sceneName);
214 }
215
216
217
218
219 /* ------------------------------------------------------------------------- */
220 /* Python functions                                                          */
221 /* ------------------------------------------------------------------------- */
222
223 /* Integration hooks ------------------------------------------------------- */
224 PyTypeObject KX_SceneActuator::Type = {
225         PyVarObject_HEAD_INIT(NULL, 0)
226         "KX_SceneActuator",
227         sizeof(PyObjectPlus_Proxy),
228         0,
229         py_base_dealloc,
230         0,
231         0,
232         0,
233         0,
234         py_base_repr,
235         0,0,0,0,0,0,0,0,0,
236         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
237         0,0,0,0,0,0,0,
238         Methods,
239         0,
240         0,
241         &SCA_IActuator::Type,
242         0,0,0,0,0,0,
243         py_base_new
244 };
245
246 PyMethodDef KX_SceneActuator::Methods[] =
247 {
248         {NULL,NULL} //Sentinel
249 };
250
251 PyAttributeDef KX_SceneActuator::Attributes[] = {
252         KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName),
253         KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera),
254         KX_PYATTRIBUTE_BOOL_RW("useRestart", KX_SceneActuator, m_restart),
255         KX_PYATTRIBUTE_INT_RW("mode", KX_SCENE_NODEF+1, KX_SCENE_MAX-1, true, KX_SceneActuator, m_mode),
256         { NULL }        //Sentinel
257 };
258
259 PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
260 {
261         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
262         if (!actuator->m_camera)
263                 Py_RETURN_NONE;
264         
265         return actuator->m_camera->GetProxy();
266 }
267
268 int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
269 {
270         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
271         KX_Camera *camOb;
272         
273         if (!ConvertPythonToCamera(value, &camOb, true, "actu.camera = value: KX_SceneActuator"))
274                 return PY_SET_ATTR_FAIL;
275         
276         if (actuator->m_camera)
277                 actuator->m_camera->UnregisterActuator(actuator);
278         
279         if(camOb==NULL) {
280                 actuator->m_camera= NULL;
281         }
282         else {  
283                 actuator->m_camera = camOb;
284                 actuator->m_camera->RegisterActuator(actuator);
285         }
286         
287         return PY_SET_ATTR_SUCCESS;
288 }
289
290 /* eof */