Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the SoundEngine into the Trunk.
merged file by file, but merged all the files in favor of the new trunk

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