Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

KX_Scene.cpp

Go to the documentation of this file.
00001 
00002 #ifdef WIN32
00003 #pragma warning (disable : 4786)
00004 #endif //WIN32
00005 
00006 #include "KX_Scene.h"
00007 #include "SM_Scene.h"           // sumo physics scene
00008 #include "SM_Object.h"          // sumo physics scene
00009 #include "OpenALScene.h"        // sound scene
00010 #include "SCA_ISystem.h"
00011 #include "ListValue.h"
00012 #include "SCA_LogicManager.h"
00013 #include "SCA_TimeEventManager.h"
00014 #include "SCA_AlwaysEventManager.h"
00015 #include "SCA_RandomEventManager.h"
00016 #include "KX_RayEventManager.h"
00017 #include "KX_TouchEventManager.h"
00018 #include "SCA_KeyboardManager.h"
00019 #include "SCA_MouseManager.h"
00020 #include "SCA_PropertyEventManager.h"
00021 #include "KX_Camera.h"
00022 #include "RAS_MeshObject.h"
00023 #include "RAS_IRasterizer.h"
00024 #include "FloatValue.h"
00025 #include "SCA_IController.h"
00026 #include "SCA_IActuator.h"
00027 #include "SG_Node.h"
00028 #include "SYS_System.h"
00029 #include "SG_Controller.h"
00030 #include "SG_IObject.h"
00031 
00032 void*   KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)

00033 {
00034         return ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
00035 }
00036 
00037 void*   KX_SceneDestructionFunc(SG_IObject* node,void* gameobj,void* scene)

00038 {
00039         return ((KX_Scene*)scene)->RemoveNodeDestructObject(node,(KX_GameObject*)gameobj);
00040 };
00041 
00042 
00043 SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(KX_SceneReplicationFunc,KX_SceneDestructionFunc);
00044 
00045 // temporarily var until there is a button in the userinterface
00046 extern bool gUseVisibilityTemp;
00047 
00048 
00049 
00050 KX_Scene::KX_Scene(SCA_ISystem* system)
00051 :m_kxsystem(system),
00052 m_mousemgr(NULL),
00053 m_keyboardmgr(NULL), 
00054 m_pCamera(NULL),
00055 m_activecam(0),
00056 m_ueberExecutionPriority(0)

00057 {
00058         m_tempObjectList = new CListValue();
00059         m_objectlist = new CListValue();
00060         m_parentlist = new CListValue();
00061         m_lightlist= new CListValue();
00062         m_cameralist= new CListValue();
00063         m_logicmgr = new SCA_LogicManager();
00064 // get commandline params from blender creator
00065 
00066         SYS_SystemHandle syshandle = SYS_GetSystem();
00067         
00068         //const char* name = SYS_GetCommandLineString(syshandle,"teststring","bart");   
00069         //const char* name = SYS_GetCommandLineInt(syshandle,"teststring",512); 
00070 
00071 //      printf(name);
00072         m_timemgr = new SCA_TimeEventManager(m_logicmgr,m_kxsystem);
00073         m_keyboardmgr = new SCA_KeyboardManager(m_logicmgr,m_kxsystem->GetKeyboardDevice());
00074         m_mousemgr = new SCA_MouseManager(m_logicmgr,m_kxsystem->GetMouseDevice());
00075         
00076         m_solidScene = DT_CreateScene();
00077         m_respTable = DT_CreateRespTable();
00078 
00079         SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr);
00080         KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, m_respTable, m_solidScene);
00081         SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr);
00082         SCA_RandomEventManager* rndmgr = new SCA_RandomEventManager(m_logicmgr);
00083         KX_RayEventManager* raymgr = new KX_RayEventManager(m_logicmgr);
00084 
00085         m_logicmgr->RegisterEventManager(alwaysmgr);
00086         m_logicmgr->RegisterEventManager(propmgr);
00087         m_logicmgr->RegisterEventManager(m_keyboardmgr);
00088         m_logicmgr->RegisterEventManager(m_mousemgr);
00089         m_logicmgr->RegisterEventManager(touchmgr);
00090         m_logicmgr->RegisterEventManager(m_timemgr);
00091         m_logicmgr->RegisterEventManager(rndmgr);
00092         m_logicmgr->RegisterEventManager(raymgr);
00093 
00094         m_sumoScene = new SM_Scene();
00095 
00096         m_sumoScene->setSecondaryRespTable(m_respTable);
00097 
00098         m_sndscene = new OpenALScene();
00099         m_sndscene->init();
00100 }
00101 
00102 KX_Scene::~KX_Scene()

