Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / source / gameengine / Ketsji / KX_Scene.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  * Ketsji scene. Holds references to all scene data.
29  */
30
31 #ifdef WIN32
32 #pragma warning (disable : 4786)
33 #endif //WIN32
34
35 #include "KX_Scene.h"
36 #include "MT_assert.h"
37 #include "KX_KetsjiEngine.h"
38 #include "KX_BlenderMaterial.h"
39 #include "RAS_IPolygonMaterial.h"
40 #include "ListValue.h"
41 #include "SCA_LogicManager.h"
42 #include "SCA_TimeEventManager.h"
43 //#include "SCA_AlwaysEventManager.h"
44 //#include "SCA_RandomEventManager.h"
45 //#include "KX_RayEventManager.h"
46 #include "KX_TouchEventManager.h"
47 #include "SCA_KeyboardManager.h"
48 #include "SCA_MouseManager.h"
49 //#include "SCA_PropertyEventManager.h"
50 #include "SCA_ActuatorEventManager.h"
51 #include "SCA_BasicEventManager.h"
52 #include "KX_Camera.h"
53 #include "SCA_JoystickManager.h"
54
55 #include "RAS_MeshObject.h"
56 #include "BL_SkinMeshObject.h"
57
58 #include "RAS_IRasterizer.h"
59 #include "RAS_BucketManager.h"
60
61 #include "FloatValue.h"
62 #include "SCA_IController.h"
63 #include "SCA_IActuator.h"
64 #include "SG_Node.h"
65 #include "SYS_System.h"
66 #include "SG_Controller.h"
67 #include "SG_IObject.h"
68 #include "SG_Tree.h"
69 #include "DNA_group_types.h"
70 #include "DNA_scene_types.h"
71 #include "BKE_anim.h"
72
73 #include "KX_SG_NodeRelationships.h"
74
75 #include "KX_NetworkEventManager.h"
76 #include "NG_NetworkScene.h"
77 #include "PHY_IPhysicsEnvironment.h"
78 #include "KX_IPhysicsController.h"
79 #include "PHY_IGraphicController.h"
80 #include "KX_BlenderSceneConverter.h"
81 #include "KX_MotionState.h"
82
83 #include "BL_ModifierDeformer.h"
84 #include "BL_ShapeDeformer.h"
85 #include "BL_DeformableGameObject.h"
86
87 // to get USE_BULLET!
88 #include "KX_ConvertPhysicsObject.h"
89
90 #ifdef USE_BULLET
91 #include "CcdPhysicsEnvironment.h"
92 #include "CcdPhysicsController.h"
93 #endif
94
95 #include "KX_Light.h"
96
97 void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
98 {
99         KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
100
101         if(replica)
102                 replica->Release();
103
104         return (void*)replica;
105 }
106
107 void* KX_SceneDestructionFunc(SG_IObject* node,void* gameobj,void* scene)
108 {
109         ((KX_Scene*)scene)->RemoveNodeDestructObject(node,(KX_GameObject*)gameobj);
110
111         return NULL;
112 };
113
114 bool KX_Scene::KX_ScenegraphUpdateFunc(SG_IObject* node,void* gameobj,void* scene)
115 {
116         return ((SG_Node*)node)->Schedule(((KX_Scene*)scene)->m_sghead);
117 }
118
119 bool KX_Scene::KX_ScenegraphRescheduleFunc(SG_IObject* node,void* gameobj,void* scene)
120 {
121         return ((SG_Node*)node)->Reschedule(((KX_Scene*)scene)->m_sghead);
122 }
123
124 SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(
125         KX_SceneReplicationFunc,
126         KX_SceneDestructionFunc,
127         KX_GameObject::UpdateTransformFunc,
128         KX_Scene::KX_ScenegraphUpdateFunc,
129         KX_Scene::KX_ScenegraphRescheduleFunc);
130
131 // temporarily var until there is a button in the userinterface
132 // (defined in KX_PythonInit.cpp)
133 extern bool gUseVisibilityTemp;
134
135 KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
136                                    class SCA_IInputDevice* mousedevice,
137                                    class NG_NetworkDeviceInterface *ndi,
138                                    const STR_String& sceneName,
139                                    Scene *scene): 
140         PyObjectPlus(),
141         m_keyboardmgr(NULL),
142         m_mousemgr(NULL),
143         m_sceneConverter(NULL),
144         m_physicsEnvironment(0),
145         m_sceneName(sceneName),
146         m_networkDeviceInterface(ndi),
147         m_active_camera(NULL),
148         m_ueberExecutionPriority(0),
149         m_blenderScene(scene)
150 {
151         m_suspendedtime = 0.0;
152         m_suspendeddelta = 0.0;
153
154         m_dbvt_culling = false;
155         m_dbvt_occlusion_res = 0;
156         m_activity_culling = false;
157         m_suspend = false;
158         m_isclearingZbuffer = true;
159         m_tempObjectList = new CListValue();
160         m_objectlist = new CListValue();
161         m_parentlist = new CListValue();
162         m_lightlist= new CListValue();
163         m_inactivelist = new CListValue();
164         m_euthanasyobjects = new CListValue();
165
166         m_logicmgr = new SCA_LogicManager();
167         
168         m_timemgr = new SCA_TimeEventManager(m_logicmgr);
169         m_keyboardmgr = new SCA_KeyboardManager(m_logicmgr,keyboarddevice);
170         m_mousemgr = new SCA_MouseManager(m_logicmgr,mousedevice);
171         
172         //SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr);
173         //SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr);
174         SCA_ActuatorEventManager* actmgr = new SCA_ActuatorEventManager(m_logicmgr);
175         //SCA_RandomEventManager* rndmgr = new SCA_RandomEventManager(m_logicmgr);
176         SCA_BasicEventManager* basicmgr = new SCA_BasicEventManager(m_logicmgr);
177         //KX_RayEventManager* raymgr = new KX_RayEventManager(m_logicmgr);
178
179         KX_NetworkEventManager* netmgr = new KX_NetworkEventManager(m_logicmgr, ndi);
180         
181         
182
183         //m_logicmgr->RegisterEventManager(alwaysmgr);
184         //m_logicmgr->RegisterEventManager(propmgr);
185         m_logicmgr->RegisterEventManager(actmgr);
186         m_logicmgr->RegisterEventManager(m_keyboardmgr);
187         m_logicmgr->RegisterEventManager(m_mousemgr);
188         m_logicmgr->RegisterEventManager(m_timemgr);
189         //m_logicmgr->RegisterEventManager(rndmgr);
190         //m_logicmgr->RegisterEventManager(raymgr);
191         m_logicmgr->RegisterEventManager(netmgr);
192         m_logicmgr->RegisterEventManager(basicmgr);
193
194
195         SYS_SystemHandle hSystem = SYS_GetSystem();
196         bool nojoystick= SYS_GetCommandLineInt(hSystem,"nojoystick",0);
197         if (!nojoystick)
198         {
199                 SCA_JoystickManager *joymgr     = new SCA_JoystickManager(m_logicmgr);
200                 m_logicmgr->RegisterEventManager(joymgr);
201         }
202
203         MT_assert (m_networkDeviceInterface != NULL);
204         m_networkScene = new NG_NetworkScene(m_networkDeviceInterface);
205         
206         m_rootnode = NULL;
207
208         m_bucketmanager=new RAS_BucketManager();
209         
210         m_attr_dict = PyDict_New(); /* new ref */
211 }
212
213
214
215 KX_Scene::~KX_Scene()
216 {
217         // The release of debug properties used to be in SCA_IScene::~SCA_IScene
218         // It's still there but we remove all properties here otherwise some
219         // reference might be hanging and causing late release of objects
220         RemoveAllDebugProperties();
221
222         while (GetRootParentList()->GetCount() > 0) 
223         {
224                 KX_GameObject* parentobj = (KX_GameObject*) GetRootParentList()->GetValue(0);
225                 this->RemoveObject(parentobj);
226         }
227
228         if(m_objectlist)
229                 m_objectlist->Release();
230
231         if (m_parentlist)
232                 m_parentlist->Release();
233         
234         if (m_inactivelist)
235                 m_inactivelist->Release();
236
237         if (m_lightlist)
238                 m_lightlist->Release();
239         
240         if (m_tempObjectList)
241                 m_tempObjectList->Release();
242
243         if (m_euthanasyobjects)
244                 m_euthanasyobjects->Release();
245
246         if (m_logicmgr)
247                 delete m_logicmgr;
248
249         if (m_physicsEnvironment)
250                 delete m_physicsEnvironment;
251
252         if (m_networkScene)
253                 delete m_networkScene;
254         
255         if (m_bucketmanager)
256         {
257                 delete m_bucketmanager;
258         }
259         PyDict_Clear(m_attr_dict);
260         Py_DECREF(m_attr_dict);
261 }
262
263 RAS_BucketManager* KX_Scene::GetBucketManager()
264 {
265         return m_bucketmanager;
266 }
267
268
269
270 CListValue* KX_Scene::GetObjectList()
271 {
272         return m_objectlist;
273 }
274
275
276
277 CListValue* KX_Scene::GetRootParentList()
278 {
279         return m_parentlist;
280 }
281
282 CListValue* KX_Scene::GetInactiveList()
283 {
284         return m_inactivelist;
285 }
286
287
288
289 CListValue* KX_Scene::GetLightList()
290 {
291         return m_lightlist;
292 }
293
294 SCA_LogicManager* KX_Scene::GetLogicManager()
295 {
296         return m_logicmgr;
297 }
298
299 SCA_TimeEventManager* KX_Scene::GetTimeEventManager()
300 {
301         return m_timemgr;
302 }
303
304
305
306  
307 list<class KX_Camera*>* KX_Scene::GetCameras()
308 {
309         return &m_cameras;
310 }
311
312
313
314 void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings)
315 {
316         m_frame_settings = frame_settings;
317 };
318
319 /**
320  * Return a const reference to the framing 
321  * type set by the above call.
322  * The contents are not guarenteed to be sensible
323  * if you don't call the above function.
324  */
325 const RAS_FrameSettings& KX_Scene::GetFramingType() const 
326 {
327         return m_frame_settings;
328 };      
329
330
331
332 /**
333  * Store the current scene's viewport on the 
334  * game engine canvas.
335  */
336 void KX_Scene::SetSceneViewport(const RAS_Rect &viewport)
337 {
338         m_viewport = viewport;
339 }
340
341
342
343 const RAS_Rect& KX_Scene::GetSceneViewport() const 
344 {
345         return m_viewport;
346 }
347
348
349
350 void KX_Scene::SetWorldInfo(class KX_WorldInfo* worldinfo)
351 {
352         m_worldinfo = worldinfo;
353 }
354
355
356
357 class KX_WorldInfo* KX_Scene::GetWorldInfo()
358 {
359         return m_worldinfo;
360 }
361
362
363 const STR_String& KX_Scene::GetName()
364 {
365         return m_sceneName;
366 }
367
368
369 void KX_Scene::Suspend()
370 {
371         m_suspend = true;
372 }
373
374 void KX_Scene::Resume()
375 {
376         m_suspend = false;
377 }
378
379 void KX_Scene::SetActivityCulling(bool b)
380 {
381         m_activity_culling = b;
382 }
383
384 bool KX_Scene::IsSuspended()
385 {
386         return m_suspend;
387 }
388
389 bool KX_Scene::IsClearingZBuffer()
390 {
391         return m_isclearingZbuffer;
392 }
393
394 void KX_Scene::EnableZBufferClearing(bool isclearingZbuffer)
395 {
396         m_isclearingZbuffer = isclearingZbuffer;
397 }
398
399 void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj)
400 {
401         KX_GameObject* orgobj = (KX_GameObject*)gameobj;        
402         if (NewRemoveObject(orgobj) != 0)
403         {
404                 // object is not yet deleted because a reference is hanging somewhere.
405                 // This should not happen anymore since we use proxy object for Python
406                 // confident enough to put an assert?
407                 //assert(false);
408                 printf("Zombie object! name=%s\n", orgobj->GetName().ReadPtr());
409                 orgobj->SetSGNode(NULL);
410                 PHY_IGraphicController* ctrl = orgobj->GetGraphicController();
411                 if (ctrl)
412                 {
413                         // a graphic controller is set, we must delete it as the node will be deleted
414                         delete ctrl;
415                         orgobj->SetGraphicController(NULL);
416                 }
417         }
418         if (node)
419                 delete node;
420 }
421
422 KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CValue* gameobj)
423 {
424         // for group duplication, limit the duplication of the hierarchy to the
425         // objects that are part of the group. 
426         if (!IsObjectInGroup(gameobj))
427                 return NULL;
428         
429         KX_GameObject* orgobj = (KX_GameObject*)gameobj;
430         KX_GameObject* newobj = (KX_GameObject*)orgobj->GetReplica();
431         m_map_gameobject_to_replica.insert(orgobj, newobj);
432
433         // also register 'timers' (time properties) of the replica
434         int numprops = newobj->GetPropertyCount();
435
436         for (int i = 0; i < numprops; i++)
437         {
438                 CValue* prop = newobj->GetProperty(i);
439
440                 if (prop->GetProperty("timer"))
441                         this->m_timemgr->AddTimeProperty(prop);
442         }
443
444         if (node)
445         {
446                 newobj->SetSGNode((SG_Node*)node);
447         }
448         else
449         {
450                 m_rootnode = new SG_Node(newobj,this,KX_Scene::m_callbacks);
451         
452                 // this fixes part of the scaling-added object bug
453                 SG_Node* orgnode = orgobj->GetSGNode();
454                 m_rootnode->SetLocalScale(orgnode->GetLocalScale());
455                 m_rootnode->SetLocalPosition(orgnode->GetLocalPosition());
456                 m_rootnode->SetLocalOrientation(orgnode->GetLocalOrientation());
457
458                 // define the relationship between this node and it's parent.
459                 KX_NormalParentRelation * parent_relation = 
460                         KX_NormalParentRelation::New();
461                 m_rootnode->SetParentRelation(parent_relation);
462
463                 newobj->SetSGNode(m_rootnode);
464         }
465         
466         SG_IObject* replicanode = newobj->GetSGNode();
467 //      SG_Node* rootnode = (replicanode == m_rootnode ? NULL : m_rootnode);
468
469         replicanode->SetSGClientObject(newobj);
470
471         // this is the list of object that are send to the graphics pipeline
472         m_objectlist->Add(newobj->AddRef());
473         if (newobj->IsLight())
474                 m_lightlist->Add(newobj->AddRef());
475         newobj->AddMeshUser();
476
477         // logic cannot be replicated, until the whole hierarchy is replicated.
478         m_logicHierarchicalGameObjects.push_back(newobj);
479         //replicate controllers of this node
480         SGControllerList        scenegraphcontrollers = orgobj->GetSGNode()->GetSGControllerList();
481         replicanode->RemoveAllControllers();
482         SGControllerList::iterator cit;
483         //int numcont = scenegraphcontrollers.size();
484         
485         for (cit = scenegraphcontrollers.begin();!(cit==scenegraphcontrollers.end());++cit)
486         {
487                 // controller replication is quite complicated
488                 // only replicate ipo and physics controller for now
489
490                 SG_Controller* replicacontroller = (*cit)->GetReplica((SG_Node*) replicanode);
491                 if (replicacontroller)
492                 {
493                         replicacontroller->SetObject(replicanode);
494                         replicanode->AddSGController(replicacontroller);
495                 }
496         }
497         // replicate graphic controller
498         if (orgobj->GetGraphicController())
499         {
500                 PHY_IMotionState* motionstate = new KX_MotionState(newobj->GetSGNode());
501                 PHY_IGraphicController* newctrl = orgobj->GetGraphicController()->GetReplica(motionstate);
502                 newctrl->setNewClientInfo(newobj->getClientInfo());
503                 newobj->SetGraphicController(newctrl);
504         }
505         return newobj;
506 }
507
508
509
510 // before calling this method KX_Scene::ReplicateLogic(), make sure to
511 // have called 'GameObject::ReParentLogic' for each object this
512 // hierarchy that's because first ALL bricks must exist in the new
513 // replica of the hierarchy in order to make cross-links work properly
514 // !
515 // It is VERY important that the order of sensors and actuators in
516 // the replicated object is preserved: it is is used to reconnect the logic.
517 // This method is more robust then using the bricks name in case of complex 
518 // group replication. The replication of logic bricks is done in 
519 // SCA_IObject::ReParentLogic(), make sure it preserves the order of the bricks.
520 void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
521 {
522         // also relink the controller to sensors/actuators
523         SCA_ControllerList& controllers = newobj->GetControllers();
524         //SCA_SensorList&     sensors     = newobj->GetSensors();
525         //SCA_ActuatorList&   actuators   = newobj->GetActuators();
526
527         for (SCA_ControllerList::iterator itc = controllers.begin(); !(itc==controllers.end());itc++)
528         {
529                 SCA_IController* cont = (*itc);
530                 cont->SetUeberExecutePriority(m_ueberExecutionPriority);
531                 vector<SCA_ISensor*> linkedsensors = cont->GetLinkedSensors();
532                 vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators();
533
534                 // disconnect the sensors and actuators
535                 // do it directly on the list at this controller is not connected to anything at this stage
536                 cont->GetLinkedSensors().clear();
537                 cont->GetLinkedActuators().clear();
538                 
539                 // now relink each sensor
540                 for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++)
541                 {
542                         SCA_ISensor* oldsensor = (*its);
543                         SCA_IObject* oldsensorobj = oldsensor->GetParent();
544                         SCA_IObject* newsensorobj = NULL;
545                 
546                         // the original owner of the sensor has been replicated?
547                         void **h_obj = m_map_gameobject_to_replica[oldsensorobj];
548                         if (h_obj)
549                                 newsensorobj = (SCA_IObject*)(*h_obj);
550                         if (!newsensorobj)
551                         {
552                                 // no, then the sensor points outside the hierachy, keep it the same
553                                 if (m_objectlist->SearchValue(oldsensorobj))
554                                         // only replicate links that points to active objects
555                                         m_logicmgr->RegisterToSensor(cont,oldsensor);
556                         }
557                         else
558                         {
559                                 // yes, then the new sensor has the same position
560                                 SCA_SensorList& sensorlist = oldsensorobj->GetSensors();
561                                 SCA_SensorList::iterator sit;
562                                 SCA_ISensor* newsensor = NULL;
563                                 int sensorpos;
564
565                                 for (sensorpos=0, sit=sensorlist.begin(); sit!=sensorlist.end(); sit++, sensorpos++)
566                                 {
567                                         if ((*sit) == oldsensor) 
568                                         {
569                                                 newsensor = newsensorobj->GetSensors().at(sensorpos);
570                                                 break;
571                                         }
572                                 }
573                                 assert(newsensor != NULL);
574                                 m_logicmgr->RegisterToSensor(cont,newsensor);
575                         }
576                 }
577                 
578                 // now relink each actuator
579                 for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());ita++)
580                 {
581                         SCA_IActuator* oldactuator = (*ita);
582                         SCA_IObject* oldactuatorobj = oldactuator->GetParent();
583                         SCA_IObject* newactuatorobj = NULL;
584
585                         // the original owner of the sensor has been replicated?
586                         void **h_obj = m_map_gameobject_to_replica[oldactuatorobj];
587                         if (h_obj)
588                                 newactuatorobj = (SCA_IObject*)(*h_obj);
589
590                         if (!newactuatorobj)
591                         {
592                                 // no, then the sensor points outside the hierachy, keep it the same
593                                 if (m_objectlist->SearchValue(oldactuatorobj))
594                                         // only replicate links that points to active objects
595                                         m_logicmgr->RegisterToActuator(cont,oldactuator);
596                         }
597                         else
598                         {
599                                 // yes, then the new sensor has the same position
600                                 SCA_ActuatorList& actuatorlist = oldactuatorobj->GetActuators();
601                                 SCA_ActuatorList::iterator ait;
602                                 SCA_IActuator* newactuator = NULL;
603                                 int actuatorpos;
604
605                                 for (actuatorpos=0, ait=actuatorlist.begin(); ait!=actuatorlist.end(); ait++, actuatorpos++)
606                                 {
607                                         if ((*ait) == oldactuator) 
608                                         {
609                                                 newactuator = newactuatorobj->GetActuators().at(actuatorpos);
610                                                 break;
611                                         }
612                                 }
613                                 assert(newactuator != NULL);
614                                 m_logicmgr->RegisterToActuator(cont,newactuator);
615                                 newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
616                         }
617                 }
618         }
619         // ready to set initial state
620         newobj->ResetState();
621 }
622
623 void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
624 {
625         KX_GameObject* groupobj = (KX_GameObject*) obj;
626         KX_GameObject* replica;
627         KX_GameObject* gameobj;
628         Object* blgroupobj = groupobj->GetBlenderObject();
629         Group* group;
630         GroupObject *go;
631         vector<KX_GameObject*> duplilist;
632
633         if (!groupobj->GetSGNode() ||
634                 !groupobj->IsDupliGroup() ||
635                 level>MAX_DUPLI_RECUR)
636                 return;
637
638         // we will add one group at a time
639         m_logicHierarchicalGameObjects.clear();
640         m_map_gameobject_to_replica.clear();
641         m_ueberExecutionPriority++;
642         // for groups will do something special: 
643         // we will force the creation of objects to those in the group only
644         // Again, this is match what Blender is doing (it doesn't care of parent relationship)
645         m_groupGameObjects.clear();
646
647         group = blgroupobj->dup_group;
648         for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next) 
649         {
650                 Object* blenderobj = go->ob;
651                 if (blgroupobj == blenderobj)
652                         // this check is also in group_duplilist()
653                         continue;
654
655                 gameobj = (KX_GameObject*)m_logicmgr->FindGameObjByBlendObj(blenderobj);
656                 if (gameobj == NULL) 
657                 {
658                         // this object has not been converted!!!
659                         // Should not happen as dupli group are created automatically 
660                         continue;
661                 }
662
663                 gameobj->SetBlenderGroupObject(blgroupobj);
664
665                 if ((blenderobj->lay & group->layer)==0)
666                 {
667                         // object is not visible in the 3D view, will not be instantiated
668                         continue;
669                 }
670                 m_groupGameObjects.insert(gameobj);
671         }
672
673         set<CValue*>::iterator oit;
674         for (oit=m_groupGameObjects.begin(); oit != m_groupGameObjects.end(); oit++)
675         {
676                 gameobj = (KX_GameObject*)(*oit);
677
678                 KX_GameObject *parent = gameobj->GetParent();
679                 if (parent != NULL)
680                 {
681                         parent->Release(); // GetParent() increased the refcount
682
683                         // this object is not a top parent. Either it is the child of another
684                         // object in the group and it will be added automatically when the parent
685                         // is added. Or it is the child of an object outside the group and the group
686                         // is inconsistent, skip it anyway
687                         continue;
688                 }
689                 replica = (KX_GameObject*) AddNodeReplicaObject(NULL,gameobj);
690                 // add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame)
691                 m_parentlist->Add(replica->AddRef());
692
693                 // recurse replication into children nodes
694                 NodeList& children = gameobj->GetSGNode()->GetSGChildren();
695
696                 replica->GetSGNode()->ClearSGChildren();
697                 for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
698                 {
699                         SG_Node* orgnode = (*childit);
700                         SG_Node* childreplicanode = orgnode->GetSGReplica();
701                         if (childreplicanode)
702                                 replica->GetSGNode()->AddChild(childreplicanode);
703                 }
704                 // don't replicate logic now: we assume that the objects in the group can have
705                 // logic relationship, even outside parent relationship
706                 // In order to match 3D view, the position of groupobj is used as a 
707                 // transformation matrix instead of the new position. This means that 
708                 // the group reference point is 0,0,0
709
710                 // get the rootnode's scale
711                 MT_Vector3 newscale = groupobj->NodeGetWorldScaling();
712                 // set the replica's relative scale with the rootnode's scale
713                 replica->NodeSetRelativeScale(newscale);
714
715                 MT_Point3 offset(group->dupli_ofs);
716                 MT_Point3 newpos = groupobj->NodeGetWorldPosition() + 
717                         newscale*(groupobj->NodeGetWorldOrientation() * (gameobj->NodeGetWorldPosition()-offset));
718                 replica->NodeSetLocalPosition(newpos);
719                 // set the orientation after position for softbody!
720                 MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation();
721                 replica->NodeSetLocalOrientation(newori);
722                 // update scenegraph for entire tree of children
723                 replica->GetSGNode()->UpdateWorldData(0);
724                 replica->GetSGNode()->SetBBox(gameobj->GetSGNode()->BBox());
725                 replica->GetSGNode()->SetRadius(gameobj->GetSGNode()->Radius());
726                 // we can now add the graphic controller to the physic engine
727                 replica->ActivateGraphicController(true);
728
729                 // done with replica
730                 replica->Release();
731         }
732
733         // the logic must be replicated first because we need
734         // the new logic bricks before relinking
735         vector<KX_GameObject*>::iterator git;
736         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
737         {
738                 (*git)->ReParentLogic();
739         }
740         
741         //      relink any pointers as necessary, sort of a temporary solution
742         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
743         {
744                 // this will also relink the actuator to objects within the hierarchy
745                 (*git)->Relink(&m_map_gameobject_to_replica);
746                 // add the object in the layer of the parent
747                 (*git)->SetLayer(groupobj->GetLayer());
748                 // If the object was a light, we need to update it's RAS_LightObject as well
749                 if ((*git)->IsLight())
750                 {
751                         KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
752                         lightobj->GetLightData()->m_layer = groupobj->GetLayer();
753                 }
754         }
755
756         // replicate crosslinks etc. between logic bricks
757         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
758         {
759                 ReplicateLogic((*git));
760         }
761         
762         // now look if object in the hierarchy have dupli group and recurse
763         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
764         {
765                 if ((*git) != groupobj && (*git)->IsDupliGroup())
766                         // can't instantiate group immediately as it destroys m_logicHierarchicalGameObjects
767                         duplilist.push_back((*git));
768         }
769
770         for (git = duplilist.begin(); !(git == duplilist.end()); ++git)
771         {
772                 DupliGroupRecurse((*git), level+1);
773         }
774 }
775
776
777 SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
778                                                                                 class CValue* parentobject,
779                                                                                 int lifespan)
780 {
781
782         m_logicHierarchicalGameObjects.clear();
783         m_map_gameobject_to_replica.clear();
784         m_groupGameObjects.clear();
785
786         // todo: place a timebomb in the object, for temporarily objects :)
787         // lifespan of zero means 'this object lives forever'
788         KX_GameObject* originalobj = (KX_GameObject*) originalobject;
789         KX_GameObject* parentobj = (KX_GameObject*) parentobject;
790
791         m_ueberExecutionPriority++;
792
793         // lets create a replica
794         KX_GameObject* replica = (KX_GameObject*) AddNodeReplicaObject(NULL,originalobj);
795
796         if (lifespan > 0)
797         {
798                 // add a timebomb to this object
799                 // for now, convert between so called frames and realtime
800                 m_tempObjectList->Add(replica->AddRef());
801                 CValue *fval = new CFloatValue(lifespan*0.02);
802                 replica->SetProperty("::timebomb",fval);
803                 fval->Release();
804         }
805
806         // add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame)
807         m_parentlist->Add(replica->AddRef());
808
809         // recurse replication into children nodes
810
811         NodeList& children = originalobj->GetSGNode()->GetSGChildren();
812
813         replica->GetSGNode()->ClearSGChildren();
814         for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
815         {
816                 SG_Node* orgnode = (*childit);
817                 SG_Node* childreplicanode = orgnode->GetSGReplica();
818                 if (childreplicanode)
819                         replica->GetSGNode()->AddChild(childreplicanode);
820         }
821
822         // At this stage all the objects in the hierarchy have been duplicated,
823         // we can update the scenegraph, we need it for the duplication of logic
824         MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition();
825         replica->NodeSetLocalPosition(newpos);
826
827         MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
828         replica->NodeSetLocalOrientation(newori);
829         
830         // get the rootnode's scale
831         MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
832
833         // set the replica's relative scale with the rootnode's scale
834         replica->NodeSetRelativeScale(newscale);
835
836         replica->GetSGNode()->UpdateWorldData(0);
837         replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
838         replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
839         // the size is correct, we can add the graphic controller to the physic engine
840         replica->ActivateGraphicController(true);
841
842         // now replicate logic
843         vector<KX_GameObject*>::iterator git;
844         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
845         {
846                 (*git)->ReParentLogic();
847         }
848         
849         //      relink any pointers as necessary, sort of a temporary solution
850         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
851         {
852                 // this will also relink the actuators in the hierarchy
853                 (*git)->Relink(&m_map_gameobject_to_replica);
854                 // add the object in the layer of the parent
855                 (*git)->SetLayer(parentobj->GetLayer());
856                 // If the object was a light, we need to update it's RAS_LightObject as well
857                 if ((*git)->IsLight())
858                 {
859                         KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
860                         lightobj->GetLightData()->m_layer = parentobj->GetLayer();
861                 }
862         }
863
864         // replicate crosslinks etc. between logic bricks
865         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
866         {
867                 ReplicateLogic((*git));
868         }
869         
870         // check if there are objects with dupligroup in the hierarchy
871         vector<KX_GameObject*> duplilist;
872         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
873         {
874                 if ((*git)->IsDupliGroup())
875                 {
876                         // separate list as m_logicHierarchicalGameObjects is also used by DupliGroupRecurse()
877                         duplilist.push_back(*git);
878                 }
879         }
880         for (git = duplilist.begin();!(git==duplilist.end());++git)
881         {
882                 DupliGroupRecurse(*git, 0);
883         }
884         //      don't release replica here because we are returning it, not done with it...
885         return replica;
886 }
887
888
889
890 void KX_Scene::RemoveObject(class CValue* gameobj)
891 {
892         KX_GameObject* newobj = (KX_GameObject*) gameobj;
893
894         // disconnect child from parent
895         SG_Node* node = newobj->GetSGNode();
896
897         if (node)
898         {
899                 node->DisconnectFromParent();
900
901                 // recursively destruct
902                 node->Destruct();
903         }
904         //no need to do that: the object is destroyed and memory released 
905         //newobj->SetSGNode(0);
906 }
907
908 void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
909 {
910         //KX_GameObject* newobj = (KX_GameObject*) gameobj;
911         if (!m_euthanasyobjects->SearchValue(gameobj))
912         {
913                 m_euthanasyobjects->Add(gameobj->AddRef());
914         } 
915 }
916
917
918
919 int KX_Scene::NewRemoveObject(class CValue* gameobj)
920 {
921         int ret;
922         KX_GameObject* newobj = (KX_GameObject*) gameobj;
923
924         /* Invalidate the python reference, since the object may exist in script lists
925          * its possible that it wont be automatically invalidated, so do it manually here,
926          * 
927          * if for some reason the object is added back into the scene python can always get a new Proxy
928          */
929         newobj->InvalidateProxy();
930
931         // keep the blender->game object association up to date
932         // note that all the replicas of an object will have the same
933         // blender object, that's why we need to check the game object
934         // as only the deletion of the original object must be recorded
935         m_logicmgr->UnregisterGameObj(newobj->GetBlenderObject(), gameobj);
936
937         //todo: look at this
938         //GetPhysicsEnvironment()->RemovePhysicsController(gameobj->getPhysicsController());
939
940         // remove all sensors/controllers/actuators from logicsystem...
941         
942         SCA_SensorList& sensors = newobj->GetSensors();
943         for (SCA_SensorList::iterator its = sensors.begin();
944                  !(its==sensors.end());its++)
945         {
946                 m_logicmgr->RemoveSensor(*its);
947         }
948         
949     SCA_ControllerList& controllers = newobj->GetControllers();
950         for (SCA_ControllerList::iterator itc = controllers.begin();
951                  !(itc==controllers.end());itc++)
952         {
953                 m_logicmgr->RemoveController(*itc);
954         }
955
956         SCA_ActuatorList& actuators = newobj->GetActuators();
957         for (SCA_ActuatorList::iterator ita = actuators.begin();
958                  !(ita==actuators.end());ita++)
959         {
960                 m_logicmgr->RemoveActuator(*ita);
961         }
962         // the sensors/controllers/actuators must also be released, this is done in ~SCA_IObject
963
964         // now remove the timer properties from the time manager
965         int numprops = newobj->GetPropertyCount();
966
967         for (int i = 0; i < numprops; i++)
968         {
969                 CValue* propval = newobj->GetProperty(i);
970                 if (propval->GetProperty("timer"))
971                 {
972                         m_timemgr->RemoveTimeProperty(propval);
973                 }
974         }
975         
976         newobj->RemoveMeshes();
977         ret = 1;
978         if (newobj->IsLight() && m_lightlist->RemoveValue(newobj))
979                 ret = newobj->Release();
980         if (m_objectlist->RemoveValue(newobj))
981                 ret = newobj->Release();
982         if (m_tempObjectList->RemoveValue(newobj))
983                 ret = newobj->Release();
984         if (m_parentlist->RemoveValue(newobj))
985                 ret = newobj->Release();
986         if (m_inactivelist->RemoveValue(newobj))
987                 ret = newobj->Release();
988         if (m_euthanasyobjects->RemoveValue(newobj))
989                 ret = newobj->Release();
990                 
991         if (newobj == m_active_camera)
992         {
993                 //no AddRef done on m_active_camera so no Release
994                 //m_active_camera->Release();
995                 m_active_camera = NULL;
996         }
997
998         // in case this is a camera
999         m_cameras.remove((KX_Camera*)newobj);
1000
1001         /* currently does nothing, keep incase we need to Unregister something */
1002 #if 0
1003         if (m_sceneConverter)
1004                 m_sceneConverter->UnregisterGameObject(newobj);
1005 #endif
1006         
1007         // return value will be 0 if the object is actually deleted (all reference gone)
1008         
1009         return ret;
1010 }
1011
1012
1013
1014 void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool use_phys)
1015 {
1016         KX_GameObject* gameobj = static_cast<KX_GameObject*>(obj);
1017         RAS_MeshObject* mesh = static_cast<RAS_MeshObject*>(meshobj);
1018
1019         if(!gameobj) {
1020                 std::cout << "KX_Scene::ReplaceMesh Warning: invalid object, doing nothing" << std::endl;
1021                 return;
1022         }
1023
1024         if(use_gfx && mesh != NULL)
1025         {               
1026         gameobj->RemoveMeshes();
1027         gameobj->AddMesh(mesh);
1028         
1029         if (gameobj->m_isDeformable)
1030         {
1031                 BL_DeformableGameObject* newobj = static_cast<BL_DeformableGameObject*>( gameobj );
1032                 
1033                 if (newobj->GetDeformer())
1034                 {
1035                         delete newobj->GetDeformer();
1036                         newobj->SetDeformer(NULL);
1037                 }
1038
1039                 if (mesh->IsDeformed())
1040                 {
1041                         // we must create a new deformer but which one?
1042                         KX_GameObject* parentobj = newobj->GetParent();
1043                         // this always return the original game object (also for replicate)
1044                         Object* blendobj = newobj->GetBlenderObject();
1045                         // object that owns the new mesh
1046                         Object* oldblendobj = static_cast<struct Object*>(m_logicmgr->FindBlendObjByGameMeshName(mesh->GetName()));
1047                         Mesh* blendmesh = mesh->GetMesh();
1048
1049                         bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(blendobj);
1050                         bool bHasShapeKey = blendmesh->key != NULL && blendmesh->key->type==KEY_RELATIVE;
1051                         bool bHasDvert = blendmesh->dvert != NULL;
1052                         bool bHasArmature = 
1053                                 parentobj &&                                                            // current parent is armature
1054                                 parentobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE &&
1055                                 oldblendobj &&                                                          // needed for mesh deform
1056                                 blendobj->parent &&                                                     // original object had armature (not sure this test is needed)
1057                                 blendobj->parent->type == OB_ARMATURE && 
1058                                 blendobj->partype==PARSKEL && 
1059                                 blendmesh->dvert!=NULL;                                         // mesh has vertex group
1060                         bool releaseParent = true;
1061
1062                         
1063                         if (oldblendobj==NULL) {
1064                                 std::cout << "warning: ReplaceMesh() new mesh is not used in an object from the current scene, you will get incorrect behavior" << std::endl;
1065                                 bHasShapeKey= bHasDvert= bHasArmature=bHasModifier= false;
1066                         }
1067                         
1068                         if (bHasModifier)
1069                         {
1070                                 BL_ModifierDeformer* modifierDeformer;
1071                                 if (bHasShapeKey || bHasArmature)
1072                                 {
1073                                         modifierDeformer = new BL_ModifierDeformer(
1074                                                 newobj,
1075                                                 m_blenderScene,
1076                                                 oldblendobj, blendobj,
1077                                                 static_cast<BL_SkinMeshObject*>(mesh),
1078                                                 true,
1079                                                 static_cast<BL_ArmatureObject*>( parentobj )
1080                                         );
1081                                         releaseParent= false;
1082                                         modifierDeformer->LoadShapeDrivers(blendobj->parent);
1083                                 }
1084                                 else
1085                                 {
1086                                         modifierDeformer = new BL_ModifierDeformer(
1087                                                 newobj,
1088                                                 m_blenderScene,
1089                                                 oldblendobj, blendobj,
1090                                                 static_cast<BL_SkinMeshObject*>(mesh),
1091                                                 false,
1092                                                 NULL
1093                                         );
1094                                 }
1095                                 newobj->SetDeformer(modifierDeformer);
1096                         } 
1097                         else    if (bHasShapeKey)
1098                         {
1099                                 BL_ShapeDeformer* shapeDeformer;
1100                                 if (bHasArmature) 
1101                                 {
1102                                         shapeDeformer = new BL_ShapeDeformer(
1103                                                 newobj,
1104                                                 oldblendobj, blendobj,
1105                                                 static_cast<BL_SkinMeshObject*>(mesh),
1106                                                 true,
1107                                                 true,
1108                                                 static_cast<BL_ArmatureObject*>( parentobj )
1109                                         );
1110                                         releaseParent= false;
1111                                         shapeDeformer->LoadShapeDrivers(blendobj->parent);
1112                                 }
1113                                 else
1114                                 {
1115                                         shapeDeformer = new BL_ShapeDeformer(
1116                                                 newobj,
1117                                                 oldblendobj, blendobj,
1118                                                 static_cast<BL_SkinMeshObject*>(mesh),
1119                                                 false,
1120                                                 true,
1121                                                 NULL
1122                                         );
1123                                 }
1124                                 newobj->SetDeformer( shapeDeformer);
1125                         }
1126                         else if (bHasArmature) 
1127                         {
1128                                 BL_SkinDeformer* skinDeformer = new BL_SkinDeformer(
1129                                         newobj,
1130                                         oldblendobj, blendobj,
1131                                         static_cast<BL_SkinMeshObject*>(mesh),
1132                                         true,
1133                                         true,
1134                                         static_cast<BL_ArmatureObject*>( parentobj )
1135                                 );
1136                                 releaseParent= false;
1137                                 newobj->SetDeformer(skinDeformer);
1138                         }
1139                         else if (bHasDvert)
1140                         {
1141                                 BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(
1142                                         newobj, oldblendobj, static_cast<BL_SkinMeshObject*>(mesh)
1143                                 );
1144                                 newobj->SetDeformer(meshdeformer);
1145                         }
1146
1147                         // release parent reference if its not being used 
1148                         if( releaseParent && parentobj)
1149                                 parentobj->Release();
1150                 }
1151         }
1152
1153         gameobj->AddMeshUser();
1154         }
1155         
1156         if(use_phys) { /* update the new assigned mesh with the physics mesh */
1157                 KX_ReInstanceBulletShapeFromMesh(gameobj, NULL, use_gfx?NULL:mesh);
1158         }
1159 }
1160
1161 KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
1162 {
1163         list<KX_Camera*>::iterator it = m_cameras.begin();
1164
1165         while ( (it != m_cameras.end()) 
1166                         && ((*it) != cam) ) {
1167           it++;
1168         }
1169
1170         return ((it == m_cameras.end()) ? NULL : (*it));
1171 }
1172
1173
1174 KX_Camera* KX_Scene::FindCamera(STR_String& name)
1175 {
1176         list<KX_Camera*>::iterator it = m_cameras.begin();
1177
1178         while ( (it != m_cameras.end()) 
1179                         && ((*it)->GetName() != name) ) {
1180           it++;
1181         }
1182
1183         return ((it == m_cameras.end()) ? NULL : (*it));
1184 }
1185
1186 void KX_Scene::AddCamera(KX_Camera* cam)
1187 {
1188         if (!FindCamera(cam))
1189                 m_cameras.push_back(cam);
1190 }
1191
1192
1193 KX_Camera* KX_Scene::GetActiveCamera()
1194 {       
1195         // NULL if not defined
1196         return m_active_camera;
1197 }
1198
1199
1200 void KX_Scene::SetActiveCamera(KX_Camera* cam)
1201 {
1202         // only set if the cam is in the active list? Or add it otherwise?
1203         if (!FindCamera(cam)){
1204                 AddCamera(cam);
1205                 if (cam) std::cout << "Added cam " << cam->GetName() << std::endl;
1206         } 
1207
1208         m_active_camera = cam;
1209 }
1210
1211 void KX_Scene::SetCameraOnTop(KX_Camera* cam)
1212 {
1213         if (!FindCamera(cam)){
1214                 // adding is always done at the back, so that's all that needs to be done
1215                 AddCamera(cam);
1216                 if (cam) std::cout << "Added cam " << cam->GetName() << std::endl;
1217         } else {
1218                 m_cameras.remove(cam);
1219                 m_cameras.push_back(cam);
1220         }
1221 }
1222
1223
1224 void KX_Scene::UpdateMeshTransformations()
1225 {
1226         // do this incrementally in the future
1227         for (int i = 0; i < m_objectlist->GetCount(); i++)
1228         {
1229                 KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
1230                 gameobj->GetOpenGLMatrix();
1231         }
1232 }
1233
1234 void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam, int layer)
1235 {
1236         int intersect = KX_Camera::INTERSECT;
1237         KX_GameObject *gameobj = node->Client()?(KX_GameObject*) node->Client()->GetSGClientObject():NULL;
1238         bool visible = (gameobj && gameobj->GetVisible() && (!layer || (gameobj->GetLayer() & layer)));
1239         bool dotest = visible || node->Left() || node->Right();
1240
1241         /* If the camera is inside the box, assume intersect. */
1242         if (dotest && !node->inside( cam->NodeGetWorldPosition()))
1243         {
1244                 MT_Scalar radius = node->Radius();
1245                 MT_Point3 center = node->Center();
1246                 
1247                 intersect =  cam->SphereInsideFrustum(center, radius); 
1248                 
1249                 if (intersect == KX_Camera::INTERSECT)
1250                 {
1251                         MT_Point3 box[8];
1252                         node->get(box);
1253                         intersect = cam->BoxInsideFrustum(box);
1254                 }
1255         }
1256
1257         switch (intersect)
1258         {
1259                 case KX_Camera::OUTSIDE:
1260                         MarkSubTreeVisible(node, rasty, false, cam);
1261                         break;
1262                 case KX_Camera::INTERSECT:
1263                         if (gameobj)
1264                                 MarkVisible(rasty, gameobj, cam, layer);
1265                         if (node->Left())
1266                                 MarkVisible(node->Left(), rasty, cam, layer);
1267                         if (node->Right())
1268                                 MarkVisible(node->Right(), rasty, cam, layer);
1269                         break;
1270                 case KX_Camera::INSIDE:
1271                         MarkSubTreeVisible(node, rasty, true, cam, layer);
1272                         break;
1273         }
1274 }
1275
1276 void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera* cam, int layer)
1277 {
1278         if (node->Client())
1279         {
1280                 KX_GameObject *gameobj = (KX_GameObject*) node->Client()->GetSGClientObject();
1281                 if (gameobj->GetVisible())
1282                 {
1283                         if (visible)
1284                         {
1285                                 int nummeshes = gameobj->GetMeshCount();
1286                                 
1287                                 // this adds the vertices to the display list
1288                                 for (int m=0;m<nummeshes;m++)
1289                                         (gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode());
1290                         }
1291
1292                         gameobj->SetCulled(!visible);
1293                         gameobj->UpdateBuckets(false);
1294                 }
1295         }
1296         if (node->Left())
1297                 MarkSubTreeVisible(node->Left(), rasty, visible, cam, layer);
1298         if (node->Right())
1299                 MarkSubTreeVisible(node->Right(), rasty, visible, cam, layer);
1300 }
1301
1302 void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera*  cam,int layer)
1303 {
1304         // User (Python/Actuator) has forced object invisible...
1305         if (!gameobj->GetSGNode() || !gameobj->GetVisible())
1306                 return;
1307         
1308         // Shadow lamp layers
1309         if(layer && !(gameobj->GetLayer() & layer)) {
1310                 gameobj->SetCulled(true);
1311                 gameobj->UpdateBuckets(false);
1312                 return;
1313         }
1314
1315         // If Frustum culling is off, the object is always visible.
1316         bool vis = !cam->GetFrustumCulling();
1317         
1318         // If the camera is inside this node, then the object is visible.
1319         if (!vis)
1320         {
1321                 vis = gameobj->GetSGNode()->inside( cam->GetCameraLocation() );
1322         }
1323                 
1324         // Test the object's bound sphere against the view frustum.
1325         if (!vis)
1326         {
1327                 MT_Vector3 scale = gameobj->GetSGNode()->GetWorldScaling();
1328                 MT_Scalar radius = fabs(scale[scale.closestAxis()] * gameobj->GetSGNode()->Radius());
1329                 switch (cam->SphereInsideFrustum(gameobj->NodeGetWorldPosition(), radius))
1330                 {
1331                         case KX_Camera::INSIDE:
1332                                 vis = true;
1333                                 break;
1334                         case KX_Camera::OUTSIDE:
1335                                 vis = false;
1336                                 break;
1337                         case KX_Camera::INTERSECT:
1338                                 // Test the object's bound box against the view frustum.
1339                                 MT_Point3 box[8];
1340                                 gameobj->GetSGNode()->getBBox(box); 
1341                                 vis = cam->BoxInsideFrustum(box) != KX_Camera::OUTSIDE;
1342                                 break;
1343                 }
1344         }
1345         
1346         if (vis)
1347         {
1348                 int nummeshes = gameobj->GetMeshCount();
1349                 
1350                 for (int m=0;m<nummeshes;m++)
1351                 {
1352                         // this adds the vertices to the display list
1353                         (gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode());
1354                 }
1355                 // Visibility/ non-visibility are marked
1356                 // elsewhere now.
1357                 gameobj->SetCulled(false);
1358                 gameobj->UpdateBuckets(false);
1359         } else {
1360                 gameobj->SetCulled(true);
1361                 gameobj->UpdateBuckets(false);
1362         }
1363 }
1364
1365 void KX_Scene::PhysicsCullingCallback(KX_ClientObjectInfo* objectInfo, void* cullingInfo)
1366 {
1367         KX_GameObject* gameobj = objectInfo->m_gameobject;
1368         if (!gameobj->GetVisible())
1369                 // ideally, invisible objects should be removed from the culling tree temporarily
1370                 return;
1371         if(((CullingInfo*)cullingInfo)->m_layer && !(gameobj->GetLayer() & ((CullingInfo*)cullingInfo)->m_layer))
1372                 // used for shadow: object is not in shadow layer
1373                 return;
1374
1375         // make object visible
1376         gameobj->SetCulled(false);
1377         gameobj->UpdateBuckets(false);
1378 }
1379
1380 void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int layer)
1381 {
1382         bool dbvt_culling = false;
1383         if (m_dbvt_culling) 
1384         {
1385                 // test culling through Bullet
1386                 PHY__Vector4 planes[6];
1387                 // get the clip planes
1388                 MT_Vector4* cplanes = cam->GetNormalizedClipPlanes();
1389                 // and convert
1390                 planes[0].setValue(cplanes[4].getValue());      // near
1391                 planes[1].setValue(cplanes[5].getValue());      // far
1392                 planes[2].setValue(cplanes[0].getValue());      // left
1393                 planes[3].setValue(cplanes[1].getValue());      // right
1394                 planes[4].setValue(cplanes[2].getValue());      // top
1395                 planes[5].setValue(cplanes[3].getValue());      // bottom
1396                 CullingInfo info(layer);
1397                 dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5,m_dbvt_occlusion_res);
1398         }
1399         if (!dbvt_culling) {
1400                 // the physics engine couldn't help us, do it the hard way
1401                 for (int i = 0; i < m_objectlist->GetCount(); i++)
1402                 {
1403                         MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer);
1404                 }
1405         }
1406 }
1407
1408 // logic stuff
1409 void KX_Scene::LogicBeginFrame(double curtime)
1410 {
1411         // have a look at temp objects ...
1412         int lastobj = m_tempObjectList->GetCount() - 1;
1413         
1414         for (int i = lastobj; i >= 0; i--)
1415         {
1416                 CValue* objval = m_tempObjectList->GetValue(i);
1417                 CFloatValue* propval = (CFloatValue*) objval->GetProperty("::timebomb");
1418                 
1419                 if (propval)
1420                 {
1421                         float timeleft = propval->GetNumber() - 1.0/KX_KetsjiEngine::GetTicRate();
1422                         
1423                         if (timeleft > 0)
1424                         {
1425                                 propval->SetFloat(timeleft);
1426                         }
1427                         else
1428                         {
1429                                 DelayedRemoveObject(objval);
1430                                 // remove obj
1431                         }
1432                 }
1433                 else
1434                 {
1435                         // all object is the tempObjectList should have a clock
1436                 }
1437         }
1438         m_logicmgr->BeginFrame(curtime, 1.0/KX_KetsjiEngine::GetTicRate());
1439 }
1440
1441
1442
1443 void KX_Scene::LogicUpdateFrame(double curtime, bool frame)
1444 {
1445         m_logicmgr->UpdateFrame(curtime, frame);
1446 }
1447
1448
1449
1450 void KX_Scene::LogicEndFrame()
1451 {
1452         m_logicmgr->EndFrame();
1453         int numobj = m_euthanasyobjects->GetCount();
1454
1455         KX_GameObject* obj;
1456
1457         while ((numobj = m_euthanasyobjects->GetCount()) > 0)
1458         {
1459                 // remove the object from this list to make sure we will not hit it again
1460                 obj = (KX_GameObject*)m_euthanasyobjects->GetValue(numobj-1);
1461                 m_euthanasyobjects->Remove(numobj-1);
1462                 obj->Release();
1463                 RemoveObject(obj);
1464         }
1465 }
1466
1467
1468
1469 /**
1470   * UpdateParents: SceneGraph transformation update.
1471   */
1472 void KX_Scene::UpdateParents(double curtime)
1473 {
1474         // we use the SG dynamic list
1475         SG_Node* node;
1476
1477         while ((node = SG_Node::GetNextScheduled(m_sghead)) != NULL)
1478         {
1479                 node->UpdateWorldData(curtime);
1480         }
1481
1482         //for (int i=0; i<GetRootParentList()->GetCount(); i++)
1483         //{
1484         //      KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i);
1485         //      parentobj->NodeUpdateGS(curtime);
1486         //}
1487
1488         // the list must be empty here
1489         assert(m_sghead.Empty());
1490         // some nodes may be ready for reschedule, move them to schedule list for next time
1491         while ((node = SG_Node::GetNextRescheduled(m_sghead)) != NULL)
1492         {
1493                 node->Schedule(m_sghead);
1494         }
1495 }
1496
1497
1498 RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat, bool &bucketCreated)
1499 {
1500         return m_bucketmanager->FindBucket(polymat, bucketCreated);
1501 }
1502
1503
1504
1505 void KX_Scene::RenderBuckets(const MT_Transform & cameratransform,
1506                                                          class RAS_IRasterizer* rasty,
1507                                                          class RAS_IRenderTools* rendertools)
1508 {
1509         m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools);
1510         KX_BlenderMaterial::EndFrame();
1511 }
1512
1513 void KX_Scene::UpdateObjectActivity(void) 
1514 {
1515         if (m_activity_culling) {
1516                 /* determine the activity criterium and set objects accordingly */
1517                 int i=0;
1518                 
1519                 MT_Point3 camloc = GetActiveCamera()->NodeGetWorldPosition(); //GetCameraLocation();
1520                 
1521                 for (i=0;i<GetObjectList()->GetCount();i++)
1522                 {
1523                         KX_GameObject* ob = (KX_GameObject*) GetObjectList()->GetValue(i);
1524                         
1525                         if (!ob->GetIgnoreActivityCulling()) {
1526                                 /* Simple test: more than 10 away from the camera, count
1527                                  * Manhattan distance. */
1528                                 MT_Point3 obpos = ob->NodeGetWorldPosition();
1529                                 
1530                                 if ( (fabs(camloc[0] - obpos[0]) > m_activity_box_radius)
1531                                          || (fabs(camloc[1] - obpos[1]) > m_activity_box_radius)
1532                                          || (fabs(camloc[2] - obpos[2]) > m_activity_box_radius) )
1533                                 {                       
1534                                         ob->Suspend();
1535                                 } else {
1536                                         ob->Resume();
1537                                 }
1538                         }
1539                 }               
1540         }
1541 }
1542
1543 void KX_Scene::SetActivityCullingRadius(float f)
1544 {
1545         if (f < 0.5)
1546                 f = 0.5;
1547         m_activity_box_radius = f;
1548 }
1549         
1550 NG_NetworkDeviceInterface* KX_Scene::GetNetworkDeviceInterface()
1551 {
1552         return m_networkDeviceInterface;
1553 }
1554
1555 NG_NetworkScene* KX_Scene::GetNetworkScene()
1556 {
1557         return m_networkScene;
1558 }
1559
1560 void KX_Scene::SetNetworkDeviceInterface(NG_NetworkDeviceInterface* newInterface)
1561 {
1562         m_networkDeviceInterface = newInterface;
1563 }
1564
1565 void KX_Scene::SetNetworkScene(NG_NetworkScene *newScene)
1566 {
1567         m_networkScene = newScene;
1568 }
1569
1570
1571 void    KX_Scene::SetGravity(const MT_Vector3& gravity)
1572 {
1573         GetPhysicsEnvironment()->setGravity(gravity[0],gravity[1],gravity[2]);
1574 }
1575
1576 void KX_Scene::SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter)
1577 {
1578         m_sceneConverter = sceneConverter;
1579 }
1580
1581 void KX_Scene::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* physEnv)
1582 {
1583         m_physicsEnvironment = physEnv;
1584
1585         KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, physEnv);
1586         m_logicmgr->RegisterEventManager(touchmgr);
1587         return;
1588 }
1589  
1590 void KX_Scene::setSuspendedTime(double suspendedtime)
1591 {
1592         m_suspendedtime = suspendedtime;
1593 }
1594 double KX_Scene::getSuspendedTime()
1595 {
1596         return m_suspendedtime;
1597 }
1598 void KX_Scene::setSuspendedDelta(double suspendeddelta)
1599 {
1600         m_suspendeddelta = suspendeddelta;
1601 }
1602 double KX_Scene::getSuspendedDelta()
1603 {
1604         return m_suspendeddelta;
1605 }
1606
1607 //----------------------------------------------------------------------------
1608 //Python
1609
1610 PyTypeObject KX_Scene::Type = {
1611         PyVarObject_HEAD_INIT(NULL, 0)
1612         "KX_Scene",
1613         sizeof(PyObjectPlus_Proxy),
1614         0,
1615         py_base_dealloc,
1616         0,
1617         0,
1618         0,
1619         0,
1620         py_base_repr,
1621         0,
1622         &Sequence,
1623         &Mapping,
1624         0,0,0,0,0,0,
1625         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1626         0,0,0,0,0,0,0,
1627         Methods,
1628         0,
1629         0,
1630         &CValue::Type,
1631         0,0,0,0,0,0,
1632         py_base_new
1633 };
1634
1635 PyMethodDef KX_Scene::Methods[] = {
1636         KX_PYMETHODTABLE(KX_Scene, addObject),
1637         
1638         /* dict style access */
1639         KX_PYMETHODTABLE(KX_Scene, get),
1640         
1641         {NULL,NULL} //Sentinel
1642 };
1643 static PyObject *Map_GetItem(PyObject *self_v, PyObject *item)
1644 {
1645         KX_Scene* self= static_cast<KX_Scene*>BGE_PROXY_REF(self_v);
1646         const char *attr_str= _PyUnicode_AsString(item);
1647         PyObject* pyconvert;
1648         
1649         if (self==NULL) {
1650                 PyErr_SetString(PyExc_SystemError, "val = scene[key]: KX_Scene, "BGE_PROXY_ERROR_MSG);
1651                 return NULL;
1652         }
1653         
1654         if (self->m_attr_dict && (pyconvert=PyDict_GetItem(self->m_attr_dict, item))) {
1655                 
1656                 if (attr_str)
1657                         PyErr_Clear();
1658                 Py_INCREF(pyconvert);
1659                 return pyconvert;
1660         }
1661         else {
1662                 if(attr_str)    PyErr_Format(PyExc_KeyError, "value = scene[key]: KX_Scene, key \"%s\" does not exist", attr_str);
1663                 else                    PyErr_SetString(PyExc_KeyError, "value = scene[key]: KX_Scene, key does not exist");
1664                 return NULL;
1665         }
1666                 
1667 }
1668
1669 static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
1670 {
1671         KX_Scene* self= static_cast<KX_Scene*>BGE_PROXY_REF(self_v);
1672         const char *attr_str= _PyUnicode_AsString(key);
1673         if(attr_str==NULL)
1674                 PyErr_Clear();
1675         
1676         if (self==NULL) {
1677                 PyErr_SetString(PyExc_SystemError, "scene[key] = value: KX_Scene, "BGE_PROXY_ERROR_MSG);
1678                 return -1;
1679         }
1680         
1681         if (val==NULL) { /* del ob["key"] */
1682                 int del= 0;
1683                 
1684                 if(self->m_attr_dict)
1685                         del |= (PyDict_DelItem(self->m_attr_dict, key)==0) ? 1:0;
1686                 
1687                 if (del==0) {
1688                         if(attr_str)    PyErr_Format(PyExc_KeyError, "scene[key] = value: KX_Scene, key \"%s\" could not be set", attr_str);
1689                         else                    PyErr_SetString(PyExc_KeyError, "del scene[key]: KX_Scene, key could not be deleted");
1690                         return -1;
1691                 }
1692                 else if (self->m_attr_dict) {
1693                         PyErr_Clear(); /* PyDict_DelItem sets an error when it fails */
1694                 }
1695         }
1696         else { /* ob["key"] = value */
1697                 int set = 0;
1698
1699                 if (self->m_attr_dict==NULL) /* lazy init */
1700                         self->m_attr_dict= PyDict_New();
1701                 
1702                 
1703                 if(PyDict_SetItem(self->m_attr_dict, key, val)==0)
1704                         set= 1;
1705                 else
1706                         PyErr_SetString(PyExc_KeyError, "scene[key] = value: KX_Scene, key not be added to internal dictionary");
1707         
1708                 if(set==0)
1709                         return -1; /* pythons error value */
1710                 
1711         }
1712         
1713         return 0; /* success */
1714 }
1715
1716 static int Seq_Contains(PyObject *self_v, PyObject *value)
1717 {
1718         KX_Scene* self= static_cast<KX_Scene*>BGE_PROXY_REF(self_v);
1719         
1720         if (self==NULL) {
1721                 PyErr_SetString(PyExc_SystemError, "val in scene: KX_Scene, "BGE_PROXY_ERROR_MSG);
1722                 return -1;
1723         }
1724         
1725         if (self->m_attr_dict && PyDict_GetItem(self->m_attr_dict, value))
1726                 return 1;
1727         
1728         return 0;
1729 }
1730
1731 PyMappingMethods KX_Scene::Mapping = {
1732         (lenfunc)NULL                                   ,                       /*inquiry mp_length */
1733         (binaryfunc)Map_GetItem,                /*binaryfunc mp_subscript */
1734         (objobjargproc)Map_SetItem,     /*objobjargproc mp_ass_subscript */
1735 };
1736
1737 PySequenceMethods KX_Scene::Sequence = {
1738         NULL,           /* Cant set the len otherwise it can evaluate as false */
1739         NULL,           /* sq_concat */
1740         NULL,           /* sq_repeat */
1741         NULL,           /* sq_item */
1742         NULL,           /* sq_slice */
1743         NULL,           /* sq_ass_item */
1744         NULL,           /* sq_ass_slice */
1745         (objobjproc)Seq_Contains,       /* sq_contains */
1746 };
1747
1748 PyObject* KX_Scene::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
1749 {
1750         KX_Scene* self= static_cast<KX_Scene*>(self_v);
1751         return PyUnicode_FromString(self->GetName().ReadPtr());
1752 }
1753
1754 PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
1755 {
1756         KX_Scene* self= static_cast<KX_Scene*>(self_v);
1757         return self->GetObjectList()->GetProxy();
1758 }
1759
1760 PyObject* KX_Scene::pyattr_get_objects_inactive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
1761 {
1762         KX_Scene* self= static_cast<KX_Scene*>(self_v);
1763         return self->GetInactiveList()->GetProxy();
1764 }
1765
1766 PyObject* KX_Scene::pyattr_get_lights(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
1767 {
1768         KX_Scene* self= static_cast<KX_Scene*>(self_v);
1769         return self->GetLightList()->GetProxy();
1770 }
1771
1772 PyObject* KX_Scene::pyattr_get_cameras(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
1773 {
1774         /* With refcounts in this case...
1775          * the new CListValue is owned by python, so its possible python holds onto it longer then the BGE
1776          * however this is the same with "scene.objects + []", when you make a copy by adding lists.
1777          */
1778         
1779         KX_Scene* self= static_cast<KX_Scene*>(self_v);
1780         CListValue* clist = new CListValue();
1781         
1782         /* return self->GetCameras()->GetProxy(); */
1783         
1784         list<KX_Camera*>::iterator it = self->GetCameras()->begin();
1785         while (it != self->GetCameras()->end()) {
1786                 clist->Add((*it)->AddRef());
1787                 it++;
1788         }
1789         
1790         return clist->NewProxy(true);
1791 }
1792
1793 PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
1794 {
1795         KX_Scene* self= static_cast<KX_Scene*>(self_v);
1796         return self->GetActiveCamera()->GetProxy();
1797 }
1798
1799
1800 int KX_Scene::pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
1801 {
1802         KX_Scene* self= static_cast<KX_Scene*>(self_v);
1803         KX_Camera *camOb;
1804         
1805         if (!ConvertPythonToCamera(value, &camOb, false, "scene.active_camera = value: KX_Scene"))
1806                 return PY_SET_ATTR_FAIL;
1807         
1808         self->SetActiveCamera(camOb);
1809         return PY_SET_ATTR_SUCCESS;
1810 }
1811
1812
1813 PyAttributeDef KX_Scene::Attributes[] = {
1814         KX_PYATTRIBUTE_RO_FUNCTION("name",                              KX_Scene, pyattr_get_name),
1815         KX_PYATTRIBUTE_RO_FUNCTION("objects",                   KX_Scene, pyattr_get_objects),
1816         KX_PYATTRIBUTE_RO_FUNCTION("objectsInactive",   KX_Scene, pyattr_get_objects_inactive), KX_PYATTRIBUTE_RO_FUNCTION("lights",                    KX_Scene, pyattr_get_lights),
1817         KX_PYATTRIBUTE_RO_FUNCTION("cameras",                   KX_Scene, pyattr_get_cameras),
1818         KX_PYATTRIBUTE_RO_FUNCTION("lights",                    KX_Scene, pyattr_get_lights),
1819         KX_PYATTRIBUTE_RW_FUNCTION("active_camera",             KX_Scene, pyattr_get_active_camera, pyattr_set_active_camera),
1820         KX_PYATTRIBUTE_BOOL_RO("suspended",                             KX_Scene, m_suspend),
1821         KX_PYATTRIBUTE_BOOL_RO("activity_culling",              KX_Scene, m_activity_culling),
1822         KX_PYATTRIBUTE_FLOAT_RW("activity_culling_radius", 0.5f, FLT_MAX, KX_Scene, m_activity_box_radius),
1823         KX_PYATTRIBUTE_BOOL_RO("dbvt_culling",                  KX_Scene, m_dbvt_culling),
1824         { NULL }        //Sentinel
1825 };
1826
1827 KX_PYMETHODDEF_DOC(KX_Scene, addObject,
1828 "addObject(object, other, time=0)\n"
1829 "Returns the added object.\n")
1830 {
1831         PyObject *pyob, *pyother;
1832         KX_GameObject *ob, *other;
1833
1834         int time = 0;
1835
1836         if (!PyArg_ParseTuple(args, "OO|i:addObject", &pyob, &pyother, &time))
1837                 return NULL;
1838
1839         if (    !ConvertPythonToGameObject(pyob, &ob, false, "scene.addObject(object, other, time): KX_Scene (first argument)") ||
1840                         !ConvertPythonToGameObject(pyother, &other, false, "scene.addObject(object, other, time): KX_Scene (second argument)") )
1841                 return NULL;
1842
1843
1844         SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time);
1845         
1846         // release here because AddReplicaObject AddRef's
1847         // the object is added to the scene so we dont want python to own a reference
1848         replica->Release();
1849         return replica->GetProxy();
1850 }
1851
1852 /* Matches python dict.get(key, [default]) */
1853 KX_PYMETHODDEF_DOC(KX_Scene, get, "")
1854 {
1855         PyObject *key;
1856         PyObject* def = Py_None;
1857         PyObject* ret;
1858
1859         if (!PyArg_ParseTuple(args, "O|O:get", &key, &def))
1860                 return NULL;
1861         
1862         if (m_attr_dict && (ret=PyDict_GetItem(m_attr_dict, key))) {
1863                 Py_INCREF(ret);
1864                 return ret;
1865         }
1866         
1867         Py_INCREF(def);
1868         return def;
1869 }