svn merge -r 15800:15973 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[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
36 #include "KX_Scene.h"
37 #include "MT_assert.h"
38
39 #include "KX_KetsjiEngine.h"
40 #include "KX_BlenderMaterial.h"
41 #include "RAS_IPolygonMaterial.h"
42 #include "ListValue.h"
43 #include "SCA_LogicManager.h"
44 #include "SCA_TimeEventManager.h"
45 #include "SCA_AlwaysEventManager.h"
46 #include "SCA_RandomEventManager.h"
47 #include "KX_RayEventManager.h"
48 #include "KX_TouchEventManager.h"
49 #include "SCA_KeyboardManager.h"
50 #include "SCA_MouseManager.h"
51 #include "SCA_PropertyEventManager.h"
52 #include "SCA_ActuatorEventManager.h"
53 #include "KX_Camera.h"
54 #include "SCA_JoystickManager.h"
55
56 #include "RAS_MeshObject.h"
57 #include "BL_SkinMeshObject.h"
58
59 #include "RAS_IRasterizer.h"
60 #include "RAS_BucketManager.h"
61
62 #include "FloatValue.h"
63 #include "SCA_IController.h"
64 #include "SCA_IActuator.h"
65 #include "SG_Node.h"
66 #include "SYS_System.h"
67 #include "SG_Controller.h"
68 #include "SG_IObject.h"
69 #include "SG_Tree.h"
70 #include "DNA_group_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 "KX_BlenderSceneConverter.h"
80
81 #include "BL_ShapeDeformer.h"
82 #include "BL_DeformableGameObject.h"
83
84 // to get USE_BULLET!
85 #include "KX_ConvertPhysicsObject.h"
86
87 #ifdef USE_BULLET
88 #include "CcdPhysicsEnvironment.h"
89 #include "CcdPhysicsController.h"
90 #endif
91
92 void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
93 {
94         KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
95
96         if(replica)
97                 replica->Release();
98
99         return (void*)replica;
100 }
101
102 void* KX_SceneDestructionFunc(SG_IObject* node,void* gameobj,void* scene)
103 {
104         ((KX_Scene*)scene)->RemoveNodeDestructObject(node,(KX_GameObject*)gameobj);
105
106         return NULL;
107 };
108
109 SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(KX_SceneReplicationFunc,KX_SceneDestructionFunc,KX_GameObject::UpdateTransformFunc);
110
111 // temporarily var until there is a button in the userinterface
112 // (defined in KX_PythonInit.cpp)
113 extern bool gUseVisibilityTemp;
114
115 KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
116                                    class SCA_IInputDevice* mousedevice,
117                                    class NG_NetworkDeviceInterface *ndi,
118                                    class SND_IAudioDevice* adi,
119                                    const STR_String& sceneName): 
120         PyObjectPlus(&KX_Scene::Type),
121         m_keyboardmgr(NULL),
122         m_mousemgr(NULL),
123         m_sceneConverter(NULL),
124         m_physicsEnvironment(0),
125         m_sceneName(sceneName),
126         m_adi(adi),
127         m_networkDeviceInterface(ndi),
128         m_active_camera(NULL),
129         m_ueberExecutionPriority(0)
130 {
131         m_suspendedtime = 0.0;
132         m_suspendeddelta = 0.0;
133
134         m_activity_culling = false;
135         m_suspend = false;
136         m_isclearingZbuffer = true;
137         m_tempObjectList = new CListValue();
138         m_objectlist = new CListValue();
139         m_parentlist = new CListValue();
140         m_lightlist= new CListValue();
141         m_inactivelist = new CListValue();
142         m_euthanasyobjects = new CListValue();
143         m_delayReleaseObjects = new CListValue();
144
145         m_logicmgr = new SCA_LogicManager();
146         
147         m_timemgr = new SCA_TimeEventManager(m_logicmgr);
148         m_keyboardmgr = new SCA_KeyboardManager(m_logicmgr,keyboarddevice);
149         m_mousemgr = new SCA_MouseManager(m_logicmgr,mousedevice);
150         
151         SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr);
152         SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr);
153         SCA_ActuatorEventManager* actmgr = new SCA_ActuatorEventManager(m_logicmgr);
154         SCA_RandomEventManager* rndmgr = new SCA_RandomEventManager(m_logicmgr);
155         KX_RayEventManager* raymgr = new KX_RayEventManager(m_logicmgr);
156
157         KX_NetworkEventManager* netmgr = new KX_NetworkEventManager(m_logicmgr, ndi);
158         
159         SCA_JoystickManager *joymgr     = new SCA_JoystickManager(m_logicmgr);
160
161         m_logicmgr->RegisterEventManager(alwaysmgr);
162         m_logicmgr->RegisterEventManager(propmgr);
163         m_logicmgr->RegisterEventManager(actmgr);
164         m_logicmgr->RegisterEventManager(m_keyboardmgr);
165         m_logicmgr->RegisterEventManager(m_mousemgr);
166         m_logicmgr->RegisterEventManager(m_timemgr);
167         m_logicmgr->RegisterEventManager(rndmgr);
168         m_logicmgr->RegisterEventManager(raymgr);
169         m_logicmgr->RegisterEventManager(netmgr);
170         m_logicmgr->RegisterEventManager(joymgr);
171
172         m_soundScene = new SND_Scene(adi);
173         MT_assert (m_networkDeviceInterface != NULL);
174         m_networkScene = new NG_NetworkScene(m_networkDeviceInterface);
175         
176         m_rootnode = NULL;
177
178         m_bucketmanager=new RAS_BucketManager();
179
180         m_canvasDesignWidth = 0;
181         m_canvasDesignHeight = 0;
182         
183         m_attrlist = PyDict_New(); /* new ref */
184 }
185
186
187
188 KX_Scene::~KX_Scene()
189 {
190         // The release of debug properties used to be in SCA_IScene::~SCA_IScene
191         // It's still there but we remove all properties here otherwise some
192         // reference might be hanging and causing late release of objects
193         RemoveAllDebugProperties();
194
195         while (GetRootParentList()->GetCount() > 0) 
196         {
197                 KX_GameObject* parentobj = (KX_GameObject*) GetRootParentList()->GetValue(0);
198                 this->RemoveObject(parentobj);
199         }
200
201         if(m_objectlist)
202                 m_objectlist->Release();
203
204         if (m_parentlist)
205                 m_parentlist->Release();
206         
207         if (m_inactivelist)
208                 m_inactivelist->Release();
209
210         if (m_lightlist)
211                 m_lightlist->Release();
212         
213         if (m_tempObjectList)
214                 m_tempObjectList->Release();
215
216         if (m_euthanasyobjects)
217                 m_euthanasyobjects->Release();
218         if (m_delayReleaseObjects)
219                 m_delayReleaseObjects->Release();
220
221         if (m_logicmgr)
222                 delete m_logicmgr;
223
224         if (m_physicsEnvironment)
225                 delete m_physicsEnvironment;
226
227         if (m_soundScene)
228                 delete m_soundScene;
229
230         if (m_networkScene)
231                 delete m_networkScene;
232         
233         if (m_bucketmanager)
234         {
235                 delete m_bucketmanager;
236         }
237 #ifdef USE_BULLET
238         // This is a fix for memory leaks in bullet: the collision shapes is not destroyed 
239         // when the physical controllers are destroyed. The reason is that shapes are shared
240         // between replicas of an object. There is no reference count in Bullet so the
241         // only workaround that does not involve changes in Bullet is to save in this array
242         // the list of shapes that are created when the scene is created (see KX_ConvertPhysicsObjects.cpp)
243         class btCollisionShape* shape;
244         class btTriangleMeshShape* meshShape;
245         vector<class btCollisionShape*>::iterator it = m_shapes.begin();
246         while (it != m_shapes.end()) {
247                 shape = *it;
248                 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
249                 {
250                         meshShape = static_cast<btTriangleMeshShape*>(shape);
251                         // shapes based on meshes use an interface that contains the vertices.
252                         // Again the idea is to be able to share the interface between shapes but
253                         // this is not used in Blender: each base object will have its own interface 
254                         btStridingMeshInterface* meshInterface = meshShape->getMeshInterface();
255                         if (meshInterface)
256                                 delete meshInterface;
257                 }
258                 delete shape;
259                 it++;
260         }
261 #endif
262         //Py_DECREF(m_attrlist);
263 }
264
265 void KX_Scene::AddShape(class btCollisionShape*shape)
266 {
267         m_shapes.push_back(shape);
268 }
269
270
271 void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
272 {
273         m_projectionmat = pmat;
274 }
275
276
277
278 RAS_BucketManager* KX_Scene::GetBucketManager()
279 {
280         return m_bucketmanager;
281 }
282
283
284
285 CListValue* KX_Scene::GetObjectList()
286 {
287         return m_objectlist;
288 }
289
290
291
292 CListValue* KX_Scene::GetRootParentList()
293 {
294         return m_parentlist;
295 }
296
297 CListValue* KX_Scene::GetInactiveList()
298 {
299         return m_inactivelist;
300 }
301
302
303
304 CListValue* KX_Scene::GetLightList()
305 {
306         return m_lightlist;
307 }
308
309 SCA_LogicManager* KX_Scene::GetLogicManager()
310 {
311         return m_logicmgr;
312 }
313
314 SCA_TimeEventManager* KX_Scene::GetTimeEventManager()
315 {
316         return m_timemgr;
317 }
318
319
320
321  
322 list<class KX_Camera*>* KX_Scene::GetCameras()
323 {
324         return &m_cameras;
325 }
326
327
328
329 void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings)
330 {
331         m_frame_settings = frame_settings;
332 };
333
334 /**
335  * Return a const reference to the framing 
336  * type set by the above call.
337  * The contents are not guarenteed to be sensible
338  * if you don't call the above function.
339  */
340 const RAS_FrameSettings& KX_Scene::GetFramingType() const 
341 {
342         return m_frame_settings;
343 };      
344
345
346
347 /**
348  * Store the current scene's viewport on the 
349  * game engine canvas.
350  */
351 void KX_Scene::SetSceneViewport(const RAS_Rect &viewport)
352 {
353         m_viewport = viewport;
354 }
355
356
357
358 const RAS_Rect& KX_Scene::GetSceneViewport() const 
359 {
360         return m_viewport;
361 }
362
363
364
365 void KX_Scene::SetWorldInfo(class KX_WorldInfo* worldinfo)
366 {
367         m_worldinfo = worldinfo;
368 }
369
370
371
372 class KX_WorldInfo* KX_Scene::GetWorldInfo()
373 {
374         return m_worldinfo;
375 }
376
377
378
379 SND_Scene* KX_Scene::GetSoundScene()
380 {
381         return m_soundScene;
382 }
383
384 const STR_String& KX_Scene::GetName()
385 {
386         return m_sceneName;
387 }
388
389
390 void KX_Scene::Suspend()
391 {
392         m_suspend = true;
393 }
394
395 void KX_Scene::Resume()
396 {
397         m_suspend = false;
398 }
399
400 void KX_Scene::SetActivityCulling(bool b)
401 {
402         m_activity_culling = b;
403 }
404
405 bool KX_Scene::IsSuspended()
406 {
407         return m_suspend;
408 }
409
410 bool KX_Scene::IsClearingZBuffer()
411 {
412         return m_isclearingZbuffer;
413 }
414
415 void KX_Scene::EnableZBufferClearing(bool isclearingZbuffer)
416 {
417         m_isclearingZbuffer = isclearingZbuffer;
418 }
419
420 void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj)
421 {
422         KX_GameObject* orgobj = (KX_GameObject*)gameobj;        
423         if (NewRemoveObject(orgobj) != 0)
424         {
425                 // object is not yet deleted (this can happen when it hangs in an add object actuator
426                 // last object created reference. It's a bad situation, don't know how to fix it exactly
427                 // The least I can do, is remove the reference to the node in the object as the node
428                 // will in any case be deleted. This ensures that the object will not try to use the node
429                 // when it is finally deleted (see KX_GameObject destructor)
430                 orgobj->SetSGNode(NULL);
431         }
432         if (node)
433                 delete node;
434 }
435
436 KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CValue* gameobj)
437 {
438         // for group duplication, limit the duplication of the hierarchy to the
439         // objects that are part of the group. 
440         if (!IsObjectInGroup(gameobj))
441                 return NULL;
442         
443         KX_GameObject* orgobj = (KX_GameObject*)gameobj;
444         KX_GameObject* newobj = (KX_GameObject*)orgobj->GetReplica();
445         m_map_gameobject_to_replica.insert(orgobj, newobj);
446
447         // also register 'timers' (time properties) of the replica
448         int numprops = newobj->GetPropertyCount();
449
450         for (int i = 0; i < numprops; i++)
451         {
452                 CValue* prop = newobj->GetProperty(i);
453
454                 if (prop->GetProperty("timer"))
455                         this->m_timemgr->AddTimeProperty(prop);
456         }
457
458         if (node)
459         {
460                 newobj->SetSGNode((SG_Node*)node);
461         }
462         else
463         {
464                 m_rootnode = new SG_Node(newobj,this,KX_Scene::m_callbacks);
465         
466                 // this fixes part of the scaling-added object bug
467                 SG_Node* orgnode = orgobj->GetSGNode();
468                 m_rootnode->SetLocalScale(orgnode->GetLocalScale());
469                 m_rootnode->SetLocalPosition(orgnode->GetLocalPosition());
470                 m_rootnode->SetLocalOrientation(orgnode->GetLocalOrientation());
471
472                 // define the relationship between this node and it's parent.
473                 KX_NormalParentRelation * parent_relation = 
474                         KX_NormalParentRelation::New();
475                 m_rootnode->SetParentRelation(parent_relation);
476
477                 newobj->SetSGNode(m_rootnode);
478         }
479         
480         SG_IObject* replicanode = newobj->GetSGNode();
481 //      SG_Node* rootnode = (replicanode == m_rootnode ? NULL : m_rootnode);
482
483         replicanode->SetSGClientObject(newobj);
484
485         // this is the list of object that are send to the graphics pipeline
486         m_objectlist->Add(newobj->AddRef());
487         newobj->Bucketize();
488
489         // logic cannot be replicated, until the whole hierarchy is replicated.
490         m_logicHierarchicalGameObjects.push_back(newobj);
491         //replicate controllers of this node
492         SGControllerList        scenegraphcontrollers = orgobj->GetSGNode()->GetSGControllerList();
493         replicanode->RemoveAllControllers();
494         SGControllerList::iterator cit;
495         //int numcont = scenegraphcontrollers.size();
496         
497         for (cit = scenegraphcontrollers.begin();!(cit==scenegraphcontrollers.end());++cit)
498         {
499                 // controller replication is quite complicated
500                 // only replicate ipo and physics controller for now
501
502                 SG_Controller* replicacontroller = (*cit)->GetReplica((SG_Node*) replicanode);
503                 if (replicacontroller)
504                 {
505                         replicacontroller->SetObject(replicanode);
506                         replicanode->AddSGController(replicacontroller);
507                 }
508         }
509         
510         return newobj;
511 }
512
513
514
515 // before calling this method KX_Scene::ReplicateLogic(), make sure to
516 // have called 'GameObject::ReParentLogic' for each object this
517 // hierarchy that's because first ALL bricks must exist in the new
518 // replica of the hierarchy in order to make cross-links work properly
519 // !
520 // It is VERY important that the order of sensors and actuators in
521 // the replicated object is preserved: it is is used to reconnect the logic.
522 // This method is more robust then using the bricks name in case of complex 
523 // group replication. The replication of logic bricks is done in 
524 // SCA_IObject::ReParentLogic(), make sure it preserves the order of the bricks.
525 void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
526 {
527         // also relink the controller to sensors/actuators
528         SCA_ControllerList& controllers = newobj->GetControllers();
529         //SCA_SensorList&     sensors     = newobj->GetSensors();
530         //SCA_ActuatorList&   actuators   = newobj->GetActuators();
531
532         for (SCA_ControllerList::iterator itc = controllers.begin(); !(itc==controllers.end());itc++)
533         {
534                 SCA_IController* cont = (*itc);
535                 cont->SetUeberExecutePriority(m_ueberExecutionPriority);
536                 vector<SCA_ISensor*> linkedsensors = cont->GetLinkedSensors();
537                 vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators();
538
539                 // disconnect the sensors and actuators
540                 cont->UnlinkAllSensors();
541                 cont->UnlinkAllActuators();
542                 
543                 // now relink each sensor
544                 for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++)
545                 {
546                         SCA_ISensor* oldsensor = (*its);
547                         SCA_IObject* oldsensorobj = oldsensor->GetParent();
548                         SCA_IObject* newsensorobj = NULL;
549                 
550                         // the original owner of the sensor has been replicated?
551                         void **h_obj = m_map_gameobject_to_replica[oldsensorobj];
552                         if (h_obj)
553                                 newsensorobj = (SCA_IObject*)(*h_obj);
554                         if (!newsensorobj)
555                         {
556                                 // no, then the sensor points outside the hierachy, keep it the same
557                                 if (m_objectlist->SearchValue(oldsensorobj))
558                                         // only replicate links that points to active objects
559                                         m_logicmgr->RegisterToSensor(cont,oldsensor);
560                         }
561                         else
562                         {
563                                 // yes, then the new sensor has the same position
564                                 SCA_SensorList& sensorlist = oldsensorobj->GetSensors();
565                                 SCA_SensorList::iterator sit;
566                                 SCA_ISensor* newsensor = NULL;
567                                 int sensorpos;
568
569                                 for (sensorpos=0, sit=sensorlist.begin(); sit!=sensorlist.end(); sit++, sensorpos++)
570                                 {
571                                         if ((*sit) == oldsensor) 
572                                         {
573                                                 newsensor = newsensorobj->GetSensors().at(sensorpos);
574                                                 break;
575                                         }
576                                 }
577                                 assert(newsensor != NULL);
578                                 m_logicmgr->RegisterToSensor(cont,newsensor);
579                         }
580                 }
581                 
582                 // now relink each actuator
583                 for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());ita++)
584                 {
585                         SCA_IActuator* oldactuator = (*ita);
586                         SCA_IObject* oldactuatorobj = oldactuator->GetParent();
587                         SCA_IObject* newactuatorobj = NULL;
588
589                         // the original owner of the sensor has been replicated?
590                         void **h_obj = m_map_gameobject_to_replica[oldactuatorobj];
591                         if (h_obj)
592                                 newactuatorobj = (SCA_IObject*)(*h_obj);
593
594                         if (!newactuatorobj)
595                         {
596                                 // no, then the sensor points outside the hierachy, keep it the same
597                                 if (m_objectlist->SearchValue(oldactuatorobj))
598                                         // only replicate links that points to active objects
599                                         m_logicmgr->RegisterToActuator(cont,oldactuator);
600                         }
601                         else
602                         {
603                                 // yes, then the new sensor has the same position
604                                 SCA_ActuatorList& actuatorlist = oldactuatorobj->GetActuators();
605                                 SCA_ActuatorList::iterator ait;
606                                 SCA_IActuator* newactuator = NULL;
607                                 int actuatorpos;
608
609                                 for (actuatorpos=0, ait=actuatorlist.begin(); ait!=actuatorlist.end(); ait++, actuatorpos++)
610                                 {
611                                         if ((*ait) == oldactuator) 
612                                         {
613                                                 newactuator = newactuatorobj->GetActuators().at(actuatorpos);
614                                                 break;
615                                         }
616                                 }
617                                 assert(newactuator != NULL);
618                                 m_logicmgr->RegisterToActuator(cont,newactuator);
619                                 newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
620                         }
621                 }
622         }
623         // ready to set initial state
624         newobj->ResetState();
625 }
626
627 void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
628 {
629         KX_GameObject* groupobj = (KX_GameObject*) obj;
630         KX_GameObject* replica;
631         KX_GameObject* gameobj;
632         Object* blgroupobj = groupobj->GetBlenderObject();
633         Group* group;
634         GroupObject *go;
635         vector<KX_GameObject*> duplilist;
636
637         if (!groupobj->IsDupliGroup() ||
638                 level>MAX_DUPLI_RECUR)
639                 return;
640
641         // we will add one group at a time
642         m_logicHierarchicalGameObjects.clear();
643         m_map_gameobject_to_replica.clear();
644         m_ueberExecutionPriority++;
645         // for groups will do something special: 
646         // we will force the creation of objects to those in the group only
647         // Again, this is match what Blender is doing (it doesn't care of parent relationship)
648         m_groupGameObjects.clear();
649
650         group = blgroupobj->dup_group;
651         for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next) 
652         {
653                 Object* blenderobj = go->ob;
654                 if (blgroupobj == blenderobj)
655                         // this check is also in group_duplilist()
656                         continue;
657                 gameobj = (KX_GameObject*)m_logicmgr->FindGameObjByBlendObj(blenderobj);
658                 if (gameobj == NULL) 
659                 {
660                         // this object has not been converted!!!
661                         // Should not happen as dupli group are created automatically 
662                         continue;
663                 }
664                 if ((blenderobj->lay & group->layer)==0)
665                 {
666                         // object is not visible in the 3D view, will not be instantiated
667                         continue;
668                 }
669                 m_groupGameObjects.insert(gameobj);
670         }
671
672         set<CValue*>::iterator oit;
673         for (oit=m_groupGameObjects.begin(); oit != m_groupGameObjects.end(); oit++)
674         {
675                 gameobj = (KX_GameObject*)(*oit);
676
677                 KX_GameObject *parent = gameobj->GetParent();
678                 if (parent != NULL)
679                 {
680                         parent->Release(); // GetParent() increased the refcount
681
682                         // this object is not a top parent. Either it is the child of another
683                         // object in the group and it will be added automatically when the parent
684                         // is added. Or it is the child of an object outside the group and the group
685                         // is inconsistent, skip it anyway
686                         continue;
687                 }
688                 replica = (KX_GameObject*) AddNodeReplicaObject(NULL,gameobj);
689                 // add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame)
690                 m_parentlist->Add(replica->AddRef());
691
692                 // recurse replication into children nodes
693                 NodeList& children = gameobj->GetSGNode()->GetSGChildren();
694
695                 replica->GetSGNode()->ClearSGChildren();
696                 for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
697                 {
698                         SG_Node* orgnode = (*childit);
699                         SG_Node* childreplicanode = orgnode->GetSGReplica();
700                         if (childreplicanode)
701                                 replica->GetSGNode()->AddChild(childreplicanode);
702                 }
703                 // don't replicate logic now: we assume that the objects in the group can have
704                 // logic relationship, even outside parent relationship
705                 // In order to match 3D view, the position of groupobj is used as a 
706                 // transformation matrix instead of the new position. This means that 
707                 // the group reference point is 0,0,0
708
709                 // get the rootnode's scale
710                 MT_Vector3 newscale = groupobj->NodeGetWorldScaling();
711                 // set the replica's relative scale with the rootnode's scale
712                 replica->NodeSetRelativeScale(newscale);
713
714                 MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation();
715                 replica->NodeSetLocalOrientation(newori);
716
717                 MT_Point3 newpos = groupobj->NodeGetWorldPosition() + 
718                         newscale*(groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldPosition());
719                 replica->NodeSetLocalPosition(newpos);
720
721                 if (replica->GetPhysicsController())
722                 {
723                         // not required, already done in NodeSetLocalOrientation..
724                         //replica->GetPhysicsController()->setPosition(newpos);
725                         //replica->GetPhysicsController()->setOrientation(newori.getRotation());
726                         // Scaling has been set relatively hereabove, this does not 
727                         // set the scaling of the controller. I don't know why it's just the
728                         // relative scale and not the full scale that has to be put here...
729                         replica->GetPhysicsController()->setScaling(newscale);
730                 }
731
732                 replica->GetSGNode()->UpdateWorldData(0);
733                 replica->GetSGNode()->SetBBox(gameobj->GetSGNode()->BBox());
734                 replica->GetSGNode()->SetRadius(gameobj->GetSGNode()->Radius());
735                 // done with replica
736                 replica->Release();
737         }
738
739         // the logic must be replicated first because we need
740         // the new logic bricks before relinking
741         vector<KX_GameObject*>::iterator git;
742         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
743         {
744                 (*git)->ReParentLogic();
745         }
746         
747         //      relink any pointers as necessary, sort of a temporary solution
748         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
749         {
750                 // this will also relink the actuator to objects within the hierarchy
751                 (*git)->Relink(&m_map_gameobject_to_replica);
752                 // add the object in the layer of the parent
753                 (*git)->SetLayer(groupobj->GetLayer());
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         // now replicate logic
823         vector<KX_GameObject*>::iterator git;
824         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
825         {
826                 (*git)->ReParentLogic();
827         }
828         
829         //      relink any pointers as necessary, sort of a temporary solution
830         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
831         {
832                 // this will also relink the actuators in the hierarchy
833                 (*git)->Relink(&m_map_gameobject_to_replica);
834                 // add the object in the layer of the parent
835                 (*git)->SetLayer(parentobj->GetLayer());
836         }
837
838         // replicate crosslinks etc. between logic bricks
839         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
840         {
841                 ReplicateLogic((*git));
842         }
843         
844         MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition();
845         replica->NodeSetLocalPosition(newpos);
846
847         MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
848         replica->NodeSetLocalOrientation(newori);
849         
850         // get the rootnode's scale
851         MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
852
853         // set the replica's relative scale with the rootnode's scale
854         replica->NodeSetRelativeScale(newscale);
855
856         if (replica->GetPhysicsController())
857         {
858                 // not needed, already done in NodeSetLocalPosition()
859                 //replica->GetPhysicsController()->setPosition(newpos);
860                 //replica->GetPhysicsController()->setOrientation(newori.getRotation());
861                 replica->GetPhysicsController()->setScaling(newscale);
862         }
863
864         // here we want to set the relative scale: the rootnode's scale will override all other
865         // scalings, so lets better prepare for it
866
867
868         replica->GetSGNode()->UpdateWorldData(0);
869         replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
870         replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
871         // check if there are objects with dupligroup in the hierarchy
872         vector<KX_GameObject*> duplilist;
873         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
874         {
875                 if ((*git)->IsDupliGroup())
876                 {
877                         // separate list as m_logicHierarchicalGameObjects is also used by DupliGroupRecurse()
878                         duplilist.push_back(*git);
879                 }
880         }
881         for (git = duplilist.begin();!(git==duplilist.end());++git)
882         {
883                 DupliGroupRecurse(*git, 0);
884         }
885         //      don't release replica here because we are returning it, not done with it...
886         return replica;
887 }
888
889
890
891 void KX_Scene::RemoveObject(class CValue* gameobj)
892 {
893         KX_GameObject* newobj = (KX_GameObject*) gameobj;
894
895         // first disconnect child from parent
896         SG_Node* node = newobj->GetSGNode();
897
898         if (node)
899         {
900                 node->DisconnectFromParent();
901
902                 // recursively destruct
903                 node->Destruct();
904         }
905         //no need to do that: the object is destroyed and memory released 
906         //newobj->SetSGNode(0);
907 }
908
909 void KX_Scene::DelayedReleaseObject(CValue* gameobj)
910 {
911         m_delayReleaseObjects->Add(gameobj->AddRef());
912 }
913
914
915 void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
916 {
917         //KX_GameObject* newobj = (KX_GameObject*) gameobj;
918         if (!m_euthanasyobjects->SearchValue(gameobj))
919         {
920                 m_euthanasyobjects->Add(gameobj->AddRef());
921         } 
922 }
923
924
925
926 int KX_Scene::NewRemoveObject(class CValue* gameobj)
927 {
928         int ret;
929         KX_GameObject* newobj = (KX_GameObject*) gameobj;
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->RemoveDestroyedActuator(*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 (m_objectlist->RemoveValue(newobj))
979                 ret = newobj->Release();
980         if (m_tempObjectList->RemoveValue(newobj))
981                 ret = newobj->Release();
982         if (m_parentlist->RemoveValue(newobj))
983                 ret = newobj->Release();
984         if (m_inactivelist->RemoveValue(newobj))
985                 ret = newobj->Release();
986         if (m_euthanasyobjects->RemoveValue(newobj))
987                 ret = newobj->Release();
988                 
989         if (newobj == m_active_camera)
990         {
991                 //no AddRef done on m_active_camera so no Release
992                 //m_active_camera->Release();
993                 m_active_camera = NULL;
994         }
995
996         // in case this is a camera
997         m_cameras.remove((KX_Camera*)newobj);
998
999         if (m_sceneConverter)
1000                 m_sceneConverter->UnregisterGameObject(newobj);
1001         // return value will be 0 if the object is actually deleted (all reference gone)
1002         return ret;
1003 }
1004
1005
1006
1007 void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
1008 {
1009         KX_GameObject* gameobj = static_cast<KX_GameObject*>(obj);
1010         RAS_MeshObject* mesh = static_cast<RAS_MeshObject*>(meshobj);
1011
1012         if(!gameobj || !mesh)
1013         {
1014                 std::cout << "warning: invalid object, mesh will not be replaced" << std::endl;
1015                 return;
1016         }
1017
1018         gameobj->RemoveMeshes();
1019         gameobj->AddMesh(mesh);
1020         
1021         if (gameobj->m_isDeformable)
1022         {
1023                 BL_DeformableGameObject* newobj = static_cast<BL_DeformableGameObject*>( gameobj );
1024                 
1025                 if (newobj->m_pDeformer)
1026                 {
1027                         delete newobj->m_pDeformer;
1028                         newobj->m_pDeformer = NULL;
1029                 }
1030
1031                 if (mesh->m_class == 1) 
1032                 {
1033                         // we must create a new deformer but which one?
1034                         KX_GameObject* parentobj = newobj->GetParent();
1035                         // this always return the original game object (also for replicate)
1036                         Object* blendobj = newobj->GetBlenderObject();
1037                         // object that owns the new mesh
1038                         Object* oldblendobj = static_cast<struct Object*>(m_logicmgr->FindBlendObjByGameMeshName(mesh->GetName()));
1039                         Mesh* blendmesh = mesh->GetMesh();
1040
1041                         bool bHasShapeKey = blendmesh->key != NULL && blendmesh->key->type==KEY_RELATIVE;
1042                         bool bHasDvert = blendmesh->dvert != NULL;
1043                         bool bHasArmature = 
1044                                 parentobj &&                                                            // current parent is armature
1045                                 parentobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE &&
1046                                 oldblendobj &&                                                          // needed for mesh deform
1047                                 blendobj->parent &&                                                     // original object had armature (not sure this test is needed)
1048                                 blendobj->parent->type == OB_ARMATURE && 
1049                                 blendobj->partype==PARSKEL && 
1050                                 blendmesh->dvert!=NULL;                                         // mesh has vertex group
1051                         bool releaseParent = true;
1052
1053                         if (bHasShapeKey)
1054                         {
1055                                 BL_ShapeDeformer* shapeDeformer;
1056                                 if (bHasArmature) 
1057                                 {
1058                                         shapeDeformer = new BL_ShapeDeformer(
1059                                                 newobj,
1060                                                 oldblendobj, blendobj,
1061                                                 static_cast<BL_SkinMeshObject*>(mesh),
1062                                                 true,
1063                                                 static_cast<BL_ArmatureObject*>( parentobj )
1064                                         );
1065                                         releaseParent= false;
1066                                         shapeDeformer->LoadShapeDrivers(blendobj->parent);
1067                                 }
1068                                 else
1069                                 {
1070                                         shapeDeformer = new BL_ShapeDeformer(
1071                                                 newobj,
1072                                                 oldblendobj, blendobj,
1073                                                 static_cast<BL_SkinMeshObject*>(mesh),
1074                                                 false,
1075                                                 NULL
1076                                         );
1077                                 }
1078                                 newobj->m_pDeformer = shapeDeformer;
1079                         }
1080                         else if (bHasArmature) 
1081                         {
1082                                 BL_SkinDeformer* skinDeformer = new BL_SkinDeformer(
1083                                         newobj,
1084                                         oldblendobj, blendobj,
1085                                         static_cast<BL_SkinMeshObject*>(mesh),
1086                                         true,
1087                                         static_cast<BL_ArmatureObject*>( parentobj )
1088                                 );
1089                                 releaseParent= false;
1090                                 newobj->m_pDeformer = skinDeformer;
1091                         }
1092                         else if (bHasDvert)
1093                         {
1094                                 BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(
1095                                         newobj, oldblendobj, static_cast<BL_SkinMeshObject*>(mesh)
1096                                 );
1097                                 newobj->m_pDeformer = meshdeformer;
1098                         }
1099
1100                         // release parent reference if its not being used 
1101                         if( releaseParent && parentobj)
1102                                 parentobj->Release();
1103                 }
1104         }
1105         gameobj->Bucketize();
1106 }
1107
1108
1109
1110 MT_CmMatrix4x4& KX_Scene::GetViewMatrix()
1111 {
1112         MT_Scalar cammat[16];
1113         m_active_camera->GetWorldToCamera().getValue(cammat);
1114         m_viewmat = cammat;
1115         return m_viewmat;
1116 }
1117
1118
1119
1120 MT_CmMatrix4x4& KX_Scene::GetProjectionMatrix()
1121 {
1122         return m_projectionmat;
1123 }
1124
1125
1126 KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
1127 {
1128         list<KX_Camera*>::iterator it = m_cameras.begin();
1129
1130         while ( (it != m_cameras.end()) 
1131                         && ((*it) != cam) ) {
1132           it++;
1133         }
1134
1135         return ((it == m_cameras.end()) ? NULL : (*it));
1136 }
1137
1138
1139 KX_Camera* KX_Scene::FindCamera(STR_String& name)
1140 {
1141         list<KX_Camera*>::iterator it = m_cameras.begin();
1142
1143         while ( (it != m_cameras.end()) 
1144                         && ((*it)->GetName() != name) ) {
1145           it++;
1146         }
1147
1148         return ((it == m_cameras.end()) ? NULL : (*it));
1149 }
1150
1151 void KX_Scene::AddCamera(KX_Camera* cam)
1152 {
1153         if (!FindCamera(cam))
1154                 m_cameras.push_back(cam);
1155 }
1156
1157
1158 KX_Camera* KX_Scene::GetActiveCamera()
1159 {       
1160         // NULL if not defined
1161         return m_active_camera;
1162 }
1163
1164
1165 void KX_Scene::SetActiveCamera(KX_Camera* cam)
1166 {
1167         // only set if the cam is in the active list? Or add it otherwise?
1168         if (!FindCamera(cam)){
1169                 AddCamera(cam);
1170                 if (cam) std::cout << "Added cam " << cam->GetName() << std::endl;
1171         } 
1172
1173         m_active_camera = cam;
1174 }
1175
1176 void KX_Scene::SetCameraOnTop(KX_Camera* cam)
1177 {
1178         if (!FindCamera(cam)){
1179                 // adding is always done at the back, so that's all that needs to be done
1180                 AddCamera(cam);
1181                 if (cam) std::cout << "Added cam " << cam->GetName() << std::endl;
1182         } else {
1183                 m_cameras.remove(cam);
1184                 m_cameras.push_back(cam);
1185         }
1186 }
1187
1188
1189 void KX_Scene::UpdateMeshTransformations()
1190 {
1191         // do this incrementally in the future
1192         for (int i = 0; i < m_objectlist->GetCount(); i++)
1193         {
1194                 KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
1195                 gameobj->GetOpenGLMatrix();
1196 //              gameobj->UpdateNonDynas();
1197         }
1198 }
1199
1200 void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam, int layer)
1201 {
1202         int intersect = KX_Camera::INTERSECT;
1203         KX_GameObject *gameobj = node->Client()?(KX_GameObject*) node->Client()->GetSGClientObject():NULL;
1204         bool visible = (gameobj && gameobj->GetVisible() && (!layer || (gameobj->GetLayer() & layer)));
1205         bool dotest = visible || node->Left() || node->Right();
1206
1207         /* If the camera is inside the box, assume intersect. */
1208         if (dotest && !node->inside( cam->NodeGetWorldPosition()))
1209         {
1210                 MT_Scalar radius = node->Radius();
1211                 MT_Point3 center = node->Center();
1212                 
1213                 intersect =  cam->SphereInsideFrustum(center, radius); 
1214                 
1215                 if (intersect == KX_Camera::INTERSECT)
1216                 {
1217                         MT_Point3 box[8];
1218                         node->get(box);
1219                         intersect = cam->BoxInsideFrustum(box);
1220                 }
1221         }
1222
1223         switch (intersect)
1224         {
1225                 case KX_Camera::OUTSIDE:
1226                         MarkSubTreeVisible(node, rasty, false, cam);
1227                         break;
1228                 case KX_Camera::INTERSECT:
1229                         if (gameobj)
1230                                 MarkVisible(rasty, gameobj, cam, layer);
1231                         if (node->Left())
1232                                 MarkVisible(node->Left(), rasty, cam, layer);
1233                         if (node->Right())
1234                                 MarkVisible(node->Right(), rasty, cam, layer);
1235                         break;
1236                 case KX_Camera::INSIDE:
1237                         MarkSubTreeVisible(node, rasty, true, cam, layer);
1238                         break;
1239         }
1240 }
1241
1242 void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera* cam, int layer)
1243 {
1244         if (node->Client())
1245         {
1246                 KX_GameObject *gameobj = (KX_GameObject*) node->Client()->GetSGClientObject();
1247                 if (gameobj->GetVisible())
1248                 {
1249                         if (visible)
1250                         {
1251                                 int nummeshes = gameobj->GetMeshCount();
1252                                 
1253                                 // this adds the vertices to the display list
1254                                 for (int m=0;m<nummeshes;m++)
1255                                         (gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode());
1256                         }
1257                         gameobj->MarkVisible(visible);
1258                 }
1259         }
1260         if (node->Left())
1261                 MarkSubTreeVisible(node->Left(), rasty, visible, cam, layer);
1262         if (node->Right())
1263                 MarkSubTreeVisible(node->Right(), rasty, visible, cam, layer);
1264 }
1265
1266 void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera*  cam,int layer)
1267 {
1268         // User (Python/Actuator) has forced object invisible...
1269         if (!gameobj->GetVisible())
1270                 return;
1271         
1272         // Shadow lamp layers
1273         if(layer && !(gameobj->GetLayer() & layer)) {
1274                 gameobj->MarkVisible(false);
1275                 return;
1276         }
1277
1278         // If Frustum culling is off, the object is always visible.
1279         bool vis = !cam->GetFrustumCulling();
1280         
1281         // If the camera is inside this node, then the object is visible.
1282         if (!vis)
1283         {
1284                 vis = gameobj->GetSGNode()->inside( GetActiveCamera()->GetCameraLocation() );
1285         }
1286                 
1287         // Test the object's bound sphere against the view frustum.
1288         if (!vis)
1289         {
1290                 MT_Vector3 scale = gameobj->GetSGNode()->GetWorldScaling();
1291                 MT_Scalar radius = fabs(scale[scale.closestAxis()] * gameobj->GetSGNode()->Radius());
1292                 switch (cam->SphereInsideFrustum(gameobj->NodeGetWorldPosition(), radius))
1293                 {
1294                         case KX_Camera::INSIDE:
1295                                 vis = true;
1296                                 break;
1297                         case KX_Camera::OUTSIDE:
1298                                 vis = false;
1299                                 break;
1300                         case KX_Camera::INTERSECT:
1301                                 // Test the object's bound box against the view frustum.
1302                                 MT_Point3 box[8];
1303                                 gameobj->GetSGNode()->getBBox(box); 
1304                                 vis = cam->BoxInsideFrustum(box) != KX_Camera::OUTSIDE;
1305                                 break;
1306                 }
1307         }
1308         
1309         if (vis)
1310         {
1311                 int nummeshes = gameobj->GetMeshCount();
1312                 
1313                 for (int m=0;m<nummeshes;m++)
1314                 {
1315                         // this adds the vertices to the display list
1316                         (gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode());
1317                 }
1318                 // Visibility/ non-visibility are marked
1319                 // elsewhere now.
1320                 gameobj->MarkVisible();
1321         } else {
1322                 gameobj->MarkVisible(false);
1323         }
1324 }
1325
1326 void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int layer)
1327 {
1328 // FIXME: When tree is operational
1329 #if 1
1330         // do this incrementally in the future
1331         for (int i = 0; i < m_objectlist->GetCount(); i++)
1332         {
1333                 MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer);
1334         }
1335 #else
1336         if (cam->GetFrustumCulling())
1337                 MarkVisible(m_objecttree, rasty, cam, layer);
1338         else
1339                 MarkSubTreeVisible(m_objecttree, rasty, true, cam, layer);
1340 #endif
1341 }
1342
1343 // logic stuff
1344 void KX_Scene::LogicBeginFrame(double curtime)
1345 {
1346         // have a look at temp objects ...
1347         int lastobj = m_tempObjectList->GetCount() - 1;
1348         
1349         for (int i = lastobj; i >= 0; i--)
1350         {
1351                 CValue* objval = m_tempObjectList->GetValue(i);
1352                 CFloatValue* propval = (CFloatValue*) objval->GetProperty("::timebomb");
1353                 
1354                 if (propval)
1355                 {
1356                         float timeleft = propval->GetNumber() - 1.0/KX_KetsjiEngine::GetTicRate();
1357                         
1358                         if (timeleft > 0)
1359                         {
1360                                 propval->SetFloat(timeleft);
1361                         }
1362                         else
1363                         {
1364                                 DelayedRemoveObject(objval);
1365                                 // remove obj
1366                         }
1367                 }
1368                 else
1369                 {
1370                         // all object is the tempObjectList should have a clock
1371                 }
1372         }
1373         m_logicmgr->BeginFrame(curtime, 1.0/KX_KetsjiEngine::GetTicRate());
1374 }
1375
1376
1377
1378 void KX_Scene::LogicUpdateFrame(double curtime, bool frame)
1379 {
1380         m_logicmgr->UpdateFrame(curtime, frame);
1381 }
1382
1383
1384
1385 void KX_Scene::LogicEndFrame()
1386 {
1387         m_logicmgr->EndFrame();
1388         int numobj = m_euthanasyobjects->GetCount();
1389         int i;
1390         for (i = numobj - 1; i >= 0; i--)
1391         {
1392                 KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i);
1393                 // KX_Scene::RemoveObject will also remove the object from this list
1394                 // that's why we start from the end
1395                 this->RemoveObject(gameobj);
1396         }
1397
1398         numobj= m_delayReleaseObjects->GetCount();
1399         for (i = numobj-1;i>=0;i--)
1400         {
1401                 KX_GameObject* gameobj = (KX_GameObject*)m_delayReleaseObjects->GetValue(i);
1402                 // This list is not for object removal, but just object release
1403                 gameobj->Release();
1404         }
1405         // empty the list as we have removed all references
1406         m_delayReleaseObjects->Resize(0);       
1407 }
1408
1409
1410
1411 /**
1412   * UpdateParents: SceneGraph transformation update.
1413   */
1414 void KX_Scene::UpdateParents(double curtime)
1415 {
1416 //      int numrootobjects = GetRootParentList()->GetCount();
1417
1418         for (int i=0; i<GetRootParentList()->GetCount(); i++)
1419         {
1420                 KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i);
1421                 parentobj->NodeUpdateGS(curtime,true);
1422         }
1423 }
1424
1425
1426
1427 RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat, bool &bucketCreated)
1428 {
1429         return m_bucketmanager->FindBucket(polymat, bucketCreated);
1430 }
1431
1432
1433
1434 void KX_Scene::RenderBuckets(const MT_Transform & cameratransform,
1435                                                          class RAS_IRasterizer* rasty,
1436                                                          class RAS_IRenderTools* rendertools)
1437 {
1438         m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools);
1439         KX_BlenderMaterial::EndFrame();
1440 }
1441
1442 void KX_Scene::UpdateObjectActivity(void) 
1443 {
1444         if (m_activity_culling) {
1445                 /* determine the activity criterium and set objects accordingly */
1446                 int i=0;
1447                 
1448                 MT_Point3 camloc = GetActiveCamera()->NodeGetWorldPosition(); //GetCameraLocation();
1449                 
1450                 for (i=0;i<GetObjectList()->GetCount();i++)
1451                 {
1452                         KX_GameObject* ob = (KX_GameObject*) GetObjectList()->GetValue(i);
1453                         
1454                         if (!ob->GetIgnoreActivityCulling()) {
1455                                 /* Simple test: more than 10 away from the camera, count
1456                                  * Manhattan distance. */
1457                                 MT_Point3 obpos = ob->NodeGetWorldPosition();
1458                                 
1459                                 if ( (fabs(camloc[0] - obpos[0]) > m_activity_box_radius)
1460                                          || (fabs(camloc[1] - obpos[1]) > m_activity_box_radius)
1461                                          || (fabs(camloc[2] - obpos[2]) > m_activity_box_radius) )
1462                                 {                       
1463                                         ob->Suspend();
1464                                 } else {
1465                                         ob->Resume();
1466                                 }
1467                         }
1468                 }               
1469         }
1470 }
1471
1472 void KX_Scene::SetActivityCullingRadius(float f)
1473 {
1474         if (f < 0.5)
1475                 f = 0.5;
1476         m_activity_box_radius = f;
1477 }
1478         
1479 NG_NetworkDeviceInterface* KX_Scene::GetNetworkDeviceInterface()
1480 {
1481         return m_networkDeviceInterface;
1482 }
1483
1484 NG_NetworkScene* KX_Scene::GetNetworkScene()
1485 {
1486         return m_networkScene;
1487 }
1488
1489 void KX_Scene::SetNetworkDeviceInterface(NG_NetworkDeviceInterface* newInterface)
1490 {
1491         m_networkDeviceInterface = newInterface;
1492 }
1493
1494 void KX_Scene::SetNetworkScene(NG_NetworkScene *newScene)
1495 {
1496         m_networkScene = newScene;
1497 }
1498
1499
1500 void    KX_Scene::SetGravity(const MT_Vector3& gravity)
1501 {
1502         GetPhysicsEnvironment()->setGravity(gravity[0],gravity[1],gravity[2]);
1503 }
1504
1505 void KX_Scene::SetNodeTree(SG_Tree* root)
1506 {
1507         m_objecttree = root;
1508 }
1509
1510 void KX_Scene::SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter)
1511 {
1512         m_sceneConverter = sceneConverter;
1513 }
1514
1515 void KX_Scene::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* physEnv)
1516 {
1517         m_physicsEnvironment = physEnv;
1518
1519         KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, physEnv);
1520         m_logicmgr->RegisterEventManager(touchmgr);
1521         return;
1522 }
1523  
1524 void KX_Scene::setSuspendedTime(double suspendedtime)
1525 {
1526         m_suspendedtime = suspendedtime;
1527 }
1528 double KX_Scene::getSuspendedTime()
1529 {
1530         return m_suspendedtime;
1531 }
1532 void KX_Scene::setSuspendedDelta(double suspendeddelta)
1533 {
1534         m_suspendeddelta = suspendeddelta;
1535 }
1536 double KX_Scene::getSuspendedDelta()
1537 {
1538         return m_suspendeddelta;
1539 }
1540
1541 //----------------------------------------------------------------------------
1542 //Python
1543
1544 PyMethodDef KX_Scene::Methods[] = {
1545         KX_PYMETHODTABLE(KX_Scene, getLightList),
1546         KX_PYMETHODTABLE(KX_Scene, getObjectList),
1547         KX_PYMETHODTABLE(KX_Scene, getName),
1548         
1549         {NULL,NULL} //Sentinel
1550 };
1551
1552 PyTypeObject KX_Scene::Type = {
1553         PyObject_HEAD_INIT(&PyType_Type)
1554                 0,
1555                 "KX_Scene",
1556                 sizeof(KX_Scene),
1557                 0,
1558                 PyDestructor,
1559                 0,
1560                 __getattr,
1561                 __setattr,
1562                 0, //&MyPyCompare,
1563                 __repr,
1564                 0, //&cvalue_as_number,
1565                 0,
1566                 0,
1567                 0,
1568                 0, 0, 0, 0, 0, 0
1569 };
1570
1571 PyParentObject KX_Scene::Parents[] = {
1572         &KX_Scene::Type,
1573                 &CValue::Type,
1574                 NULL
1575 };
1576
1577 PyObject* KX_Scene::_getattr(const STR_String& attr)
1578 {
1579         if (attr == "name")
1580                 return PyString_FromString(GetName());
1581         
1582         if (attr == "active_camera")
1583         {
1584                 KX_Camera *camera = GetActiveCamera();
1585                 camera->AddRef();
1586                 return (PyObject*) camera;
1587         }
1588         
1589         if (attr == "suspended")
1590                 return PyInt_FromLong(m_suspend);
1591         
1592         if (attr == "activity_culling")
1593                 return PyInt_FromLong(m_activity_culling);
1594         
1595         if (attr == "activity_culling_radius")
1596                 return PyFloat_FromDouble(m_activity_box_radius);
1597         
1598         PyObject* value = PyDict_GetItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()));
1599         if (value)
1600         {
1601                 Py_INCREF(value);
1602                 return value;
1603         }
1604         
1605         _getattr_up(PyObjectPlus);
1606 }
1607
1608 int KX_Scene::_delattr(const STR_String &attr)
1609 {
1610         PyDict_DelItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()));
1611         return 0;
1612 }
1613
1614 int KX_Scene::_setattr(const STR_String &attr, PyObject *pyvalue)
1615 {
1616
1617         if (!PyDict_SetItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()), pyvalue))
1618                 return 0;
1619
1620         return PyObjectPlus::_setattr(attr, pyvalue);
1621 }
1622
1623 KX_PYMETHODDEF_DOC(KX_Scene, getLightList,
1624 "getLightList() -> list [KX_Light]\n"
1625 "Returns a list of all lights in the scene.\n"
1626 )
1627 {
1628         m_lightlist->AddRef();
1629         return (PyObject*) m_lightlist;
1630 }
1631
1632 KX_PYMETHODDEF_DOC(KX_Scene, getObjectList,
1633 "getObjectList() -> list [KX_GameObject]\n"
1634 "Returns a list of all game objects in the scene.\n"
1635 )
1636 {
1637         m_objectlist->AddRef();
1638         return (PyObject*) m_objectlist;
1639 }
1640
1641 KX_PYMETHODDEF_DOC(KX_Scene, getName,
1642 "getName() -> string\n"
1643 "Returns the name of the scene.\n"
1644 )
1645 {
1646         return PyString_FromString(GetName());
1647 }