00103 {
00104 
00105         // reset old blenderlocations
00106         int numobj = m_objectlist->GetCount();
00107         //for (i=0;i<numobj;i++)
00108         //{
00109         //      ((KX_GameObject*) m_objectlist->GetValue(i))->RestoreBlenderObjectPosition();
00110         //}
00111         
00112 
00113 
00114         // first delete scene, then objects !
00115         if (m_sumoScene)
00116                 delete m_sumoScene;
00117         
00118         if (m_sndscene) {
00119                 m_sndscene->exit();
00120                 delete m_sndscene;
00121         }
00122 
00123         if(m_objectlist)
00124                 m_objectlist->Release();
00125         
00126         if (m_parentlist)
00127                 m_parentlist->Release();
00128         
00129         if (m_lightlist)
00130                 m_lightlist->Release();
00131         
00132         if (m_cameralist)
00133                 m_cameralist->Release();
00134 
00135         if (m_tempObjectList)
00136                 m_tempObjectList->Release();
00137         
00138 
00139         if (m_logicmgr)
00140                 delete m_logicmgr;
00141 
00142         T_MaterialList::iterator im;
00143         for (im = m_materialList.begin(); im != m_materialList.end(); ++im) {
00144                 delete (*im);
00145         }
00146 
00147         T_ShapeList::iterator j;
00148         for (j = m_shapeList.begin(); j != m_shapeList.end(); ++j) {
00149                 delete (*j);
00150         }
00151         
00152 }
00153 
00154 void*                   KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj)

00155 {
00156         KX_GameObject* orgobj = (KX_GameObject*)gameobj;
00157         NewRemoveObject(orgobj);
00158         return NULL;
00159 }
00160 
00161 void*                   KX_Scene::AddNodeReplicaObject(class SG_IObject* node,class CValue* gameobj)

00162 {
00163         KX_GameObject* orgobj = (KX_GameObject*)gameobj;
00164         KX_GameObject* newobj = (KX_GameObject*)orgobj->GetReplica();
00165         
00166         if (node)
00167         {
00168                 //SG_Node* newroot = new SG_Node(newobj,this,KX_SceneReplicationFunc);
00169                 newobj->SetSGNode((SG_Node*)node);
00170                 //newobj->SetSGNode(newroot);
00171         } else
00172         {
00173                 SG_Node* newroot = new SG_Node(newobj,this,KX_Scene::m_callbacks);
00174                 newobj->SetSGNode(newroot);
00175         }
00176 
00177         SG_IObject* orgnode = orgobj->GetSGNode();
00178         SG_IObject* replicanode = newobj->GetSGNode();
00179 
00180         replicanode->SetSGClientObject(newobj);
00181         // this is the list of object that are send to the graphics pipeline
00182         m_objectlist->Add(newobj);
00183         newobj->Bucketize();
00184 
00185         // logic cannot be replicated, until the whole hierarchy is replicated.
00186         m_logicGameObjectSearchMap.insert(CHashedPtr(orgobj),newobj);
00187 
00188         //replicate controllers of this node
00189         SGControllerList        scenegraphcontrollers = orgnode->GetSGControllerList();
00190         replicanode->RemoveAllControllers();
00191         SGControllerList::iterator cit;
00192         int numcont = scenegraphcontrollers.size();
00193 
00194         for (cit = scenegraphcontrollers.begin();!(cit==scenegraphcontrollers.end());++cit)
00195         {
00196                 // controller replication is quite complicated
00197                 // only replicate ipo and physics controller for now
00198                 SG_Controller* replicacontroller = (*cit)->GetReplica();
00199                 if (replicacontroller)
00200                 {
00201                         replicacontroller->SetObject(replicanode);
00202                         replicanode->AddSGController(replicacontroller);
00203                 }
00204                 
00205 
00206         }
00207         
00208         return newobj;
00209 }
00210 
00211 void                    KX_Scene::ReplicateLogic(KX_GameObject* newobj)

