First checkin of core ODE functionality. See OdePhysicsController.cpp for a todo...
[blender-staging.git] / source / gameengine / Converter / KX_BlenderSceneConverter.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL 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. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
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/BL DUAL LICENSE BLOCK *****
30  */
31
32 #ifdef WIN32
33
34         #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
35 #endif
36
37
38 #include "KX_Scene.h"
39 #include "KX_GameObject.h"
40 #include "KX_IpoConvert.h"
41 #include "RAS_MeshObject.h"
42 #include "KX_PhysicsEngineEnums.h"
43
44 #include "DummyPhysicsEnvironment.h"
45
46 //to decide to use sumo/ode or dummy physics - defines USE_ODE
47 #include "KX_ConvertPhysicsObject.h"
48
49 #ifdef USE_ODE
50 #include "OdePhysicsEnvironment.h"
51 #endif //USE_ODE
52
53 #ifdef USE_SUMO_SOLID
54 #include "SumoPhysicsEnvironment.h"
55 #endif
56
57 #include "KX_BlenderSceneConverter.h"
58 #include "KX_BlenderScalarInterpolator.h"
59 #include "BL_BlenderDataConversion.h"
60 #include "BlenderWorldInfo.h"
61 #include "KX_Scene.h"
62
63 /* This little block needed for linking to Blender... */
64 #ifdef WIN32
65 #include "BLI_winstuff.h"
66 #endif
67
68 /* This list includes only data type definitions */
69 #include "DNA_scene_types.h"
70 #include "DNA_world_types.h"
71 #include "BKE_main.h"
72
73
74 KX_BlenderSceneConverter::KX_BlenderSceneConverter(
75                                                         struct Main* maggie,
76                                                         class KX_KetsjiEngine* engine
77                                                         )
78                                                         : m_maggie(maggie),
79                                                         m_ketsjiEngine(engine),
80                                                         m_alwaysUseExpandFraming(false)
81 {
82         m_newfilename = "";
83 }
84
85
86 KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
87 {
88         // clears meshes, and hashmaps from blender to gameengine data
89         int i;
90         // delete sumoshapes
91         
92
93         int numipolists = m_map_blender_to_gameipolist.size();
94         for (i=0; i<numipolists; i++) {
95                 BL_InterpolatorList *ipoList= *m_map_blender_to_gameipolist.at(i);
96
97                 delete (ipoList);
98         }
99
100         vector<KX_WorldInfo*>::iterator itw = m_worldinfos.begin();
101         while (itw != m_worldinfos.end()) {
102                 delete (*itw);
103                 itw++;
104         }
105
106         vector<RAS_IPolyMaterial*>::iterator itp = m_polymaterials.begin();
107         while (itp != m_polymaterials.end()) {
108                 delete (*itp);
109                 itp++;
110         }
111         
112         vector<RAS_MeshObject*>::iterator itm = m_meshobjects.begin();
113         while (itm != m_meshobjects.end()) {
114                 delete (*itm);
115                 itm++;
116         }
117 }
118
119
120
121 void KX_BlenderSceneConverter::SetNewFileName(const STR_String& filename)
122 {
123         m_newfilename = filename;
124 }
125
126
127
128 bool KX_BlenderSceneConverter::TryAndLoadNewFile()
129 {
130         bool result = false;
131
132         // find the file
133 /*      if ()
134         {
135                 result = true;
136         }
137         // if not, clear the newfilename
138         else
139         {
140                 m_newfilename = "";     
141         }
142 */
143         return result;
144 }
145
146
147
148         /**
149          * Find the specified scene by name, or the first
150          * scene if nothing matches (shouldn't happen).
151          */
152 static struct Scene *GetSceneForName2(struct Main *maggie, const STR_String& scenename) {
153         Scene *sce;
154
155         for (sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
156                 if (scenename == (sce->id.name+2))
157                         return sce;
158
159         return (Scene*) maggie->scene.first;
160 }
161
162
163 void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
164                                                                                         class KX_Scene* destinationscene,
165                                                                                         PyObject* dictobj,
166                                                                                         class SCA_IInputDevice* keyinputdev,
167                                                                                         class RAS_IRenderTools* rendertools,
168                                                                                         class RAS_ICanvas* canvas)
169 {
170         //find out which physics engine
171         Scene *blenderscene = GetSceneForName2(m_maggie, scenename);
172
173         e_PhysicsEngine physics_engine = UseSumo;
174
175         if (blenderscene)
176         {
177                 int i=0;
178                 
179                 if (blenderscene->world)
180                 {
181                         
182                         switch (blenderscene->world->pad1)
183                         {
184                                 
185                         case 1:
186                                 {
187                                         physics_engine = UseNone;
188                                         break;
189                                 };
190                         case 2:
191                                 {
192                                         physics_engine = UseSumo;
193                                         break;
194                                 }
195                         case 3:
196                                 {
197                                         physics_engine = UseODE;
198                                         break;
199                                 }
200                         case 4:
201                                 {
202                                         physics_engine = UseDynamo;
203                                         break;
204                                 }
205                         default:
206                                 {
207                                         physics_engine = UseODE;
208                                 }
209                         }
210                 }
211         }
212
213         switch (physics_engine)
214         {
215
216         case UseSumo:
217                 {
218 #ifdef USE_SUMO_SOLID
219
220                         PHY_IPhysicsEnvironment* physEnv = 
221                                 new SumoPhysicsEnvironment();
222 #else
223                         physics_engine = UseNone;
224                         
225                         PHY_IPhysicsEnvironment* physEnv = 
226                                 new DummyPhysicsEnvironment();
227
228 #endif
229                         destinationscene ->SetPhysicsEnvironment(physEnv);
230                         break;
231                 }
232         case UseODE:
233                 {
234 #ifdef USE_ODE
235
236                         PHY_IPhysicsEnvironment* physEnv = 
237                                 new ODEPhysicsEnvironment();
238 #else
239                         PHY_IPhysicsEnvironment* physEnv = 
240                                 new DummyPhysicsEnvironment();
241
242 #endif //USE_ODE
243
244                         destinationscene ->SetPhysicsEnvironment(physEnv);
245                         break;
246                 }
247         case UseDynamo:
248                 {
249                 }
250
251         case UseNone:
252                 {
253                 };
254         default:
255                 {
256                         physics_engine = UseNone;
257                         
258                         PHY_IPhysicsEnvironment* physEnv = 
259                                 new DummyPhysicsEnvironment();
260                         destinationscene ->SetPhysicsEnvironment(physEnv);
261
262                 }
263         }
264
265         BL_ConvertBlenderObjects(m_maggie,
266                                                          scenename,
267                                                          destinationscene,
268                                                          m_ketsjiEngine,
269                                                          physics_engine,
270                                                          dictobj,
271                                                          keyinputdev,
272                                                          rendertools,
273                                                          canvas,
274                                                          this,
275                                                          m_alwaysUseExpandFraming
276                                                          );
277
278         m_map_blender_to_gameactuator.clear();
279         m_map_blender_to_gamecontroller.clear();
280
281         m_map_blender_to_gameobject.clear();
282         m_map_mesh_to_gamemesh.clear();
283         m_map_gameobject_to_blender.clear();
284 }
285
286
287
288 void KX_BlenderSceneConverter::SetAlwaysUseExpandFraming(
289         bool to_what)
290 {
291         m_alwaysUseExpandFraming= to_what;
292 }
293
294         
295
296 void KX_BlenderSceneConverter::RegisterGameObject(
297                                                                         KX_GameObject *gameobject, 
298                                                                         struct Object *for_blenderobject) 
299 {
300         m_map_gameobject_to_blender.insert(CHashedPtr(gameobject),for_blenderobject);
301         m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject);
302 }
303
304
305
306 KX_GameObject *KX_BlenderSceneConverter::FindGameObject(
307                                                                         struct Object *for_blenderobject) 
308 {
309         KX_GameObject **obp= m_map_blender_to_gameobject[CHashedPtr(for_blenderobject)];
310         
311         return obp?*obp:NULL;
312 }
313
314
315
316 struct Object *KX_BlenderSceneConverter::FindBlenderObject(
317                                                                         KX_GameObject *for_gameobject) 
318 {
319         struct Object **obp= m_map_gameobject_to_blender[CHashedPtr(for_gameobject)];
320         
321         return obp?*obp:NULL;
322 }
323
324         
325
326 void KX_BlenderSceneConverter::RegisterGameMesh(
327                                                                         RAS_MeshObject *gamemesh,
328                                                                         struct Mesh *for_blendermesh)
329 {
330         m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
331         m_meshobjects.push_back(gamemesh);
332 }
333
334
335
336 RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
337                                                                         struct Mesh *for_blendermesh,
338                                                                         unsigned int onlayer)
339 {
340         RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)];
341         
342         if (meshp && onlayer==(*meshp)->GetLightLayer()) {
343                 return *meshp;
344         } else {
345                 return NULL;
346         }
347 }
348
349         
350
351
352         
353
354 void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
355 {
356         m_polymaterials.push_back(polymat);
357 }
358
359
360
361 void KX_BlenderSceneConverter::RegisterInterpolatorList(
362                                                                         BL_InterpolatorList *ipoList,
363                                                                         struct Ipo *for_ipo)
364 {
365         m_map_blender_to_gameipolist.insert(CHashedPtr(for_ipo), ipoList);
366 }
367
368
369
370 BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(
371                                                                         struct Ipo *for_ipo)
372 {
373         BL_InterpolatorList **listp = m_map_blender_to_gameipolist[CHashedPtr(for_ipo)];
374                 
375         return listp?*listp:NULL;
376 }
377
378
379
380 void KX_BlenderSceneConverter::RegisterGameActuator(
381                                                                         SCA_IActuator *act,
382                                                                         struct bActuator *for_actuator)
383 {
384         m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act);
385 }
386
387
388
389 SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(
390                                                                         struct bActuator *for_actuator)
391 {
392         SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
393         
394         return actp?*actp:NULL;
395 }
396
397
398
399 void KX_BlenderSceneConverter::RegisterGameController(
400                                                                         SCA_IController *cont,
401                                                                         struct bController *for_controller)
402 {
403         m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont);
404 }
405
406
407
408 SCA_IController *KX_BlenderSceneConverter::FindGameController(
409                                                                         struct bController *for_controller)
410 {
411         SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
412         
413         return contp?*contp:NULL;
414 }
415
416
417
418 void KX_BlenderSceneConverter::RegisterWorldInfo(
419                                                                         KX_WorldInfo *worldinfo)
420 {
421         m_worldinfos.push_back(worldinfo);
422 }