Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4501 was 4501, checked in by bensch, 19 years ago

orxonox/trunk: loading of track works just fine now. little problems with the setSavePoint-function

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