00212 {
00213                 // replicate logic stuff
00214         newobj->ReParentLogic();
00215         // also relink the controller to sensors/actuators
00216         
00217         SCA_ControllerList& controllers = newobj->GetControllers();
00218         SCA_SensorList&     sensors     = newobj->GetSensors();
00219         SCA_ActuatorList&   actuators   = newobj->GetActuators();
00220         for (SCA_ControllerList::iterator itc = controllers.begin(); !(itc==controllers.end());itc++)
00221         {
00222                 SCA_IController* cont = (*itc);
00223                 cont->SetUeberExecutePriority(m_ueberExecutionPriority);
00224                 vector<SCA_ISensor*>            linkedsensors =         cont->GetLinkedSensors();
00225                 vector<SCA_IActuator*>  linkedactuators = cont->GetLinkedActuators();
00226 
00227                 // disconnect the sensors and actuators
00228                 cont->UnlinkAllSensors();
00229                 cont->UnlinkAllActuators();
00230                 
00231                 // now relink each sensor
00232                 for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++)
00233                 {
00234                         SCA_ISensor* oldsensor = (*its);
00235                         CCString name = oldsensor->GetName();
00236                         //find this name in the list
00237                         SCA_ISensor* newsensor = newobj->FindSensor(name);
00238                 
00239                         if (newsensor)
00240                         {
00241                                 // relink this newsensor to the controller
00242                                 m_logicmgr->RegisterToSensor(cont,newsensor);
00243 
00244                         } else
00245                         {
00246                                 // it can be linked somewhere in the hierarchy or...
00247                                 int numreplicants = m_logicGameObjectSearchMap.size();
00248                                 int i = 0;
00249                                 do
00250                                 {
00251                                         KX_GameObject* gameobj = *m_logicGameObjectSearchMap.at(i);
00252                                         newsensor = gameobj->FindSensor(name);
00253                                 } while (i<numreplicants && !newsensor);
00254 
00255                                 if (newsensor)
00256                                 {
00257                                         // relink this newsensor to the controller somewhere else within this
00258                                         // hierarchy
00259                                         m_logicmgr->RegisterToSensor(cont,newsensor);
00260                                 } else
00261                                 {
00262                                         // must be an external sensor, so...
00263                                         m_logicmgr->RegisterToSensor(cont,oldsensor);
00264                                 }
00265                         }
00266 
00267                 }
00268                 
00269                 // now relink each actuator
00270                 for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());ita++)
00271                 {
00272                         SCA_IActuator* oldactuator = (*ita);
00273                         CCString name = oldactuator->GetName();
00274                         //find this name in the list
00275                         SCA_IActuator* newactuator = newobj->FindActuator(name);
00276                         if (newactuator)
00277                         {
00278                                 // relink this newsensor to the controller
00279                                 m_logicmgr->RegisterToActuator(cont,newactuator);
00280                                 newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
00281 
00282                         } else
00283                         {
00284 
00285                                 // it can be linked somewhere in the hierarchy or...
00286                                 int numreplicants = m_logicGameObjectSearchMap.size();
00287                                 int i = 0;
00288                                 do
00289                                 {
00290                                         KX_GameObject* gameobj = *m_logicGameObjectSearchMap.at(i);
00291                                         newactuator= gameobj->FindActuator(name);
00292                                 } while (i<numreplicants && !newactuator);
00293 
00294                                 if (newactuator)
00295                                 {
00296                                         // relink this actuator to the controller somewhere else within this
00297                                         // hierarchy
00298                                         m_logicmgr->RegisterToActuator(cont,newactuator);
00299                                         newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
00300                                 } else
00301                                 {
00302                                         
00303                                         // must be an external actuator, so...
00304                                         m_logicmgr->RegisterToActuator(cont,oldactuator);
00305                                 }
00306                                 
00307                                 
00308                         }
00309                 }
00310         }
00311 }
00312 
00313 
00314 SCA_IObject*    KX_Scene::AddReplicaObject(class CValue* gameobj,class CValue* locationobj, int lifespan)

