Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/story_entities/world.cc @ 4324

Last change on this file since 4324 was 4324, checked in by patrick, 19 years ago

orxonox/trunk: added a debug level at the end to be able to experiment a little with new load modules and game ideas

File size: 27.2 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer: Christian Meyer
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
19
20#include "world.h"
21
22#include "orxonox.h"
23
24#include "p_node.h"
25#include "null_parent.h"
26#include "helper_parent.h"
27#include "track_node.h"
28#include "world_entity.h"
29#include "player.h"
30#include "camera.h"
31#include "environment.h"
32#include "skysphere.h"
33#include "skybox.h"
34#include "satellite.h"
35#include "test_entity.h"
36#include "terrain.h"
37#include "light.h"
38#include "text_engine.h"
39
40#include "track_manager.h"
41#include "garbage_collector.h"
42#include "object_manager.h"
43#include "animation_player.h"
44#include "particle_engine.h"
45#include "graphics_engine.h"
46
47#include "command_node.h"
48#include "glmenu_imagescreen.h"
49#include "list.h"
50#include "game_loader.h"
51
52#include "animation3d.h"
53
54#include "substring.h"
55
56#include "factory.h"
57
58#include "projectile.h"
59
60using namespace std;
61
62WorldInterface* WorldInterface::singletonRef = 0;
63
64
65/**
66   \brief private constructor because of singleton
67*/
68WorldInterface::WorldInterface()
69{
70  this->worldIsInitialized = false;
71  this->worldReference = NULL;
72}
73
74/**
75   \brief public deconstructor
76*/
77WorldInterface::~WorldInterface()
78{
79  this->singletonRef = NULL;
80  this->worldIsInitialized = false;
81  this->worldReference = NULL;
82}
83
84/**
85   \brief gets the singleton instance
86   \returns singleton instance
87*/
88WorldInterface* WorldInterface::getInstance()
89{
90  if( singletonRef == NULL)
91    singletonRef = new WorldInterface();
92  return singletonRef;
93}
94
95
96/**
97   \brief initializes the interface
98   \param reference to the world
99
100   if the worldinterface is not initilizes, there wont be any
101   useable interface
102*/
103void WorldInterface::init(World* world)
104{
105  this->worldReference = world;
106  if( world != NULL)
107    {
108      this->worldIsInitialized = true;
109      PRINTF(3)("WorldInterface up and running\n");
110    }
111}
112
113
114/**
115   \brief gets the entity list from the world
116   \return entity list
117*/
118tList<WorldEntity>* WorldInterface::getEntityList()
119{
120  if( this->worldIsInitialized)
121    return this->worldReference->getEntities();
122  PRINT(1)("Someone tried to use the WorldInterface before it has been initizlized! this can result in SEGFAULTs!\n");
123  return NULL;
124}
125
126CREATE_FACTORY(World);
127
128World::World(const TiXmlElement* root)
129{
130  this->constuctorInit("", -1);
131  this->path = NULL;
132 
133  this->loadParams(root);
134}
135
136/**
137    \brief create a new World
138   
139    This creates a new empty world!
140*/
141World::World (char* name)
142{
143  this->path = NULL;
144  this->constuctorInit(name, -1);
145  //NullParent* np = NullParent::getInstance();
146}
147
148/**
149   \brief creates a new World...
150   \param worldID with this ID
151*/
152World::World (int worldID)
153{
154  this->path = NULL;
155  this->constuctorInit(NULL, worldID);
156}
157
158/**
159    \brief remove the World from memory
160   
161    delete everything explicitly, that isn't contained in the parenting tree!
162    things contained in the tree are deleted automaticaly
163*/
164World::~World ()
165{
166  PRINTF(3)("World::~World() - deleting current world\n");
167  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
168  cn->unbind(this->localPlayer);
169  cn->reset();
170
171  delete WorldInterface::getInstance();
172  delete this->nullParent;
173  delete this->entities;
174  delete this->lightMan;
175  delete this->trackManager;
176  delete this->particleEngine;
177  TextEngine::getInstance()->flush();
178  delete AnimationPlayer::getInstance(); // this should be at the end of the unloading sequence.
179  //delete garbagecollecor
180  //delete animator
181
182  LoadClassDescription::printAll();
183
184  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
185}
186
187/**
188   \brief initializes the world.
189
190   set all stuff here that is world generic and does not use to much memory
191   because the real init() function StoryEntity::init() will be called
192   shortly before start of the game. 
193   since all worlds are initiated/referenced before they will be started.
194   NO LEVEL LOADING HERE - NEVER!
195*/
196void World::constuctorInit(char* name, int worldID)
197{
198  this->setClassID(CL_WORLD, "World");
199
200  //this->worldName = name;
201  //this->worldName = new char[strlen(name)+1];
202  //strcpy(this->worldName, name);
203  this->debugWorldNr = worldID;
204  this->entities = new tList<WorldEntity>();
205}
206
207void World::loadParams(const TiXmlElement* root)
208{
209  const char *string;
210  char *name;
211  int id;
212
213  PRINTF0("Creating a World\n");
214
215  LoadParam<World>(root, "identifier", this, &World::setStoryID)
216    .describe("Sets the StoryID of this world");
217  LoadParam<World>(root, "nextid", this, &World::setNextStoryID)
218    .describe("Sets the ID of the next world");
219  LoadParam<World>(root, "path", this, &World::setPath)
220    .describe("The Filename of this World (relative from the data-dir)");
221
222
223  /* 
224  // identifier
225  string = grabParameter( root, "identifier");
226  if( string == NULL || sscanf(string, "%d", &id) != 1)
227  {
228  PRINTF0("World is missing a proper 'identifier'\n");
229  this->setStoryID( -1);
230  }
231  else setStoryID( id);
232
233  // next id
234  string = grabParameter( root, "nextid");
235  if( string == NULL || sscanf(string, "%d", &id) != 1)
236  {
237  PRINTF0("World is missing a proper 'nextid'\n");
238  this->setStoryID( -1);
239  }
240  else setNextStoryID( id);
241 
242
243  // path
244  string = grabParameter( root, "path");
245  if( string == NULL)
246  {
247  PRINTF0("World is missing a proper 'path'\n");
248  this->setPath( NULL);
249  }
250  else
251  {
252  name = new char[strlen(string + 2)];
253  strcpy( name, string);
254  this->setPath( name);
255  }
256  */
257}
258
259
260/**
261   \brief this is executed before load
262
263   since the load function sometimes needs data, that has been init before
264   the load and after the proceeding storyentity has finished
265*/
266ErrorMessage World::preLoad()
267{
268  /* init the world interface */
269  WorldInterface* wi = WorldInterface::getInstance();
270  wi->init(this);
271  this->garbageCollector = GarbageCollector::getInstance();
272
273  this->particleEngine = ParticleEngine::getInstance();
274  this->trackManager = TrackManager::getInstance();
275  this->lightMan = LightManager::getInstance();
276  this->nullParent = NullParent::getInstance ();
277  this->nullParent->setName ("NullParent");
278
279  AnimationPlayer::getInstance(); // initializes the animationPlayer
280
281  this->localCamera = new Camera();
282  this->localCamera->setName ("Camera");
283 
284  GraphicsEngine::getInstance()->displayFPS(true);
285}
286
287
288/**
289   \brief loads the World by initializing all resources, and set their default values.
290*/
291ErrorMessage World::load()
292{       
293  PRINTF(3)("> Loading world: '%s'\n", getPath());
294  TiXmlElement* element;
295  GameLoader* loader = GameLoader::getInstance();
296 
297  if( getPath() == NULL)
298    {
299      PRINTF(1)("World has no path specified for loading");
300      this->loadDebugWorld(this->getStoryID());
301      return (ErrorMessage){213,"Path not specified","World::load()"};
302    }
303 
304  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
305  // load the campaign document
306  if( !XMLDoc->LoadFile()) 
307  {
308    // report an error
309    PRINTF(1)("loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
310    delete XMLDoc;
311    return (ErrorMessage){213,"XML File parsing error","World::load()"};
312  }
313 
314  // check basic validity
315  TiXmlElement* root = XMLDoc->RootElement();
316  assert( root != NULL);
317 
318  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
319    {
320      // report an error
321      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
322      delete XMLDoc;
323      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
324    }
325 
326  // load the parameters
327  // name
328  char* temp;
329  const char* string = grabParameter( root, "name");
330  if( string == NULL)
331    {
332      PRINTF(2)("World is missing a proper 'name'\n");
333      string = "Unknown";
334      temp = new char[strlen(string + 2)];
335      strcpy( temp, string);
336      this->worldName = temp;
337    }
338  else
339    {
340      temp = new char[strlen(string + 2)];
341      strcpy( temp, string);
342      this->worldName = temp;
343    }
344  ////////////////
345  // LOADSCREEN //
346  ////////////////
347  element = root->FirstChildElement("LoadScreen");
348  if (element == NULL)
349    {
350      PRINTF(2)("no LoadScreen specified, loading default\n");
351
352      glmis->setBackgroundImage("pictures/load_screen.jpg");
353      this->glmis->setMaximum(8);
354      this->glmis->draw();
355    }
356  else
357    {
358      this->glmis->loadParams(element);
359      this->glmis->draw();
360    }
361  this->glmis->draw();
362  // find WorldEntities
363  element = root->FirstChildElement("WorldEntities");
364 
365  if( element == NULL)
366    {
367      PRINTF(1)("World is missing 'WorldEntities'\n");
368    }
369  else
370    {
371      element = element->FirstChildElement();
372      // load Players/Objects/Whatever
373      PRINTF(4)("Loading WorldEntities\n");
374      while( element != NULL)
375        {
376          WorldEntity* created = (WorldEntity*) loader->fabricate( element);
377          if( created != NULL) this->spawn( created);
378          // if we load a 'Player' we use it as localPlayer
379          //todo do this more elegant
380          if( element->Value() != NULL && !strcmp( element->Value(), "Player")) localPlayer = (Player*) created;
381          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
382          element = element->NextSiblingElement();
383          glmis->step(); //! \todo temporary
384        }
385      PRINTF(4)("Done loading WorldEntities\n");
386    }
387 
388  // find Track
389  element = root->FirstChildElement( "Track");
390  if( element == NULL)
391    {
392      PRINTF(0)("World is missing a 'Track'\n");
393    }
394  else
395    {   
396      //load track
397      PRINTF(4)("Loading Track\n");
398
399      trackManager->load( element);
400      trackManager->finalize();
401    }
402 
403  // free the XML data
404
405  delete XMLDoc;
406  /* GENERIC LOADING PROCESS FINISHED */
407 
408  // bind input
409  Orxonox *orx = Orxonox::getInstance ();
410  orx->getLocalInput()->bind (localPlayer);
411 
412  // bind camera
413  //this->localCamera->bind (localPlayer);
414  this->localPlayer->addChild (this->localCamera);
415     
416
417  lightMan->setAmbientColor(.1,.1,.1);
418  lightMan->addLight();
419  //      lightMan->setAttenuation(1.0, .01, 0.0);
420  //      lightMan->setDiffuseColor(1,1,1);
421  //  lightMan->addLight(1);
422  //  lightMan->setPosition(20, 10, -20);
423  //  lightMan->setDiffuseColor(0,0,0);
424  //lightMan->debug();
425  lightMan->setPosition(-5.0, 10.0, -40.0);
426 
427  //        trackManager->setBindSlave(env);
428  PNode* tn = trackManager->getTrackNode();
429  tn->addChild(this->localPlayer);
430 
431  //localCamera->setParent(TrackNode::getInstance());
432  tn->addChild(this->localCamera);
433  localCamera->lookAt(tn);
434  localCamera->setMode(PNODE_MOVEMENT);
435  this->localPlayer->setMode(PNODE_ALL);
436  Vector* cameraOffset = new Vector (0, 5, -10);
437  trackManager->condition(2, LEFTRIGHT, this->localPlayer);
438 
439  this->sky->setParent(this->localCamera);
440
441  // initialize debug coord system
442  objectList = glGenLists(1);
443  glNewList (objectList, GL_COMPILE);
444 
445  //trackManager->drawGraph(.01);
446  //trackManager->debug(2);
447  glEndList();
448
449  terrain = new Terrain("worlds/newGround.obj");
450  terrain->setRelCoor(Vector(0,-10,0));
451  this->spawn(terrain);
452
453
454
455  ParticleSystem* system = new ParticleSystem(1000, PARTICLE_SPRITE);
456  system->setLifeSpan(.5);
457  system->setConserve(.99);
458  system->setRadius(2, 0, 2, 0);
459
460  ParticleEmitter* emitter = new ParticleEmitter(Vector(-1, 0, 0), M_PI_4, 100, .05);
461  emitter->setParent(this->localPlayer);
462 
463  particleEngine->addConnection(emitter, system);
464
465  WorldEntity* testEntity = new TestEntity();
466  //testEntity->setRelCoor(Vector(570, 10, -15));
467  testEntity->setRelCoor(Vector(25, -10, -20));
468  testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
469  this->spawn(testEntity);
470  this->localPlayer->addChild(testEntity);
471}
472
473
474
475void World::loadDebugWorld(int worldID)
476{
477  printf("ajsdflkajs;dlfaj;slfja;lsjf;lajsf;la;sdfkja;lskdjfashdfklajshdflkjasdfh\n");
478  /*monitor progress*/
479  this->glmis->step();
480  // stuff beyond this point remains to be loaded properly
481
482  // initializing the TrackManager
483  this->trackManager = TrackManager::getInstance();
484  //trackManager->addPoint(Vector(0,0,0));
485  trackManager->addPoint(Vector(150, -35, 5));
486  trackManager->addPoint(Vector(200,-35, 5));
487  trackManager->addPoint(Vector(250, -35, 5));
488  trackManager->addPoint(Vector(320,-33,-.55));
489  trackManager->setDuration(1);
490  trackManager->setSavePoint();
491
492  trackManager->addPoint(Vector(410, 0, 0));
493  trackManager->addPoint(Vector(510, 20, -10));
494  trackManager->addPoint(Vector(550, 20, -10));
495  trackManager->addPoint(Vector(570, 20, -10));
496  trackManager->setDuration(2);
497     
498  trackManager->forkS("testFork1,testFork2");
499  trackManager->workOn("testFork1");
500  trackManager->addPoint(Vector(640, 25, -30));
501  trackManager->addPoint(Vector(700, 40, -120));
502  trackManager->addPoint(Vector(800, 50, -150));
503  trackManager->addPoint(Vector(900, 60, -100));
504  trackManager->addPoint(Vector(900, 60, -70));
505  trackManager->addPoint(Vector(990, 65, -15));
506  trackManager->addPoint(Vector(1050, 65, -10));
507  trackManager->addPoint(Vector(1100, 65, -20));
508  trackManager->setDuration(4);
509
510  trackManager->workOn("testFork2");
511  trackManager->addPoint(Vector(640, 25, 20));
512  trackManager->addPoint(Vector(670, 50, 120));
513  trackManager->addPoint(Vector(700, 70, 80));
514  trackManager->addPoint(Vector(800, 70, 65));
515  trackManager->addPoint(Vector(850, 65, 65));
516  trackManager->addPoint(Vector(920, 35, 40));
517  trackManager->addPoint(Vector(945, 40, 40));
518  trackManager->addPoint(Vector(970, 24, 40));
519  trackManager->addPoint(Vector(1000, 40, -7));
520  trackManager->setDuration(4);
521     
522     
523  trackManager->joinS("testFork1,testFork2");
524       
525  trackManager->addPoint(Vector(1200, 60, -50));
526  trackManager->addPoint(Vector(1300, 50, -50));
527  trackManager->addPoint(Vector(1400, 40, -50));
528  trackManager->addPoint(Vector(1500, 40, -60));
529  trackManager->addPoint(Vector(1600, 35, -55));
530  trackManager->addPoint(Vector(1700, 45, -40));
531  trackManager->addPoint(Vector(1750, 60, -40));
532  trackManager->addPoint(Vector(1770, 80, -40));
533  trackManager->addPoint(Vector(1800, 100, -40));
534  trackManager->setDuration(10);
535 
536  trackManager->finalize();
537 
538
539  // LIGHT initialisation
540  lightMan->setAmbientColor(.1,.1,.1);
541  lightMan->addLight();
542  lightMan->debug();
543
544  switch(this->debugWorldNr)
545    {
546      /*
547        this loads the hard-coded debug world. this only for simplicity and will be
548        removed by a reald world-loader, which interprets a world-file.
549        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
550        make whatever you want...
551      */
552    case DEBUG_WORLD_0:
553      {
554        lightMan->setPosition(-5.0, 10.0, -40.0);
555
556
557        // create a player
558        this->localPlayer = new Player ();
559        this->localPlayer->setName ("player");
560        this->spawn (this->localPlayer);
561        /*monitor progress*/
562        //this->glmis->step();
563        this->glmis->step();
564
565        // bind input
566        Orxonox *orx = Orxonox::getInstance ();
567        orx->getLocalInput()->bind (this->localPlayer);
568           
569        // bind camera
570        this->localCamera = new Camera();
571        this->localCamera->setName ("camera");
572           
573        /*monitor progress*/
574        this->glmis->step();
575
576
577        // Create SkySphere
578        this->sky = new Skysphere("pictures/sky-replace.jpg");
579        this->sky->setName("SkySphere");
580        this->spawn(this->sky);
581        this->localCamera->addChild(this->sky);
582        this->sky->setMode(PNODE_MOVEMENT);
583        /*monitor progress*/
584        this->glmis->step();
585
586
587        terrain = new Terrain("worlds/newGround.obj");
588        terrain->setRelCoor(Vector(0,-10,0));
589        this->spawn(terrain);
590        /*monitor progress*/
591        this->glmis->step();
592
593        PNode* tn = trackManager->getTrackNode();
594        tn->addChild(this->localPlayer);
595        this->localCamera->lookAt(tn);
596
597
598        tn->addChild(this->localCamera);
599        this->localPlayer->setMode(PNODE_ALL);
600        trackManager->condition(2, LEFTRIGHT, this->localPlayer);
601        this->glmis->step();
602        break;
603      }
604    case DEBUG_WORLD_1:
605      {
606
607        break;
608      }
609    case DEBUG_WORLD_2:
610      {
611
612        break;
613      }
614    default:
615      break;
616    }
617}
618
619
620
621/**
622   \brief initializes a new World shortly before start
623
624   this is the function, that will be loaded shortly before the world is
625   started
626*/
627ErrorMessage World::init()
628{
629  this->bPause = false;
630  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
631  cn->addToWorld(this);
632  cn->enable(true);
633}
634
635
636/**
637   \brief starts the World
638*/
639ErrorMessage World::start()
640{
641  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
642  this->bQuitOrxonox = false;
643  this->bQuitCurrentGame = false;
644  this->mainLoop();
645}
646
647/**
648   \brief stops the world.
649
650   This happens, when the player decides to end the Level.
651*/
652ErrorMessage World::stop()
653{
654  PRINTF(3)("World::stop() - got stop signal\n");
655  this->bQuitCurrentGame = true;
656}
657
658/**
659   \brief pauses the Game
660*/
661ErrorMessage World::pause()
662{
663  this->isPaused = true;
664}
665
666/**
667   \brief ends the pause Phase
668*/
669ErrorMessage World::resume()
670{
671  this->isPaused = false;
672}
673
674/**
675   \brief destroys the World
676*/
677ErrorMessage World::destroy()
678{
679
680}
681
682/**
683   \brief shows the loading screen
684*/
685void World::displayLoadScreen ()
686{
687  PRINTF(3)("World::displayLoadScreen - start\n"); 
688 
689  //GLMenuImageScreen*
690  this->glmis = new GLMenuImageScreen();
691  this->glmis->init();
692  this->glmis->setMaximum(8);
693  //  this->glmis->draw();
694 
695  PRINTF(3)("World::displayLoadScreen - end\n"); 
696}
697
698/**
699   \brief removes the loadscreen, and changes over to the game
700
701   \todo take out the delay
702*/
703void World::releaseLoadScreen ()
704{
705  PRINTF(3)("World::releaseLoadScreen - start\n"); 
706  this->glmis->setValue(this->glmis->getMaximum());
707  PRINTF(3)("World::releaseLoadScreen - end\n"); 
708  delete this->glmis;
709}
710
711
712/**
713   \brief gets the list of entities from the world
714   \returns entity list
715*/
716tList<WorldEntity>* World::getEntities()
717{
718  return this->entities;
719}
720
721
722/**
723   \brief this returns the current game time
724   \returns elapsed game time
725*/
726double World::getGameTime()
727{
728  return this->gameTime;
729}
730
731
732/**
733    \brief checks for collisions
734   
735    This method runs through all WorldEntities known to the world and checks for collisions
736    between them. In case of collisions the collide() method of the corresponding entities
737    is called.
738*/
739void World::collide ()
740{
741  /*
742  List *a, *b;
743  WorldEntity *aobj, *bobj;
744   
745  a = entities;
746 
747  while( a != NULL)
748    {
749      aobj = a->nextElement();
750      if( aobj->bCollide && aobj->collisioncluster != NULL)
751        {
752          b = a->nextElement();
753          while( b != NULL )
754            {
755              bobj = b->nextElement();
756              if( bobj->bCollide && bobj->collisioncluster != NULL )
757                {
758                  unsigned long ahitflg, bhitflg;
759                  if( check_collision ( &aobj->place, aobj->collisioncluster,
760                                        &ahitflg, &bobj->place, bobj->collisioncluster,
761                                        &bhitflg) );
762                  {
763                    aobj->collide (bobj, ahitflg, bhitflg);
764                    bobj->collide (aobj, bhitflg, ahitflg);
765                  }
766                }
767              b = b->nextElement();
768            }
769        }
770      a = a->enumerate();
771    }
772  */
773}
774
775/**
776    \brief runs through all entities calling their draw() methods
777*/
778void World::draw ()
779{
780  /* draw entities */
781  WorldEntity* entity;
782  glLoadIdentity();
783
784  //entity = this->entities->enumerate();
785  tIterator<WorldEntity>* iterator = this->entities->getIterator();
786  entity = iterator->nextElement();
787  while( entity != NULL ) 
788    { 
789      if( entity->bDraw ) entity->draw();
790      //entity = this->entities->nextElement();
791      entity = iterator->nextElement();
792    }
793  delete iterator;
794 
795  glCallList (objectList);
796
797  TextEngine::getInstance()->draw();
798  particleEngine->draw(this->dtS); //!< \todo should be dts like in the Trunk;
799
800  lightMan->draw(); // must be at the end of the drawing procedure, otherwise Light cannot be handled as PNodes //
801}
802
803
804/**
805   \brief function to put your own debug stuff into it. it can display informations about
806   the current class/procedure
807*/
808void World::debug()
809{
810  PRINTF(2)("debug() - starting debug\n");
811  PNode* p1 = NullParent::getInstance ();
812  PNode* p2 = new PNode (Vector(2, 2, 2), p1);
813  PNode* p3 = new PNode (Vector(4, 4, 4), p1);
814  PNode* p4 = new PNode (Vector(6, 6, 6), p2);
815
816  p1->debug ();
817  p2->debug ();
818  p3->debug ();
819  p4->debug ();
820
821  p1->shiftCoor (Vector(-1, -1, -1));
822
823  printf("World::debug() - shift\n");
824  p1->debug ();
825  p2->debug ();
826  p3->debug ();
827  p4->debug ();
828 
829  p1->update (0);
830
831  printf ("World::debug() - update\n");
832  p1->debug ();
833  p2->debug ();
834  p3->debug ();
835  p4->debug ();
836
837  p2->shiftCoor (Vector(-1, -1, -1));
838  p1->update (0);
839
840  p1->debug ();
841  p2->debug ();
842  p3->debug ();
843  p4->debug ();
844
845  p2->setAbsCoor (Vector(1,2,3));
846
847
848 p1->update (0);
849
850  p1->debug ();
851  p2->debug ();
852  p3->debug ();
853  p4->debug ();
854
855  delete p1;
856 
857 
858  /*
859  WorldEntity* entity;
860  printf("counting all entities\n");
861  printf("World::debug() - enumerate()\n");
862  entity = entities->enumerate(); 
863  while( entity != NULL )
864    {
865      if( entity->bDraw ) printf("got an entity\n");
866      entity = entities->nextElement();
867    }
868  */
869}
870
871
872/**
873  \brief main loop of the world: executing all world relevant function
874
875  in this loop we synchronize (if networked), handle input events, give the heart-beat to
876  all other member-entities of the world (tick to player, enemies etc.), checking for
877  collisions drawing everything to the screen.
878*/
879void World::mainLoop()
880{
881  this->lastFrame = SDL_GetTicks ();
882  PRINTF(3)("World::mainLoop() - Entering main loop\n");
883  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
884    {
885      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
886      // Network
887      this->synchronize ();
888      // Process input
889      this->handleInput ();
890      if( this->bQuitCurrentGame || this->bQuitOrxonox)
891          break;
892      // Process time
893      this->tick ();
894      // Update the state
895      this->update ();     
896      // Process collision
897      this->collide ();
898      // Draw
899      this->display ();
900
901      //      for( int i = 0; i < 5000000; i++) {}
902      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
903    }
904  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
905}
906
907
908/**
909   \brief synchronize local data with remote data
910*/
911void World::synchronize ()
912{
913  // Get remote input
914  // Update synchronizables
915}
916
917
918/**
919   \brief run all input processing
920
921   the command node is the central input event dispatcher. the node uses the even-queue from
922   sdl and has its own event-passing-queue.
923*/
924void World::handleInput ()
925{
926  // localinput
927  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
928  cn->process();
929  // remoteinput
930}
931
932
933/**
934   \brief advance the timeline
935
936   this calculates the time used to process one frame (with all input handling, drawing, etc)
937   the time is mesured in ms and passed to all world-entities and other classes that need
938   a heart-beat.
939*/
940void World::tick ()
941{
942  Uint32 currentFrame = SDL_GetTicks();
943  if(!this->bPause)
944    {
945      this->dt = currentFrame - this->lastFrame;
946     
947      if( this->dt > 0)
948        {
949          float fps = 1000/dt;
950
951          // temporary, only for showing how fast the text-engine is
952          char tmpChar[20];
953          sprintf(tmpChar, "fps: %4.0f", fps);
954        }
955      else
956        {
957          /* the frame-rate is limited to 100 frames per second, all other things are for
958             nothing.
959          */
960          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
961          SDL_Delay(10);
962          this->dt = 10;
963        }
964      //this->timeSlice (dt);
965     
966      /* function to let all entities tick (iterate through list) */
967      this->dtS = (float)this->dt / 1000.0;     
968      this->gameTime += this->dtS;
969      //entity = entities->enumerate();
970      tIterator<WorldEntity>* iterator = this->entities->getIterator();
971      WorldEntity* entity = iterator->nextElement();
972      while( entity != NULL) 
973        { 
974          entity->tick (this->dtS);
975          entity = iterator->nextElement();
976        }
977      delete iterator;
978
979      /* update tick the rest */
980      this->trackManager->tick(this->dt);
981      this->localCamera->tick(this->dt);
982      AnimationPlayer::getInstance()->tick(this->dtS);
983
984      particleEngine->tick(this->dtS);
985      this->garbageCollector->tick(this->dtS);
986         
987      /* actualy the Graphics Engine should tick the world not the other way around...
988         but since we like the things not too complicated we got it this way around
989         until there is need or time to do it the other way around.
990         \todo: GraphicsEngine ticks world: separation of processes and data...
991      */
992      GraphicsEngine::getInstance()->tick(this->dtS);
993    }
994  this->lastFrame = currentFrame;
995}
996
997
998/**
999   \brief this function gives the world a consistant state
1000
1001   after ticking (updating the world state) this will give a constistant
1002   state to the whole system.
1003*/
1004void World::update()
1005{
1006  this->garbageCollector->update();
1007  this->nullParent->update (this->dtS);
1008}
1009
1010
1011/**
1012   \brief render the current frame
1013   
1014   clear all buffers and draw the world
1015*/
1016void World::display ()
1017{
1018  // clear buffer
1019  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1020  // set camera
1021  this->localCamera->apply ();
1022  // draw world
1023  this->draw();
1024  // draw HUD
1025  /* \todo draw HUD */
1026  // flip buffers
1027  SDL_GL_SwapBuffers();
1028  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
1029  //SDL_Flip (screen);
1030}
1031
1032
1033/**
1034   \brief add and spawn a new entity to this world
1035   \param entity to be added
1036*/
1037void World::spawn(WorldEntity* entity)
1038{
1039  this->entities->add (entity);
1040  entity->postSpawn ();
1041}
1042
1043
1044/**
1045   \brief add and spawn a new entity to this world
1046   \param entity to be added
1047   \param absCoor At what coordinates to add this entity.
1048   \param absDir In which direction should it look.
1049*/
1050void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1051{
1052  this->entities->add (entity);
1053
1054  entity->setAbsCoor (*absCoor);
1055  entity->setAbsDir (*absDir);
1056
1057  entity->postSpawn ();
1058}
1059
1060
1061/**
1062   \brief add and spawn a new entity to this world
1063   \param entity to be added
1064   \param entity to be added to (PNode)
1065   \param At what relative  coordinates to add this entity.
1066   \param In which relative direction should it look.
1067*/
1068void World::spawn(WorldEntity* entity, PNode* parentNode, 
1069                  Vector* relCoor, Quaternion* relDir, 
1070                  int parentingMode)
1071{
1072  this->nullParent = NullParent::getInstance();
1073  if( parentNode != NULL)
1074    {
1075      parentNode->addChild (entity);
1076     
1077      entity->setRelCoor (*relCoor);
1078      entity->setRelDir (*relDir);
1079      entity->setMode(parentingMode);
1080     
1081      this->entities->add (entity);
1082     
1083      entity->postSpawn ();
1084    }
1085}
1086
1087
1088
1089/**
1090  \brief commands that the world must catch
1091  \returns false if not used by the world
1092*/
1093bool World::command(Command* cmd)
1094{
1095  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1096  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1097  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1098  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1099  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1100  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1101
1102  return false;
1103}
1104
1105void World::setPath( const char* name)
1106{
1107  if (this->path)
1108    delete this->path;
1109  if (ResourceManager::isFile(name))
1110  {
1111    this->path = new char[strlen(name)+1];
1112    strcpy(this->path, name);
1113  }
1114  else
1115    {
1116      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1117      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1118    }
1119}
1120
1121const char* World::getPath( void)
1122{
1123  return path;
1124}
Note: See TracBrowser for help on using the repository browser.