1ed429ea4904be033c17f8682490fd18124f96c2
[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_Scene.h"
39 #include "MT_assert.h"
40
41 #include "KX_KetsjiEngine.h"
42 #include "RAS_IPolygonMaterial.h"
43 #include "ListValue.h"
44 #include "SCA_LogicManager.h"
45 #include "SCA_TimeEventManager.h"
46 #include "SCA_AlwaysEventManager.h"
47 #include "SCA_RandomEventManager.h"
48 #include "KX_RayEventManager.h"
49 #include "KX_TouchEventManager.h"
50 #include "SCA_KeyboardManager.h"
51 #include "SCA_MouseManager.h"
52 #include "SCA_PropertyEventManager.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
71 #include "KX_SG_NodeRelationships.h"
72
73 #include "KX_NetworkEventManager.h"
74 #include "NG_NetworkScene.h"
75 #include "PHY_IPhysicsEnvironment.h"
76 #include "KX_IPhysicsController.h"
77
78 #include "BL_SkinDeformer.h"
79 #include "BL_DeformableGameObject.h"
80
81
82 void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
83 {
84         KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
85
86         return (void*)replica;
87 }
88
89 void* KX_SceneDestructionFunc(SG_IObject* node,void* gameobj,void* scene)
90 {
91         ((KX_Scene*)scene)->RemoveNodeDestructObject(node,(KX_GameObject*)gameobj);
92
93         return NULL;
94 };
95
96 SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(KX_SceneReplicationFunc,KX_SceneDestructionFunc,KX_GameObject::UpdateTransformFunc);
97
98 // temporarily var until there is a button in the userinterface
99 // (defined in KX_PythonInit.cpp)
100 extern bool gUseVisibilityTemp;
101
102 KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
103                                    class SCA_IInputDevice* mousedevice,
104                                    class NG_NetworkDeviceInterface *ndi,
105                                    class SND_IAudioDevice* adi,
106                                    const STR_String& sceneName): 
107         PyObjectPlus(&KX_Scene::Type),
108         m_keyboardmgr(NULL),
109         m_mousemgr(NULL),
110         m_physicsEnvironment(0),
111         m_sceneName(sceneName),
112         m_adi(adi),
113         m_networkDeviceInterface(ndi),
114         m_active_camera(NULL),
115         m_ueberExecutionPriority(0)
116 {
117         m_suspendedtime = 0.0;
118         m_suspendeddelta = 0.0;
119
120         m_activity_culling = false;
121         m_suspend = false;
122         m_isclearingZbuffer = true;
123         m_tempObjectList = new CListValue();
124         m_objectlist = new CListValue();
125         m_parentlist = new CListValue();
126         m_lightlist= new CListValue();
127         m_euthanasyobjects = new CListValue();
128         m_delayReleaseObjects = new CListValue();
129
130         m_logicmgr = new SCA_LogicManager();
131         
132         m_timemgr = new SCA_TimeEventManager(m_logicmgr);
133         m_keyboardmgr = new SCA_KeyboardManager(m_logicmgr,keyboarddevice);
134         m_mousemgr = new SCA_MouseManager(m_logicmgr,mousedevice);
135         
136         SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr);
137         SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr);
138         SCA_RandomEventManager* rndmgr = new SCA_RandomEventManager(m_logicmgr);
139         KX_RayEventManager* raymgr = new KX_RayEventManager(m_logicmgr);
140
141         KX_NetworkEventManager* netmgr = new KX_NetworkEventManager(m_logicmgr, ndi);
142         
143         SCA_JoystickManager *joymgr     = new SCA_JoystickManager(m_logicmgr);
144
145         m_logicmgr->RegisterEventManager(alwaysmgr);
146         m_logicmgr->RegisterEventManager(propmgr);
147         m_logicmgr->RegisterEventManager(m_keyboardmgr);
148         m_logicmgr->RegisterEventManager(m_mousemgr);
149         m_logicmgr->RegisterEventManager(m_timemgr);
150         m_logicmgr->RegisterEventManager(rndmgr);
151         m_logicmgr->RegisterEventManager(raymgr);
152         m_logicmgr->RegisterEventManager(netmgr);
153         m_logicmgr->RegisterEventManager(joymgr);
154
155         m_soundScene = new SND_Scene(adi);
156         MT_assert (m_networkDeviceInterface != NULL);
157         m_networkScene = new NG_NetworkScene(m_networkDeviceInterface);
158         
159         m_rootnode = NULL;
160
161         m_bucketmanager=new RAS_BucketManager();
162
163         m_canvasDesignWidth = 0;
164         m_canvasDesignHeight = 0;
165         
166         m_attrlist = PyDict_New(); /* new ref */
167 }
168
169
170
171 KX_Scene::~KX_Scene()
172 {
173         
174         while (GetRootParentList()->GetCount() > 0) 
175         {
176                 KX_GameObject* parentobj = (KX_GameObject*) GetRootParentList()->GetValue(0);
177                 this->RemoveObject(parentobj);
178         }
179
180         if(m_objectlist)
181                 m_objectlist->Release();
182
183         if (m_parentlist)
184                 m_parentlist->Release();
185         
186         if (m_lightlist)
187                 m_lightlist->Release();
188         
189         if (m_tempObjectList)
190                 m_tempObjectList->Release();
191
192         if (m_euthanasyobjects)
193                 m_euthanasyobjects->Release();
194         if (m_delayReleaseObjects)
195                 m_delayReleaseObjects->Release();
196
197         if (m_logicmgr)
198                 delete m_logicmgr;
199
200         if (m_physicsEnvironment)
201                 delete m_physicsEnvironment;
202
203         if (m_soundScene)
204                 delete m_soundScene;
205
206         if (m_networkScene)
207                 delete m_networkScene;
208         
209         if (m_bucketmanager)
210         {
211                 delete m_bucketmanager;
212         }
213
214         //Py_DECREF(m_attrlist);
215 }
216
217
218
219
220 void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
221 {
222         m_projectionmat = pmat;
223 }
224
225
226
227 RAS_BucketManager* KX_Scene::GetBucketManager()
228 {
229         return m_bucketmanager;
230 }
231
232
233
234 CListValue* KX_Scene::GetObjectList()
235 {
236         return m_objectlist;
237 }
238
239
240
241 CListValue* KX_Scene::GetRootParentList()
242 {
243         return m_parentlist;
244 }
245
246
247
248 CListValue* KX_Scene::GetLightList()
249 {
250         return m_lightlist;
251 }
252
253 SCA_LogicManager* KX_Scene::GetLogicManager()
254 {
255         return m_logicmgr;
256 }
257
258 SCA_TimeEventManager* KX_Scene::GetTimeEventManager()
259 {
260         return m_timemgr;
261 }
262
263
264
265  
266 set<class KX_Camera*>* KX_Scene::GetCameras()
267 {
268         return &m_cameras;
269 }
270
271
272
273 void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings)
274 {
275         m_frame_settings = frame_settings;
276 };
277
278 /**
279  * Return a const reference to the framing 
280  * type set by the above call.
281  * The contents are not guarenteed to be sensible
282  * if you don't call the above function.
283  */
284 const RAS_FrameSettings& KX_Scene::GetFramingType() const 
285 {
286         return m_frame_settings;
287 };      
288
289
290
291 /**
292  * Store the current scene's viewport on the 
293  * game engine canvas.
294  */
295 void KX_Scene::SetSceneViewport(const RAS_Rect &viewport)
296 {
297         m_viewport = viewport;
298 }
299
300
301
302 const RAS_Rect& KX_Scene::GetSceneViewport() const 
303 {
304         return m_viewport;
305 }
306
307
308
309 void KX_Scene::SetWorldInfo(class KX_WorldInfo* worldinfo)
310 {
311         m_worldinfo = worldinfo;
312 }
313
314
315
316 class KX_WorldInfo* KX_Scene::GetWorldInfo()
317 {
318         return m_worldinfo;
319 }
320
321
322
323 SND_Scene* KX_Scene::GetSoundScene()
324 {
325         return m_soundScene;
326 }
327
328 const STR_String& KX_Scene::GetName()
329 {
330         return m_sceneName;
331 }
332
333
334 void KX_Scene::Suspend()
335 {
336         m_suspend = true;
337 }
338
339 void KX_Scene::Resume()
340 {
341         m_suspend = false;
342 }
343
344 void KX_Scene::SetActivityCulling(bool b)
345 {
346         m_activity_culling = b;
347 }
348
349 bool KX_Scene::IsSuspended()
350 {
351         return m_suspend;
352 }
353
354 bool KX_Scene::IsClearingZBuffer()
355 {
356         return m_isclearingZbuffer;
357 }
358
359 void KX_Scene::EnableZBufferClearing(bool isclearingZbuffer)
360 {
361         m_isclearingZbuffer = isclearingZbuffer;
362 }
363
364 void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj)
365 {
366         KX_GameObject* orgobj = (KX_GameObject*)gameobj;        
367         NewRemoveObject(orgobj);
368
369         if (node)
370                 delete node;
371 }
372
373 KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CValue* gameobj)
374 {
375         KX_GameObject* orgobj = (KX_GameObject*)gameobj;
376         KX_GameObject* newobj = (KX_GameObject*)orgobj->GetReplica();
377         m_map_gameobject_to_replica.insert(orgobj, newobj);
378
379         // also register 'timers' (time properties) of the replica
380         int numprops = newobj->GetPropertyCount();
381
382         for (int i = 0; i < numprops; i++)
383         {
384                 CValue* prop = newobj->GetProperty(i);
385
386                 if (prop->GetProperty("timer"))
387                         this->m_timemgr->AddTimeProperty(prop);
388         }
389
390         if (node)
391         {
392                 newobj->SetSGNode((SG_Node*)node);
393         }
394         else
395         {
396                 m_rootnode = new SG_Node(newobj,this,KX_Scene::m_callbacks);
397         
398                 // this fixes part of the scaling-added object bug
399                 SG_Node* orgnode = orgobj->GetSGNode();
400                 m_rootnode->SetLocalScale(orgnode->GetLocalScale());
401                 m_rootnode->SetLocalPosition(orgnode->GetLocalPosition());
402                 m_rootnode->SetLocalOrientation(orgnode->GetLocalOrientation());
403
404                 // define the relationship between this node and it's parent.
405                 KX_NormalParentRelation * parent_relation = 
406                         KX_NormalParentRelation::New();
407                 m_rootnode->SetParentRelation(parent_relation);
408
409                 newobj->SetSGNode(m_rootnode);
410         }
411         
412         SG_IObject* replicanode = newobj->GetSGNode();
413 //      SG_Node* rootnode = (replicanode == m_rootnode ? NULL : m_rootnode);
414
415         replicanode->SetSGClientObject(newobj);
416
417         // this is the list of object that are send to the graphics pipeline
418         m_objectlist->Add(newobj);
419         newobj->Bucketize();
420
421         // logic cannot be replicated, until the whole hierarchy is replicated.
422         m_logicHierarchicalGameObjects.push_back(newobj);
423         //replicate controllers of this node
424         SGControllerList        scenegraphcontrollers = orgobj->GetSGNode()->GetSGControllerList();
425         replicanode->RemoveAllControllers();
426         SGControllerList::iterator cit;
427         //int numcont = scenegraphcontrollers.size();
428         
429         for (cit = scenegraphcontrollers.begin();!(cit==scenegraphcontrollers.end());++cit)
430         {
431                 // controller replication is quite complicated
432                 // only replicate ipo and physics controller for now
433
434                 SG_Controller* replicacontroller = (*cit)->GetReplica((SG_Node*) replicanode);
435                 if (replicacontroller)
436                 {
437                         replicacontroller->SetObject(replicanode);
438                         replicanode->AddSGController(replicacontroller);
439                 }
440         }
441         
442         return newobj;
443 }
444
445
446
447 // before calling this method KX_Scene::ReplicateLogic(), make sure to
448 // have called 'GameObject::ReParentLogic' for each object this
449 // hierarchy that's because first ALL bricks must exist in the new
450 // replica of the hierarchy in order to make cross-links work properly
451 // !
452 void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
453 {
454         // also relink the controller to sensors/actuators
455         SCA_ControllerList& controllers = newobj->GetControllers();
456         //SCA_SensorList&     sensors     = newobj->GetSensors();
457         //SCA_ActuatorList&   actuators   = newobj->GetActuators();
458
459         for (SCA_ControllerList::iterator itc = controllers.begin(); !(itc==controllers.end());itc++)
460         {
461                 SCA_IController* cont = (*itc);
462                 cont->SetUeberExecutePriority(m_ueberExecutionPriority);
463                 vector<SCA_ISensor*> linkedsensors = cont->GetLinkedSensors();
464                 vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators();
465
466                 // disconnect the sensors and actuators
467                 cont->UnlinkAllSensors();
468                 cont->UnlinkAllActuators();
469                 
470                 // now relink each sensor
471                 for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++)
472                 {
473                         SCA_ISensor* oldsensor = (*its);
474                         STR_String name = oldsensor->GetName();
475                         //find this name in the list
476                         SCA_ISensor* newsensor = newobj->FindSensor(name);
477                 
478                         if (newsensor)
479                         {
480                                 // relink this newsensor to the controller
481                                 m_logicmgr->RegisterToSensor(cont,newsensor);
482                         }
483                         else
484                         {
485                                 // it can be linked somewhere in the hierarchy or...
486                                 for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin();
487                                 !(git==m_logicHierarchicalGameObjects.end());++git)
488                                 {
489                                         newsensor = (*git)->FindSensor(name);
490                                         if (newsensor)
491                                                 break;
492                                 } 
493
494                                 if (newsensor)
495                                 {
496                                         // relink this newsensor to the controller somewhere else within this
497                                         // hierarchy
498                                         m_logicmgr->RegisterToSensor(cont,newsensor);
499                                 }
500                                 else
501                                 {
502                                         // must be an external sensor, so...
503                                         m_logicmgr->RegisterToSensor(cont,oldsensor);
504                                 }
505                         }
506                 }
507                 
508                 // now relink each actuator
509                 for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());ita++)
510                 {
511                         SCA_IActuator* oldactuator = (*ita);
512                         STR_String name = oldactuator->GetName();
513                         //find this name in the list
514                         SCA_IActuator* newactuator = newobj->FindActuator(name);
515                         if (newactuator)
516                         {
517                                 // relink this newsensor to the controller
518                                 m_logicmgr->RegisterToActuator(cont,newactuator);
519                                 newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
520                         }
521                         else
522                         {
523                                 // it can be linked somewhere in the hierarchy or...
524                                 for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin();
525                                 !(git==m_logicHierarchicalGameObjects.end());++git)
526                                 {
527                                         newactuator= (*git)->FindActuator(name);
528                                         if (newactuator)
529                                                 break;
530                                 } 
531
532                                 if (newactuator)
533                                 {
534                                         // relink this actuator to the controller somewhere else within this
535                                         // hierarchy
536                                         m_logicmgr->RegisterToActuator(cont,newactuator);
537                                         newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
538                                 }
539                                 else
540                                 {
541                                         // must be an external actuator, so...
542                                         m_logicmgr->RegisterToActuator(cont,oldactuator);
543                                 }
544                         }
545                 }
546         }
547 }
548
549
550
551 SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
552                                                                                 class CValue* parentobject,
553                                                                                 int lifespan)
554 {
555
556         m_logicHierarchicalGameObjects.clear();
557         m_map_gameobject_to_replica.clear();
558
559         // todo: place a timebomb in the object, for temporarily objects :)
560         // lifespan of zero means 'this object lives forever'
561         KX_GameObject* originalobj = (KX_GameObject*) originalobject;
562         KX_GameObject* parentobj = (KX_GameObject*) parentobject;
563
564         m_ueberExecutionPriority++;
565
566         // lets create a replica
567         KX_GameObject* replica = (KX_GameObject*) AddNodeReplicaObject(NULL,originalobj);
568
569         if (lifespan > 0)
570         {
571                 // add a timebomb to this object
572                 // for now, convert between so called frames and realtime
573                 m_tempObjectList->Add(replica->AddRef());
574                 replica->SetProperty("::timebomb",new CFloatValue(lifespan*0.02));
575         }
576
577         // add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame)
578         m_parentlist->Add(replica->AddRef());
579
580         // recurse replication into children nodes
581
582         NodeList& children = originalobj->GetSGNode()->GetSGChildren();
583
584         replica->GetSGNode()->ClearSGChildren();
585         for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
586         {
587                 SG_Node* orgnode = (*childit);
588                 SG_Node* childreplicanode = orgnode->GetSGReplica();
589                 replica->GetSGNode()->AddChild(childreplicanode);
590         }
591
592         //      relink any pointers as necessary, sort of a temporary solution
593         vector<KX_GameObject*>::iterator git;
594         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
595         {
596                 (*git)->Relink(&m_map_gameobject_to_replica);
597         }
598
599         // now replicate logic
600         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
601         {
602                 (*git)->ReParentLogic();
603         }
604         
605         // replicate crosslinks etc. between logic bricks
606         for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
607         {
608                 ReplicateLogic((*git));
609         }
610         
611         MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition();
612         replica->NodeSetLocalPosition(newpos);
613
614         MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
615         replica->NodeSetLocalOrientation(newori);
616         
617         // get the rootnode's scale
618         MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
619
620         // set the replica's relative scale with the rootnode's scale
621         replica->NodeSetRelativeScale(newscale);
622
623         if (replica->GetPhysicsController())
624         {
625                 replica->GetPhysicsController()->setPosition(newpos);
626                 replica->GetPhysicsController()->setOrientation(newori.getRotation());
627                 replica->GetPhysicsController()->setScaling(newscale);
628         }
629
630         // here we want to set the relative scale: the rootnode's scale will override all other
631         // scalings, so lets better prepare for it
632
633
634         replica->GetSGNode()->UpdateWorldData(0);
635         replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
636         replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
637         
638         return replica;
639 }
640
641
642
643 void KX_Scene::RemoveObject(class CValue* gameobj)
644 {
645         KX_GameObject* newobj = (KX_GameObject*) gameobj;
646
647         // first disconnect child from parent
648         SG_Node* node = newobj->GetSGNode();
649
650         if (node)
651         {
652                 node->DisconnectFromParent();
653
654                 // recursively destruct
655                 node->Destruct();
656         }
657         newobj->SetSGNode(0);
658 }
659
660 void KX_Scene::DelayedReleaseObject(CValue* gameobj)
661 {
662         m_delayReleaseObjects->Add(gameobj->AddRef());
663 }
664
665
666 void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
667 {
668         //KX_GameObject* newobj = (KX_GameObject*) gameobj;
669         if (!m_euthanasyobjects->SearchValue(gameobj))
670         {
671                 m_euthanasyobjects->Add(gameobj->AddRef());
672         } 
673 }
674
675
676
677 void KX_Scene::NewRemoveObject(class CValue* gameobj)
678 {
679         KX_GameObject* newobj = (KX_GameObject*) gameobj;
680
681         //todo: look at this
682         //GetPhysicsEnvironment()->RemovePhysicsController(gameobj->getPhysicsController());
683
684         // remove all sensors/controllers/actuators from logicsystem...
685         
686         SCA_SensorList& sensors = newobj->GetSensors();
687         for (SCA_SensorList::iterator its = sensors.begin();
688                  !(its==sensors.end());its++)
689         {
690                 m_logicmgr->RemoveSensor(*its);
691         }
692         
693     SCA_ControllerList& controllers = newobj->GetControllers();
694         for (SCA_ControllerList::iterator itc = controllers.begin();
695                  !(itc==controllers.end());itc++)
696         {
697                 (*itc)->UnlinkAllSensors();
698                 (*itc)->UnlinkAllActuators();
699         }
700
701         SCA_ActuatorList& actuators = newobj->GetActuators();
702         for (SCA_ActuatorList::iterator ita = actuators.begin();
703                  !(ita==actuators.end());ita++)
704         {
705                 m_logicmgr->RemoveDestroyedActuator(*ita);
706         }
707
708         // now remove the timer properties from the time manager
709         int numprops = newobj->GetPropertyCount();
710
711         for (int i = 0; i < numprops; i++)
712         {
713                 CValue* propval = newobj->GetProperty(i);
714                 if (propval->GetProperty("timer"))
715                 {
716                         m_timemgr->RemoveTimeProperty(propval);
717                 }
718         }
719         
720         newobj->RemoveMeshes();
721         if (m_objectlist->RemoveValue(newobj))
722                 newobj->Release();
723         if (m_tempObjectList->RemoveValue(newobj))
724                 newobj->Release();
725         if (m_parentlist->RemoveValue(newobj))
726                 newobj->Release();
727         if (m_euthanasyobjects->RemoveValue(newobj))
728                 newobj->Release();
729                 
730         if (newobj == m_active_camera)
731         {
732                 m_active_camera->Release();
733                 m_active_camera = NULL;
734         }
735 }
736
737
738
739 void KX_Scene::ReplaceMesh(class CValue* gameobj,void* meshobj)
740 {
741         KX_GameObject* newobj = static_cast<KX_GameObject*>(gameobj);
742         RAS_MeshObject* mesh = static_cast<RAS_MeshObject*>(meshobj);
743
744         const STR_String origMeshName = newobj->GetMesh(0)->GetName();
745
746         if( !newobj || !mesh ) 
747         {
748                 std::cout << "warning: invalid object, mesh will not be replaced" << std::endl;
749                 return;
750         }
751
752         newobj->RemoveMeshes();
753         newobj->AddMesh(mesh);
754
755         bool isDeformer = (newobj->m_isDeformable && mesh->m_class == 1);
756         if(isDeformer)
757         {
758                 /* FindBlendObjByGameObj() can return 0... 
759                         In the case of 0 here,
760                         the replicated object that is calling this function
761                         is some how not in the map. (which is strange because it's added)
762                         So we will search the map by the first mesh name
763                         to try to locate it there. If its still not found 
764                         spit some message rather than crash 
765                 */
766                 Object* blendobj = static_cast<struct Object*>(m_logicmgr->FindBlendObjByGameObj(newobj));
767                 Object* oldblendobj = static_cast<struct Object*>(m_logicmgr->FindBlendObjByGameMeshName(mesh->GetName()));
768         
769                 bool parSkin = blendobj && blendobj->parent && blendobj->parent->type == OB_ARMATURE && blendobj->partype==PARSKEL;
770                 bool releaseParent = true;
771                 KX_GameObject* parentobj = newobj->GetParent();
772
773
774                 // lookup by mesh name if blendobj is 0 
775                 if( !blendobj &&  parentobj )
776                 {
777                         blendobj = static_cast<struct Object*>(m_logicmgr->FindBlendObjByGameMeshName(origMeshName));
778
779                         // replace the mesh on the parent armature 
780                         if( blendobj )
781                                 parSkin = parentobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE;
782
783                         // can't do it 
784                         else 
785                                 std::cout << "warning: child object for " << parentobj->GetName().ReadPtr() 
786                                         << " not found, and can't create!" << std::endl;
787                 }
788
789                 if( blendobj && oldblendobj )
790                 {
791                         isDeformer = (static_cast<Mesh*>(blendobj->data)->dvert != 0);
792                         BL_DeformableGameObject* deformIter =0;
793
794                         // armature parent
795                         if( parSkin && isDeformer )
796                         {
797                                 deformIter = static_cast<BL_DeformableGameObject*>( newobj );
798                                 delete deformIter->m_pDeformer;
799
800                                 BL_SkinDeformer* skinDeformer = new BL_SkinDeformer(
801                                         oldblendobj, blendobj,
802                                         static_cast<BL_SkinMeshObject*>(mesh),
803                                         true,
804                                         static_cast<BL_ArmatureObject*>( parentobj )
805                                 );
806                                 releaseParent= false;
807                                 deformIter->m_pDeformer = skinDeformer;
808                         }
809
810                         // normal deformer
811                         if( !parSkin && isDeformer)
812                         {
813                                 deformIter = static_cast<BL_DeformableGameObject*>( newobj );
814                                 delete deformIter->m_pDeformer;
815
816                                 BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(
817                                         oldblendobj, static_cast<BL_SkinMeshObject*>(mesh)
818                                 );
819
820                                 deformIter->m_pDeformer = meshdeformer;
821                         }
822                 }
823                 // release parent reference if its not being used 
824                 if( releaseParent && parentobj)
825                         parentobj->Release();
826         }
827         newobj->Bucketize();
828 }
829
830
831
832 MT_CmMatrix4x4& KX_Scene::GetViewMatrix()
833 {
834         MT_Scalar cammat[16];
835         m_active_camera->GetWorldToCamera().getValue(cammat);
836         m_viewmat = cammat;
837         return m_viewmat;
838 }
839
840
841
842 MT_CmMatrix4x4& KX_Scene::GetProjectionMatrix()
843 {
844         return m_projectionmat;
845 }
846
847
848 KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
849 {
850         set<KX_Camera*>::iterator it = m_cameras.begin();
851
852         while ( (it != m_cameras.end()) 
853                         && ((*it) != cam) ) {
854           it++;
855         }
856
857         return ((it == m_cameras.end()) ? NULL : (*it));
858 }
859
860
861 KX_Camera* KX_Scene::FindCamera(STR_String& name)
862 {
863         set<KX_Camera*>::iterator it = m_cameras.begin();
864
865         while ( (it != m_cameras.end()) 
866                         && ((*it)->GetName() != name) ) {
867           it++;
868         }
869
870         return ((it == m_cameras.end()) ? NULL : (*it));
871 }
872
873 void KX_Scene::AddCamera(KX_Camera* cam)
874 {
875         m_cameras.insert(cam);
876 }
877
878 KX_Camera* KX_Scene::GetActiveCamera()
879 {       
880         // NULL if not defined
881         return m_active_camera;
882 }
883
884
885 void KX_Scene::SetActiveCamera(KX_Camera* cam)
886 {
887         // only set if the cam is in the active list? Or add it otherwise?
888         if (!FindCamera(cam)){
889                 AddCamera(cam);
890                 if (cam) std::cout << "Added cam " << cam->GetName() << std::endl;
891         } 
892
893         m_active_camera = cam;
894 }
895
896
897
898 void KX_Scene::UpdateMeshTransformations()
899 {
900         // do this incrementally in the future
901         for (int i = 0; i < m_objectlist->GetCount(); i++)
902         {
903                 KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
904                 gameobj->GetOpenGLMatrix();
905 //              gameobj->UpdateNonDynas();
906         }
907 }
908
909 void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam)
910 {
911         int intersect = KX_Camera::INTERSECT;
912         KX_GameObject *gameobj = node->Client()?(KX_GameObject*) node->Client()->GetSGClientObject():NULL;
913         bool dotest = (gameobj && gameobj->GetVisible()) || node->Left() || node->Right();
914         
915         /* If the camera is inside the box, assume intersect. */
916         if (dotest && !node->inside( cam->NodeGetWorldPosition()))
917         {
918                 MT_Scalar radius = node->Radius();
919                 MT_Point3 center = node->Center();
920                 
921                 intersect =  cam->SphereInsideFrustum(center, radius); 
922                 
923                 if (intersect == KX_Camera::INTERSECT)
924                 {
925                         MT_Point3 box[8];
926                         node->get(box);
927                         intersect = cam->BoxInsideFrustum(box);
928                 }
929         }
930
931         switch (intersect)
932         {
933                 case KX_Camera::OUTSIDE:
934                         MarkSubTreeVisible(node, rasty, false, cam);
935                         break;
936                 case KX_Camera::INTERSECT:
937                         if (gameobj)
938                                 MarkVisible(rasty, gameobj,cam);
939                         if (node->Left())
940                                 MarkVisible(node->Left(), rasty,cam);
941                         if (node->Right())
942                                 MarkVisible(node->Right(), rasty,cam);
943                         break;
944                 case KX_Camera::INSIDE:
945                         MarkSubTreeVisible(node, rasty, true,cam);
946                         break;
947         }
948 }
949
950 void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible,KX_Camera* cam)
951 {
952         if (node->Client())
953         {
954                 KX_GameObject *gameobj = (KX_GameObject*) node->Client()->GetSGClientObject();
955                 if (gameobj->GetVisible())
956                 {
957                         if (visible)
958                         {
959                                 int nummeshes = gameobj->GetMeshCount();
960                                 MT_Transform t( cam->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
961         
962                                 
963                                 for (int m=0;m<nummeshes;m++)
964                                 {
965                                         // this adds the vertices to the display list
966                                         (gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode());
967                                 }
968                         }
969                         gameobj->MarkVisible(visible);
970                 }
971         }
972         if (node->Left())
973                 MarkSubTreeVisible(node->Left(), rasty, visible,cam);
974         if (node->Right())
975                 MarkSubTreeVisible(node->Right(), rasty, visible,cam);
976 }
977
978 void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera*  cam)
979 {
980         // User (Python/Actuator) has forced object invisible...
981         if (!gameobj->GetVisible())
982                 return;
983         // If Frustum culling is off, the object is always visible.
984         bool vis = !cam->GetFrustumCulling();
985         
986         // If the camera is inside this node, then the object is visible.
987         if (!vis)
988         {
989                 vis = gameobj->GetSGNode()->inside( GetActiveCamera()->GetCameraLocation() );
990         }
991                 
992         // Test the object's bound sphere against the view frustum.
993         if (!vis)
994         {
995                 MT_Vector3 scale = gameobj->GetSGNode()->GetWorldScaling();
996                 MT_Scalar radius = fabs(scale[scale.closestAxis()] * gameobj->GetSGNode()->Radius());
997                 switch (cam->SphereInsideFrustum(gameobj->NodeGetWorldPosition(), radius))
998                 {
999                         case KX_Camera::INSIDE:
1000                                 vis = true;
1001                                 break;
1002                         case KX_Camera::OUTSIDE:
1003                                 vis = false;
1004                                 break;
1005                         case KX_Camera::INTERSECT:
1006                                 // Test the object's bound box against the view frustum.
1007                                 MT_Point3 box[8];
1008                                 gameobj->GetSGNode()->getBBox(box); 
1009                                 vis = cam->BoxInsideFrustum(box) != KX_Camera::OUTSIDE;
1010                                 break;
1011                 }
1012         }
1013         
1014         if (vis)
1015         {
1016                 int nummeshes = gameobj->GetMeshCount();
1017                 MT_Transform t(cam->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
1018                 
1019                 for (int m=0;m<nummeshes;m++)
1020                 {
1021                         // this adds the vertices to the display list
1022                         (gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode());
1023                 }
1024                 // Visibility/ non-visibility are marked
1025                 // elsewhere now.
1026                 gameobj->MarkVisible();
1027         } else {
1028                 gameobj->MarkVisible(false);
1029         }
1030 }
1031
1032 void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam)
1033 {
1034 // FIXME: When tree is operational
1035 #if 1
1036         // do this incrementally in the future
1037         for (int i = 0; i < m_objectlist->GetCount(); i++)
1038         {
1039                 MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam);
1040         }
1041 #else
1042         if (cam->GetFrustumCulling())
1043                 MarkVisible(m_objecttree, rasty, cam);
1044         else
1045                 MarkSubTreeVisible(m_objecttree, rasty, true, cam);
1046 #endif
1047 }
1048
1049 // logic stuff
1050 void KX_Scene::LogicBeginFrame(double curtime)
1051 {
1052         // have a look at temp objects ...
1053         int lastobj = m_tempObjectList->GetCount() - 1;
1054         
1055         for (int i = lastobj; i >= 0; i--)
1056         {
1057                 CValue* objval = m_tempObjectList->GetValue(i);
1058                 CFloatValue* propval = (CFloatValue*) objval->GetProperty("::timebomb");
1059                 
1060                 if (propval)
1061                 {
1062                         float timeleft = propval->GetNumber() - 1.0/KX_KetsjiEngine::GetTicRate();
1063                         
1064                         if (timeleft > 0)
1065                         {
1066                                 propval->SetFloat(timeleft);
1067                         }
1068                         else
1069                         {
1070                                 DelayedRemoveObject(objval);
1071                                 // remove obj
1072                         }
1073                 }
1074                 else
1075                 {
1076                         // all object is the tempObjectList should have a clock
1077                 }
1078         }
1079         m_logicmgr->BeginFrame(curtime, 1.0/KX_KetsjiEngine::GetTicRate());
1080 }
1081
1082
1083
1084 void KX_Scene::LogicUpdateFrame(double curtime, bool frame)
1085 {
1086         m_logicmgr->UpdateFrame(curtime, frame);
1087 }
1088
1089
1090
1091 void KX_Scene::LogicEndFrame()
1092 {
1093         m_logicmgr->EndFrame();
1094         int numobj = m_euthanasyobjects->GetCount();
1095         int i;
1096         for (i = numobj - 1; i >= 0; i--)
1097         {
1098                 KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i);
1099                 this->RemoveObject(gameobj);
1100         }
1101
1102         numobj= m_delayReleaseObjects->GetCount();
1103         for (i = numobj-1;i>=0;i--)
1104         {
1105                 KX_GameObject* gameobj = (KX_GameObject*)m_delayReleaseObjects->GetValue(i);
1106                 m_delayReleaseObjects->RemoveValue(gameobj);    
1107                 
1108         }
1109         
1110
1111 }
1112
1113
1114
1115 /**
1116   * UpdateParents: SceneGraph transformation update.
1117   */
1118 void KX_Scene::UpdateParents(double curtime)
1119 {
1120 //      int numrootobjects = GetRootParentList()->GetCount();
1121
1122         for (int i=0; i<GetRootParentList()->GetCount(); i++)
1123         {
1124                 KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i);
1125                 parentobj->NodeUpdateGS(curtime,true);
1126         }
1127 }
1128
1129
1130
1131 RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat)
1132 {
1133         return m_bucketmanager->RAS_BucketManagerFindBucket(polymat);
1134 }
1135
1136
1137
1138 void KX_Scene::RenderBuckets(const MT_Transform & cameratransform,
1139                                                          class RAS_IRasterizer* rasty,
1140                                                          class RAS_IRenderTools* rendertools)
1141 {
1142         m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools);
1143 }
1144
1145
1146
1147 void KX_Scene::UpdateObjectActivity(void) 
1148 {
1149         if (m_activity_culling) {
1150                 /* determine the activity criterium and set objects accordingly */
1151                 int i=0;
1152                 
1153                 MT_Point3 camloc = GetActiveCamera()->NodeGetWorldPosition(); //GetCameraLocation();
1154                 
1155                 for (i=0;i<GetObjectList()->GetCount();i++)
1156                 {
1157                         KX_GameObject* ob = (KX_GameObject*) GetObjectList()->GetValue(i);
1158                         
1159                         if (!ob->GetIgnoreActivityCulling()) {
1160                                 /* Simple test: more than 10 away from the camera, count
1161                                  * Manhattan distance. */
1162                                 MT_Point3 obpos = ob->NodeGetWorldPosition();
1163                                 
1164                                 if ( (fabs(camloc[0] - obpos[0]) > m_activity_box_radius)
1165                                          || (fabs(camloc[1] - obpos[1]) > m_activity_box_radius)
1166                                          || (fabs(camloc[2] - obpos[2]) > m_activity_box_radius) )
1167                                 {                       
1168                                         ob->Suspend();
1169                                 } else {
1170                                         ob->Resume();
1171                                 }
1172                         }
1173                 }               
1174         }
1175 }
1176
1177 void KX_Scene::SetActivityCullingRadius(float f)
1178 {
1179         if (f < 0.5)
1180                 f = 0.5;
1181         m_activity_box_radius = f;
1182 }
1183         
1184 NG_NetworkDeviceInterface* KX_Scene::GetNetworkDeviceInterface()
1185 {
1186         return m_networkDeviceInterface;
1187 }
1188
1189 NG_NetworkScene* KX_Scene::GetNetworkScene()
1190 {
1191         return m_networkScene;
1192 }
1193
1194 void KX_Scene::SetNetworkDeviceInterface(NG_NetworkDeviceInterface* newInterface)
1195 {
1196         m_networkDeviceInterface = newInterface;
1197 }
1198
1199 void KX_Scene::SetNetworkScene(NG_NetworkScene *newScene)
1200 {
1201         m_networkScene = newScene;
1202 }
1203
1204
1205 void    KX_Scene::SetGravity(const MT_Vector3& gravity)
1206 {
1207         GetPhysicsEnvironment()->setGravity(gravity[0],gravity[1],gravity[2]);
1208 }
1209
1210 void KX_Scene::SetNodeTree(SG_Tree* root)
1211 {
1212         m_objecttree = root;
1213 }
1214
1215 void KX_Scene::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* physEnv)
1216 {
1217         m_physicsEnvironment = physEnv;
1218
1219         KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, physEnv);
1220         m_logicmgr->RegisterEventManager(touchmgr);
1221         return;
1222 }
1223  
1224 void KX_Scene::setSuspendedTime(double suspendedtime)
1225 {
1226         m_suspendedtime = suspendedtime;
1227 }
1228 double KX_Scene::getSuspendedTime()
1229 {
1230         return m_suspendedtime;
1231 }
1232 void KX_Scene::setSuspendedDelta(double suspendeddelta)
1233 {
1234         m_suspendeddelta = suspendeddelta;
1235 }
1236 double KX_Scene::getSuspendedDelta()
1237 {
1238         return m_suspendeddelta;
1239 }
1240
1241 //----------------------------------------------------------------------------
1242 //Python
1243
1244 PyMethodDef KX_Scene::Methods[] = {
1245         KX_PYMETHODTABLE(KX_Scene, getLightList),
1246         KX_PYMETHODTABLE(KX_Scene, getObjectList),
1247         KX_PYMETHODTABLE(KX_Scene, getName),
1248         
1249         {NULL,NULL} //Sentinel
1250 };
1251
1252 PyTypeObject KX_Scene::Type = {
1253         PyObject_HEAD_INIT(&PyType_Type)
1254                 0,
1255                 "KX_Scene",
1256                 sizeof(KX_Scene),
1257                 0,
1258                 PyDestructor,
1259                 0,
1260                 __getattr,
1261                 __setattr,
1262                 0, //&MyPyCompare,
1263                 __repr,
1264                 0, //&cvalue_as_number,
1265                 0,
1266                 0,
1267                 0,
1268                 0, 0, 0, 0, 0, 0
1269 };
1270
1271 PyParentObject KX_Scene::Parents[] = {
1272         &KX_Scene::Type,
1273                 &CValue::Type,
1274                 NULL
1275 };
1276
1277 PyObject* KX_Scene::_getattr(const STR_String& attr)
1278 {
1279         if (attr == "name")
1280                 return PyString_FromString(GetName());
1281         
1282         if (attr == "active_camera")
1283         {
1284                 KX_Camera *camera = GetActiveCamera();
1285                 camera->AddRef();
1286                 return (PyObject*) camera;
1287         }
1288         
1289         if (attr == "suspended")
1290                 return PyInt_FromLong(m_suspend);
1291         
1292         if (attr == "activity_culling")
1293                 return PyInt_FromLong(m_activity_culling);
1294         
1295         if (attr == "activity_culling_radius")
1296                 return PyFloat_FromDouble(m_activity_box_radius);
1297         
1298         PyObject* value = PyDict_GetItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()));
1299         if (value)
1300         {
1301                 Py_INCREF(value);
1302                 return value;
1303         }
1304         
1305         _getattr_up(PyObjectPlus);
1306 }
1307
1308 int KX_Scene::_delattr(const STR_String &attr)
1309 {
1310         PyDict_DelItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()));
1311         return 0;
1312 }
1313
1314 int KX_Scene::_setattr(const STR_String &attr, PyObject *pyvalue)
1315 {
1316
1317         if (!PyDict_SetItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()), pyvalue))
1318                 return 0;
1319
1320         return PyObjectPlus::_setattr(attr, pyvalue);
1321 }
1322
1323 KX_PYMETHODDEF_DOC(KX_Scene, getLightList,
1324 "getLightList() -> list [KX_Light]\n"
1325 "Returns a list of all lights in the scene.\n"
1326 )
1327 {
1328         m_lightlist->AddRef();
1329         return (PyObject*) m_lightlist;
1330 }
1331
1332 KX_PYMETHODDEF_DOC(KX_Scene, getObjectList,
1333 "getObjectList() -> list [KX_GameObject]\n"
1334 "Returns a list of all game objects in the scene.\n"
1335 )
1336 {
1337         m_objectlist->AddRef();
1338         return (PyObject*) m_objectlist;
1339 }
1340
1341 KX_PYMETHODDEF_DOC(KX_Scene, getName,
1342 "getName() -> string\n"
1343 "Returns the name of the scene.\n"
1344 )
1345 {
1346         return PyString_FromString(GetName());
1347 }