00315 {
00316         m_logicGameObjectSearchMap.clear();
00317 
00318         // todo: place a timebomb in the object, for temporarily objects :)
00319         // lifespan of zero means 'this object lives forever'
00320         KX_GameObject* originalobj = (KX_GameObject*) gameobj;
00321         //KX_GameObject* newobj = (KX_GameObject*)originalobj->GetReplica();
00322 
00323         m_ueberExecutionPriority++;
00324         KX_GameObject* replica = (KX_GameObject*) AddNodeReplicaObject(NULL,originalobj);
00325 
00326         if (lifespan > 0)
00327         {
00328                 // add a timebomb to this object
00329                 // for now, convert between so called frames and realtime
00330                 m_tempObjectList->Add(replica->AddRef());
00331                 replica->SetProperty("::timebomb",new CIntValue(lifespan*0.02));
00332         }
00333 
00334         // add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame)
00335         m_parentlist->Add(replica->AddRef());
00336 
00337         // recurse replication into children nodes
00338 
00339         SpatialList& children = originalobj->GetSGNode()->GetSGChildren();
00340         SG_Node* rootnode = replica->GetSGNode();
00341         rootnode->ClearSGChildren();
00342                 
00343         SpatialList::iterator childit;
00344         for (childit = children.begin();!(childit==children.end());++childit)
00345         {
00346                 SG_Spatial* orgnode = (*childit);
00347                 SG_Spatial* childreplicanode = (SG_Spatial*) orgnode->GetSGReplica();
00348                 replica->GetSGNode()->AddChild(childreplicanode);
00349         }
00350 
00351 
00352         // now replicate logic
00353         int numreplicants = m_logicGameObjectSearchMap.size();
00354         int i;
00355         for (i=0;i<numreplicants;i++)
00356         {
00357                 KX_GameObject* gameobj = *m_logicGameObjectSearchMap.at(i);
00358                 ReplicateLogic(gameobj);
00359         }
00360         
00361 
00362         MT_Point3 newpos = ((KX_GameObject*) locationobj)->NodeGetWorldPosition();
00363         MT_Matrix3x3 newori = ((KX_GameObject*) locationobj)->NodeGetWorldOrientation();
00364         SM_Object* sumoObj = replica->GetSumoObject();
00365         if (sumoObj)
00366         {
00367                 replica->NodeSetLocalPosition(newpos);
00368                 replica->NodeSetLocalOrientation(newori);
00369                 sumoObj->setPosition(newpos);
00370                 sumoObj->setOrientation(newori.getRotation());
00371         } else
00372         {
00373                 replica->NodeSetLocalPosition(newpos);
00374                 replica->NodeSetLocalOrientation(newori);
00375         }
00376         replica->GetSGNode()->UpdateGS(0,true);
00377         
00378         return replica;
00379 };
00380 
00381 
00382 void            KX_Scene::RemoveObject(class CValue* gameobj)

00383 {
00384         KX_GameObject* newobj = (KX_GameObject*) gameobj;
00385         // recursively destruct
00386         newobj->GetSGNode()->Destruct();
00387 
00388 }
00389 void            KX_Scene::NewRemoveObject(class CValue* gameobj)

