Initial revision
[blender.git] / source / gameengine / Ketsji / KX_Scene.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * Ketsji scene. Holds references to all scene data.
32  */
33
34 #ifdef WIN32
35 #pragma warning (disable : 4786)
36 #endif //WIN32
37
38 #include "KX_KetsjiEngine.h"
39 #include "RAS_IPolygonMaterial.h"
40 #include "KX_Scene.h"
41 #include "ListValue.h"
42 #include "SCA_LogicManager.h"
43 #include "SCA_TimeEventManager.h"
44 #include "SCA_AlwaysEventManager.h"
45 #include "SCA_RandomEventManager.h"
46 #include "KX_RayEventManager.h"
47 #include "KX_TouchEventManager.h"
48 #include "SCA_KeyboardManager.h"
49 #include "SCA_MouseManager.h"
50 #include "SCA_PropertyEventManager.h"
51 #include "KX_Camera.h"
52
53 #include "RAS_MeshObject.h"
54 #include "RAS_IRasterizer.h"
55 #include "RAS_BucketManager.h"
56
57 #include "FloatValue.h"
58 #include "SCA_IController.h"
59 #include "SCA_IActuator.h"
60 #include "SG_Node.h"
61 #include "SYS_System.h"
62 #include "SG_Controller.h"
63 #include "SG_IObject.h"
64
65 #include "KX_SG_NodeRelationships.h"
66
67 #include "KX_NetworkEventManager.h"
68 #include "NG_NetworkScene.h"
69 #include "PHY_IPhysicsEnvironment.h"
70 #include "KX_IPhysicsController.h"
71
72
73 void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
74 {
75         KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
76
77         return (void*)replica;
78 }
79
80 void* KX_SceneDestructionFunc(SG_IObject* node,void* gameobj,void* scene)
81 {
82         ((KX_Scene*)scene)->RemoveNodeDestructObject(node,(KX_GameObject*)gameobj);
83
84         return NULL;
85 };
86
87
88 SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(KX_SceneReplicationFunc,KX_SceneDestructionFunc);
89
90 // temporarily var until there is a button in the userinterface
91 // (defined in KX_PythonInit.cpp)
92 extern bool gUseVisibilityTemp;
93
94
95
96
97 KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
98                                    class SCA_IInputDevice* mousedevice,
99                                    class NG_NetworkDeviceInterface *ndi,
100                                    class SND_IAudioDevice* adi,
101                                    const STR_String& sceneName): 
102
103         m_mousemgr(NULL),
104         m_keyboardmgr(NULL),
105         m_active_camera(NULL),
106         m_ueberExecutionPriority(0),
107         m_adi(adi),
108         m_sceneName(sceneName),
109         m_networkDeviceInterface(ndi),
110         m_physicsEnvironment(0)
111 {
112                 
113
114         m_activity_culling = false;
115         m_suspend = false;
116         m_isclearingZbuffer = true;
117         m_tempObjectList = new CListValue();
118         m_objectlist = new CListValue();
119         m_parentlist = new CListValue();
120         m_lightlist= new CListValue();
121         m_euthanasyobjects = new CListValue();
122
123         m_logicmgr = new SCA_LogicManager();
124         
125         m_timemgr = new SCA_TimeEventManager(m_logicmgr);
126         m_keyboardmgr = new SCA_KeyboardManager(m_logicmgr,keyboarddevice);
127         m_mousemgr = new SCA_MouseManager(m_logicmgr,mousedevice);
128         
129 //      m_solidScene = DT_CreateScene();
130 //      m_respTable = DT_CreateRespTable();
131
132         SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr);
133         //KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, m_respTable, m_solidScene);
134         SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr);
135         SCA_RandomEventManager* rndmgr = new SCA_RandomEventManager(m_logicmgr);
136         KX_RayEventManager* raymgr = new KX_RayEventManager(m_logicmgr);
137
138         KX_NetworkEventManager* netmgr = new KX_NetworkEventManager(m_logicmgr, ndi);
139
140         m_logicmgr->RegisterEventManager(alwaysmgr);
141         m_logicmgr->RegisterEventManager(propmgr);
142         m_logicmgr->RegisterEventManager(m_keyboardmgr);
143         m_logicmgr->RegisterEventManager(m_mousemgr);
144         //m_logicmgr->RegisterEventManager(touchmgr);
145         m_logicmgr->RegisterEventManager(m_timemgr);
146         m_logicmgr->RegisterEventManager(rndmgr);
147         m_logicmgr->RegisterEventManager(raymgr);
148         m_logicmgr->RegisterEventManager(netmgr);
149
150         //m_sumoScene = new SM_Scene();
151         //m_sumoScene->setSecondaryRespTable(m_respTable);
152         m_soundScene = new SND_Scene(adi);
153         assert (m_networkDeviceInterface != NULL);
154         m_networkScene = new NG_NetworkScene(m_networkDeviceInterface);
155         
156         m_rootnode = NULL;
157
158         m_bucketmanager=new RAS_BucketManager();
159
160         m_canvasDesignWidth = 0;
161         m_canvasDesignHeight = 0;
162 }
163
164
165
166 KX_Scene::~KX_Scene()
167 {
168 //      int numobj = m_objectlist->GetCount();
169
170         //int numrootobjects = GetRootParentList()->GetCount();
171         for (int i = 0; i < GetRootParentList()->GetCount(); i++)
172         {
173                 KX_GameObject* parentobj = (KX_GameObject*) GetRootParentList()->GetValue(i);
174                 this->RemoveObject(parentobj);
175         }
176
177         if(m_objectlist)
178                 m_objectlist->Release();
179         
180         if (m_parentlist)
181                 m_parentlist->Release();
182         
183         if (m_lightlist)
184                 m_lightlist->Release();
185         
186         if (m_tempObjectList)
187                 m_tempObjectList->Release();
188
189         if (m_euthanasyobjects)
190                 m_euthanasyobjects->Release();
191         
192         if (m_logicmgr)
193                 delete m_logicmgr;
194
195         if (m_physicsEnvironment)
196                 delete m_physicsEnvironment;
197
198         if (m_soundScene)
199                 delete m_soundScene;
200
201         if (m_networkScene)
202                 delete m_networkScene;
203         
204         if (m_bucketmanager)
205         {
206                 delete m_bucketmanager;
207         }
208 }
209
210
211
212
213 void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
214 {
215         m_projectionmat = pmat;
216 }
217
218
219
220 RAS_BucketManager* KX_Scene::GetBucketManager()
221 {
222         return m_bucketmanager;
223 }
224
225
226
227 CListValue* KX_Scene::GetObjectList()
228 {
229         return m_objectlist;
230 }
231
232
233
234 CListValue* KX_Scene::GetRootParentList()
235 {
236         return m_parentlist;
237 }
238
239
240
241 CListValue* KX_Scene::GetLightList()
242 {
243         return m_lightlist;
244 }
245
246 SCA_LogicManager* KX_Scene::GetLogicManager()
247 {
248         return m_logicmgr;
249 }
250
251 SCA_TimeEventManager* KX_Scene::GetTimeEventManager()
252 {
253         return m_timemgr;
254 }
255
256
257
258
259 void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings)
260 {
261         m_frame_settings = frame_settings;
262 };
263
264 /**
265  * Return a const reference to the framing 
266  * type set by the above call.
267  * The contents are not guarenteed to be sensible
268  * if you don't call the above function.
269  */
270 const RAS_FrameSettings& KX_Scene::GetFramingType() const 
271 {
272         return m_frame_settings;
273 };      
274
275
276
277 /**
278  * Store the current scene's viewport on the 
279  * game engine canvas.
280  */
281 void KX_Scene::SetSceneViewport(const RAS_Rect &viewport)
282 {
283         m_viewport = viewport;
284 }
285
286
287
288 const RAS_Rect& KX_Scene::GetSceneViewport() const 
289 {
290         return m_viewport;
291 }
292
293
294
295 void KX_Scene::SetWorldInfo(class KX_WorldInfo* worldinfo)
296 {
297         m_worldinfo = worldinfo;
298 }
299
300
301
302 class KX_WorldInfo* KX_Scene::GetWorldInfo()
303 {
304         return m_worldinfo;
305 }
306
307
308
309 SND_Scene* KX_Scene::GetSoundScene()
310 {
311         return m_soundScene;
312 }
313
314 const STR_String& KX_Scene::GetName()
315 {
316         return m_sceneName;
317 }
318
319
320 void KX_Scene::Suspend()
321 {
322         m_suspend = true;
323 }
324
325 void KX_Scene::Resume()
326 {
327         m_suspend = false;
328 }
329
330 void KX_Scene::SetActivityCulling(bool b)
331 {
332         m_activity_culling = b;
333 }
334
335 bool KX_Scene::IsSuspended()
336 {
337         return m_suspend;
338 }
339
340 bool KX_Scene::IsClearingZBuffer()
341 {
342         return m_isclearingZbuffer;
343 }
344
345 void KX_Scene::EnableZBufferClearing(bool isclearingZbuffer)
346 {
347         m_isclearingZbuffer = isclearingZbuffer;
348 }
349
350 void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj)
351 {
352         KX_GameObject* orgobj = (KX_GameObject*)gameobj;        
353         NewRemoveObject(orgobj);
354
355         if (node)
356                 delete node;
357 }
358
359 KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CValue* gameobj)
360 {
361         KX_GameObject* orgobj = (KX_GameObject*)gameobj;
362         KX_GameObject* newobj = (KX_GameObject*)orgobj->GetReplica();
363         m_map_gameobject_to_replica.insert(orgobj, newobj);
364
365         // also register 'timers' (time properties) of the replica
366         int numprops = newobj->GetPropertyCount();
367
368         for (int i = 0; i < numprops; i++)
369         {
370                 CValue* prop = newobj->GetProperty(i);
371
372                 if (prop->GetProperty("timer"))
373                         this->m_timemgr->AddTimeProperty(prop);
374         }
375
376         if (node)
377         {
378                 newobj->SetSGNode((SG_Node*)node);
379         }
380         else
381         {
382                 m_rootnode = new SG_Node(newobj,this,KX_Scene::m_callbacks);
383         
384                 // this fixes part of the scaling-added object bug
385                 SG_Node* orgnode = orgobj->GetSGNode();
386                 m_rootnode->SetLocalScale(orgnode->GetLocalScale());
387                 m_rootnode->SetLocalPosition(orgnode->GetLocalPosition());
388                 m_rootnode->SetLocalOrientation(orgnode->GetLocalOrientation());
389
390                 // define the relationship between this node and it's parent.
391                 KX_NormalParentRelation * parent_relation = 
392                         KX_NormalParentRelation::New();
393                 m_rootnode->SetParentRelation(parent_relation);
394
395                 newobj->SetSGNode(m_rootnode);
396         }
397         
398         SG_IObject* replicanode = newobj->GetSGNode();
399         SG_Node* rootnode = (replicanode == m_rootnode ? NULL : m_rootnode);
400
401         replicanode->SetSGClientObject(newobj);
402
403         // this is the list of object that are send to the graphics pipeline
404         m_objectlist->Add(newobj);
405         newobj->Bucketize();
406
407         // logic cannot be replicated, until the whole hierarchy is replicated.
408         m_logicHierarchicalGameObjects.push_back(newobj);
409         //replicate controllers of this node
410         SGControllerList        scenegraphcontrollers = orgobj->GetSGNode()->GetSGControllerList();
411         replicanode->RemoveAllControllers();
412         SGControllerList::iterator cit;
413         //int numcont = scenegraphcontrollers.size();
414         
415         for (cit = scenegraphcontrollers.begin();!(cit==scenegraphcontrollers.end());++cit)
416         {
417                 // controller replication is quite complicated
418                 // only replicate ipo and physics controller for now
419
420                 SG_Controller* replicacontroller = (*cit)->GetReplica((SG_Node*) replicanode);
421                 if (replicacontroller)
422                 {
423                         replicacontroller->SetObject(replicanode);
424                         replicanode->AddSGController(replicacontroller);
425                 }
426         }
427         
428         return newobj;
429 }
430
431
432
433 // before calling this method KX_Scene::ReplicateLogic(), make sure to
434 // have called 'GameObject::ReParentLogic' for each object this
435 // hierarchy that's because first ALL bricks must exist in the new
436 // replica of the hierarchy in order to make cross-links work properly
437 // !
438 void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
439 {
440         // also relink the controller to sensors/actuators
441         SCA_ControllerList& controllers = newobj->GetControllers();
442         //SCA_SensorList&     sensors     = newobj->GetSensors();
443         //SCA_ActuatorList&   actuators   = newobj->GetActuators();
444
445         for (SCA_ControllerList::iterator itc = controllers.begin(); !(itc==controllers.end());itc++)
446         {
447                 SCA_IController* cont = (*itc);
448                 cont->SetUeberExecutePriority(m_ueberExecutionPriority);
449                 vector<SCA_ISensor*> linkedsensors = cont->GetLinkedSensors();
450                 vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators();
451
452                 // disconnect the sensors and actuators
453                 cont->UnlinkAllSensors();
454                 cont->UnlinkAllActuators();
455                 
456                 // now relink each sensor
457                 for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++)
458                 {
459                         SCA_ISensor* oldsensor = (*its);
460                         STR_String name = oldsensor->GetName();
461                         //find this name in the list
462                         SCA_ISensor* newsensor = newobj->FindSensor(name);
463                 
464                         if (newsensor)
465                         {
466                                 // relink this newsensor to the controller
467                                 m_logicmgr->RegisterToSensor(cont,newsensor);
468                         }
469                         else
470                         {
471                                 // it can be linked somewhere in the hierarchy or...
472                                 for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin();
473                                 !(git==m_logicHierarchicalGameObjects.end());++git)
474                                 {
475                                         newsensor = (*git)->FindSensor(name);
476                                         if (newsensor)
477                                                 break;
478                                 } 
479
480                                 if (newsensor)
481                                 {
482                                         // relink this newsensor to the controller somewhere else within this
483                                         // hierarchy
484                                         m_logicmgr->RegisterToSensor(cont,newsensor);
485                                 }
486                                 else
487                                 {
488                                         // must be an external sensor, so...
489                                         m_logicmgr->RegisterToSensor(cont,oldsensor);
490                                 }
491                         }
492                 }
493                 
494                 // now relink each actuator
495                 for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());ita++)
496                 {
497                         SCA_IActuator* oldactuator = (*ita);
498                         STR_String name = oldactuator->GetName();
499                         //find this name in the list
500                         SCA_IActuator* newactuator = newobj->FindActuator(name);
501                         if (newactuator)
502                         {
503                                 // relink this newsensor to the controller
504                                 m_logicmgr->RegisterToActuator(cont,newactuator);
505                                 newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
506                         }
507                         else
508                         {
509                                 // it can be linked somewhere in the hierarchy or...
510                                 for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin();
511                                 !(git==m_logicHierarchicalGameObjects.end());++git)
512                                 {
513                                         newactuator= (*git)->FindActuator(name);
514                                         if (newactuator)
515                                                 break;
516                                 } 
517
518                                 if (newactuator)
519                                 {
520                                         // relink this actuator to the controller somewhere else within this
521                                         // hierarchy
522                                         m_logicmgr->RegisterToActuator(cont,newactuator);
523                                         newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
524                                 }
525                                 else
526                                 {
527                                         // must be an external actuator, so...
528                                         m_logicmgr->RegisterToActuator(cont,oldactuator);
529                                 }
530                         }
531                 }
532         }
533 }
534
535
536
537 SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
538                                                                                 class CValue* parentobject,
539                                                                                 int lifespan)
540 {
541
542         m_logicHierarchicalGameObjects.clear();
543         m_map_gameobject_to_replica.clear();
544
545         // todo: place a timebomb in the object, for temporarily objects :)
546         // lifespan of zero means 'this object lives forever'
547         KX_GameObject* originalobj = (KX_GameObject*) originalobject;
548         KX_GameObject* parentobj = (KX_GameObject*) parentobject;
549
550         m_ueberExecutionPriority++;
551
552         // lets create a replica
553         KX_GameObject* replica = (KX_GameObject*) AddNodeReplicaObject(NULL,originalobj);
554
555         if (lifespan > 0)
556         {
557                 // add a timebomb to this object
558                 // for now, convert between so called frames and realtime
559                 m_tempObjectList->Add(replica->AddRef());
560                 replica->SetProperty("::timebomb",new CFloatValue(lifespan*0.02));
561         }
562
563         // add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame)
564         m_parentlist->Add(replica->AddRef());
565
566         // recurse replication into children nodes
567
568         NodeList& children = originalobj->GetSGNode()->GetSGChildren();
569
570         replica->GetSGNode()->ClearSGChildren();
571         for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
572         {
573                 SG_Node* orgnode = (*childit);
574                 SG_Node* childreplicanode = orgnode->GetSGReplica();
575                 replica->GetSGNode()->AddChild(childreplicanode);
576         }
577
578         //      relink any pointers as necessary, sort of a temporary solution
579         vector<KX_GameObject*>::iterator git;
580         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
581         {
582                 (*git)->Relink(&m_map_gameobject_to_replica);
583         }
584
585         // now replicate logic
586         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
587         {
588                 (*git)->ReParentLogic();
589         }
590         
591         // replicate crosslinks etc. between logic bricks
592         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
593         {
594                 ReplicateLogic((*git));
595         }
596         
597         MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition();
598         replica->NodeSetLocalPosition(newpos);
599
600         MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
601         replica->NodeSetLocalOrientation(newori);
602
603         if (replica->GetPhysicsController())
604         {
605                 replica->GetPhysicsController()->setPosition(newpos);
606                 replica->GetPhysicsController()->setOrientation(newori.getRotation());
607         }
608
609         // here we want to set the relative scale: the rootnode's scale will override all other
610         // scalings, so lets better prepare for it
611
612         // get the rootnode's scale
613         MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
614
615         // set the replica's relative scale with the rootnode's scale
616         replica->NodeSetRelativeScale(newscale);
617
618         replica->GetSGNode()->UpdateWorldData(0);
619         
620         return replica;
621 }
622
623
624
625 void KX_Scene::RemoveObject(class CValue* gameobj)
626 {
627         KX_GameObject* newobj = (KX_GameObject*) gameobj;
628
629         // first disconnect child from parent
630         SG_Node* node = newobj->GetSGNode();
631
632         if (node)
633         {
634                 node->DisconnectFromParent();
635
636                 // recursively destruct
637                 node->Destruct();
638         }
639 }
640
641
642
643 void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
644 {
645         //KX_GameObject* newobj = (KX_GameObject*) gameobj;
646         if (!m_euthanasyobjects->SearchValue(gameobj))
647         {
648                 m_euthanasyobjects->Add(gameobj->AddRef());
649         } 
650 }
651
652
653
654 void KX_Scene::NewRemoveObject(class CValue* gameobj)
655 {
656         KX_GameObject* newobj = (KX_GameObject*) gameobj;
657         //SM_Object* sumoObj = newobj->GetSumoObject();
658         //if (sumoObj)
659         //{
660         //      this->GetSumoScene()->remove(*sumoObj);
661         //}
662         // remove all sensors/controllers/actuators from logicsystem...
663         
664         SCA_SensorList& sensors = newobj->GetSensors();
665         for (SCA_SensorList::iterator its = sensors.begin();
666                  !(its==sensors.end());its++)
667         {
668                 m_logicmgr->RemoveSensor(*its);
669         }
670         
671     SCA_ControllerList& controllers = newobj->GetControllers();
672         for (SCA_ControllerList::iterator itc = controllers.begin();
673                  !(itc==controllers.end());itc++)
674         {
675                 (*itc)->UnlinkAllSensors();
676                 (*itc)->UnlinkAllActuators();
677         }
678
679         SCA_ActuatorList& actuators = newobj->GetActuators();
680         for (SCA_ActuatorList::iterator ita = actuators.begin();
681                  !(ita==actuators.end());ita++)
682         {
683                 m_logicmgr->RemoveDestroyedActuator(*ita);
684         }
685
686         // now remove the timer properties from the time manager
687         int numprops = newobj->GetPropertyCount();
688
689         for (int i = 0; i < numprops; i++)
690         {
691                 CValue* propval = newobj->GetProperty(i);
692                 if (propval->GetProperty("timer"))
693                 {
694                         m_timemgr->RemoveTimeProperty(propval);
695                 }
696         }
697         
698         newobj->RemoveMeshes();
699         if (m_objectlist->RemoveValue(newobj))
700                 newobj->Release();
701         if (m_tempObjectList->RemoveValue(newobj))
702                 newobj->Release();
703         if (m_parentlist->RemoveValue(newobj))
704                 newobj->Release();
705         if (m_euthanasyobjects->RemoveValue(newobj))
706                 newobj->Release();
707 }
708
709
710
711 void KX_Scene::ReplaceMesh(class CValue* gameobj,void* meshobj)
712 {
713         KX_GameObject* newobj = (KX_GameObject*) gameobj;
714         newobj->RemoveMeshes();
715         newobj->AddMesh((RAS_MeshObject*)meshobj);
716         newobj->Bucketize();
717 }
718
719
720
721 MT_CmMatrix4x4& KX_Scene::GetViewMatrix()
722 {
723         MT_Scalar cammat[16];
724         m_active_camera->GetWorldToCamera().getValue(cammat);
725         m_viewmat = cammat;
726         return m_viewmat;
727 }
728
729
730
731 MT_CmMatrix4x4& KX_Scene::GetProjectionMatrix()
732 {
733         return m_projectionmat;
734 }
735
736
737 KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
738 {
739         set<KX_Camera*>::iterator it = m_cameras.begin();
740
741         while ( (it != m_cameras.end()) 
742                         && ((*it) != cam) ) {
743           it++;
744         }
745
746         return ((it == m_cameras.end()) ? NULL : (*it));
747 }
748
749
750 KX_Camera* KX_Scene::FindCamera(STR_String& name)
751 {
752         set<KX_Camera*>::iterator it = m_cameras.begin();
753
754         while ( (it != m_cameras.end()) 
755                         && ((*it)->GetName() != name) ) {
756           it++;
757         }
758
759         return ((it == m_cameras.end()) ? NULL : (*it));
760 }
761
762 void KX_Scene::AddCamera(KX_Camera* cam)
763 {
764         m_cameras.insert(cam);
765 }
766
767
768 KX_Camera* KX_Scene::GetActiveCamera()
769 {       
770         // NULL if not defined
771         return m_active_camera;
772 }
773
774
775 void KX_Scene::SetActiveCamera(KX_Camera* cam)
776 {
777         // only set if the cam is in the active list? Or add it otherwise?
778         if (!FindCamera(cam)){
779                 AddCamera(cam);
780                 if (cam) std::cout << "Added cam " << cam->GetName() << std::endl;
781         } 
782
783         m_active_camera = cam;
784 }
785
786
787
788 void KX_Scene::UpdateMeshTransformations()
789 {
790         // do this incrementally in the future
791         for (int i = 0; i < m_objectlist->GetCount(); i++)
792         {
793                 KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
794                 gameobj->GetOpenGLMatrix();
795                 gameobj->UpdateNonDynas();
796         }
797 }
798
799 void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty)
800 {
801         
802         // do this incrementally in the future
803         for (int i = 0; i < m_objectlist->GetCount(); i++)
804         {
805                 KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
806                 
807                 int nummeshes = gameobj->GetMeshCount();
808                 
809                 for (int m=0;m<nummeshes;m++)
810                 {
811                         // this adds the vertices to the display list
812                         (gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode(),rasty);
813                         // Visibility/ non-visibility are marked
814                         // elsewhere now.
815                         gameobj->MarkVisible();
816                 }
817         }
818 }
819
820 // logic stuff
821 void KX_Scene::LogicBeginFrame(double curtime,double deltatime)
822 {
823         // have a look at temp objects ...
824         int lastobj = m_tempObjectList->GetCount() - 1;
825         
826         for (int i = lastobj; i >= 0; i--)
827         {
828                 CValue* objval = m_tempObjectList->GetValue(i);
829                 CFloatValue* propval = (CFloatValue*) objval->GetProperty("::timebomb");
830                 
831                 if (propval)
832                 {
833                         float timeleft = propval->GetNumber() - deltatime;
834                         
835                         if (timeleft > 0)
836                         {
837                                 propval->SetFloat(timeleft);
838                         }
839                         else
840                         {
841                                 DelayedRemoveObject(objval);
842                                 // remove obj
843                         }
844                 }
845                 else
846                 {
847                         // all object is the tempObjectList should have a clock
848                 }
849         }
850         m_logicmgr->BeginFrame(curtime,deltatime);
851 }
852
853
854
855 void KX_Scene::LogicUpdateFrame(double curtime,double deltatime)
856 {
857         m_logicmgr->UpdateFrame(curtime,deltatime);
858 }
859
860
861
862 void KX_Scene::LogicEndFrame()
863 {
864         m_logicmgr->EndFrame();
865         int numobj = m_euthanasyobjects->GetCount();
866
867         for (int i = numobj - 1; i >= 0; i--)
868         {
869                 KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i);
870                 this->RemoveObject(gameobj);
871         }
872         
873         numobj = m_euthanasyobjects->GetCount();
874         if (numobj != 0)
875         {
876                 // huh?
877                 int ii=0;
878         }
879         // numobj is 0 we hope
880 }
881
882
883
884 /**
885   * UpdateParents: SceneGraph transformation update.
886   */
887 void KX_Scene::UpdateParents(double curtime)
888 {
889 //      int numrootobjects = GetRootParentList()->GetCount();
890
891         for (int i=0; i<GetRootParentList()->GetCount(); i++)
892         {
893                 KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i);
894                 parentobj->NodeUpdateGS(curtime,true);
895         }
896 }
897
898
899
900 RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat)
901 {
902         return m_bucketmanager->RAS_BucketManagerFindBucket(polymat);
903 }
904
905
906
907 void KX_Scene::RenderBuckets(const MT_Transform & cameratransform,
908                                                          class RAS_IRasterizer* rasty,
909                                                          class RAS_IRenderTools* rendertools)
910 {
911         m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools);
912 }
913
914
915
916 void KX_Scene::UpdateObjectActivity(void) 
917 {
918         if (m_activity_culling) {
919                 /* determine the activity criterium and set objects accordingly */
920                 int i=0;
921                 
922                 MT_Point3 camloc = GetActiveCamera()->NodeGetWorldPosition(); //GetCameraLocation();
923                 
924                 for (i=0;i<GetObjectList()->GetCount();i++)
925                 {
926                         KX_GameObject* ob = (KX_GameObject*) GetObjectList()->GetValue(i);
927                         
928                         if (!ob->GetIgnoreActivityCulling()) {
929                                 /* Simple test: more than 10 away from the camera, count
930                                  * Manhattan distance. */
931                                 MT_Point3 obpos = ob->NodeGetWorldPosition();
932                                 
933                                 if ( (fabs(camloc[0] - obpos[0]) > m_activity_box_radius)
934                                          || (fabs(camloc[1] - obpos[1]) > m_activity_box_radius)
935                                          || (fabs(camloc[2] - obpos[2]) > m_activity_box_radius) )
936                                 {                       
937                                         ob->Suspend();
938                                 } else {
939                                         ob->Resume();
940                                 }
941                         }
942                 }               
943         }
944 }
945
946 void KX_Scene::SetActivityCullingRadius(float f)
947 {
948         if (f < 0.5)
949                 f = 0.5;
950         m_activity_box_radius = f;
951 }
952         
953 NG_NetworkDeviceInterface* KX_Scene::GetNetworkDeviceInterface()
954 {
955         return m_networkDeviceInterface;
956 }
957
958 NG_NetworkScene* KX_Scene::GetNetworkScene()
959 {
960         return m_networkScene;
961 }
962
963 void KX_Scene::SetNetworkDeviceInterface(NG_NetworkDeviceInterface* newInterface)
964 {
965         m_networkDeviceInterface = newInterface;
966 }
967
968 void KX_Scene::SetNetworkScene(NG_NetworkScene *newScene)
969 {
970         m_networkScene = newScene;
971 }
972
973
974 void    KX_Scene::SetGravity(const MT_Vector3& gravity)
975 {
976         GetPhysicsEnvironment()->setGravity(gravity[0],gravity[1],gravity[2]);
977 }