Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: loading Terrain via XML

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