00390 {
00391         KX_GameObject* newobj = (KX_GameObject*) gameobj;
00392         SM_Object* sumoObj = newobj->GetSumoObject();
00393         if (sumoObj)
00394         {
00395                 this->GetSumoScene()->remove(*sumoObj);
00396         }
00397         // remove all sensors/controllers/actuators from logicsystem...
00398         
00399         SCA_SensorList& sensors = newobj->GetSensors();
00400         for (SCA_SensorList::iterator its = sensors.begin();
00401                  !(its==sensors.end());its++)
00402         {
00403                 m_logicmgr->RemoveSensor(*its);
00404         }
00405         newobj->RemoveMeshes();
00406         m_objectlist->RemoveValue(newobj);
00407         m_tempObjectList->RemoveValue(newobj);
00408         m_parentlist->RemoveValue(newobj);
00409         
00410         
00411 }
00412 
00413 void            KX_Scene::ReplaceMesh(class CValue* gameobj,void* meshobj)

00414 {
00415         KX_GameObject* newobj = (KX_GameObject*) gameobj;
00416         newobj->RemoveMeshes();
00417         newobj->AddMesh((RAS_MeshObject*)meshobj);
00418         newobj->Bucketize();
00419 }
00420 
00421 
00422 CMatrix4x4&     KX_Scene::GetViewMatrix()

00423 {
00424         MT_Scalar cammat[16];
00425         m_pCamera->GetWorldToCamera().getValue(cammat);
00426         m_viewmat = cammat;
00427         return m_viewmat;
00428 }
00429 
00430 CMatrix4x4&     KX_Scene::GetProjectionMatrix()

00431 {
00432         return m_projectionmat;
00433 }
00434 
00435 KX_Camera*      KX_Scene::GetActiveCamera()

00436 {
00437         return m_pCamera;//(KX_Camera*)m_cameralist->GetValue(0);
00438 }
00439 
00440 void    KX_Scene::SetActiveCamera(KX_Camera* cam)

00441 {
00442         m_pCamera = cam;
00443         //m_cameralist->Add(cam);
00444 }
00445 
00446 void  KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty)

00447 {
00448         
00449         int i;
00450         bool visible = !gUseVisibilityTemp;
00451 
00452         // do this incrementally in the future
00453         for (i=0;i<m_objectlist->GetCount();i++)
00454         {
00455                 KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
00456         
00457                 int nummeshes = gameobj->GetMeshCount();
00458                 
00459                 for (int m=0;m<nummeshes;m++)
00460                 {
00461                         (gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode(),rasty);
00462                         
00463                         gameobj->MarkVisible(visible);
00464                 }
00465         }
00466 }       
00467 
00468 
00469 // logic stuff
00470 void    KX_Scene::LogicBeginFrame(double curtime,double deltatime)

00471 {
00472         // have a look at temp objects ...
00473         int i;
00474         for (i=0;i<m_tempObjectList->GetCount();i++)
00475         {
00476                 CValue* objval = m_tempObjectList->GetValue(i);
00477                 CValue* propval = objval->GetProperty("::timebomb");
00478                 if (propval)
00479                 {
00480                         float timeleft = propval->GetNumber() - deltatime;
00481                         if (timeleft > 0)
00482                                 objval->SetProperty("::timebomb",new CFloatValue(timeleft));
00483                         else
00484                         {
00485                                 RemoveObject(objval);
00486                                 // remove obj
00487                         }
00488                 } else
00489                 {
00490                         // all object is the tempObjectList should have a clock
00491                 }
00492         }
00493 
00494 
00495         m_logicmgr->BeginFrame(curtime,deltatime);
00496 }
00497 
00498 void    KX_Scene::LogicUpdateFrame(double curtime,double deltatime)

00499 {
00500         m_logicmgr->UpdateFrame(curtime,deltatime);
00501 };
00502 
00503 void    KX_Scene::LogicEndFrame()

00504 {
00505         m_logicmgr->EndFrame();
00506 }
00507 
00508 

Generated at Thu Feb 1 13:03:06 2001 for Ketsji Game Engine by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000