Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: one can now also tell Singleton-classes

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  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
491  // Creating a Test Particle Emitter
492  ParticleEmitter* emitter = new ParticleEmitter(Vector(-1, 0, 0), M_PI_4, 400, .5);
493  emitter->setType(EMITTER_DOT);
494  emitter->setSize(20);
495  emitter->setParent(this->localPlayer);
496  emitter->setRelCoor(Vector(-3,0,0));
497
498  Field* gravity = new Gravity();
499  gravity->setMagnitude(10.0);
500  gravity->setParent(this->localCamera->getTarget());
501
502  // Add the Flow from the Emitter into the System
503  particleEngine->addConnection(emitter, system);
504
505  new PhysicsConnection(system, gravity);
506  //    new PhysicsConnection(this->localPlayer, gravity);
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  // printing out some debug stuff
523  NullParent::getInstance()->debug(0);
524  this->localPlayer->whatIs();
525  this->whatIs();
526  GraphicsEngine::getInstance()->whatIs();
527}
528
529
530
531/**
532   \brief loads the debug world: only for experimental stuff
533*/
534void World::loadDebugWorld(int worldID)
535{
536  /*monitor progress*/
537  this->glmis->step();
538  // stuff beyond this point remains to be loaded properly
539
540  // initializing the TrackManager
541  this->trackManager = TrackManager::getInstance();
542  //trackManager->addPointV(Vector(0,0,0));
543  trackManager->addPointV(Vector(150, -35, 5));
544  trackManager->addPointV(Vector(200,-35, 5));
545  trackManager->addPointV(Vector(250, -35, 5));
546  trackManager->addPointV(Vector(320,-33,-.55));
547  trackManager->setDuration(1);
548  trackManager->setSavePoint();
549
550  trackManager->addPointV(Vector(410, 0, 0));
551  trackManager->addPointV(Vector(510, 20, -10));
552  trackManager->addPointV(Vector(550, 20, -10));
553  trackManager->addPointV(Vector(570, 20, -10));
554  trackManager->setDuration(2);
555
556  trackManager->forkS("testFork1,testFork2");
557  trackManager->workOnS("testFork1");
558  trackManager->addPointV(Vector(640, 25, -30));
559  trackManager->addPointV(Vector(700, 40, -120));
560  trackManager->addPointV(Vector(800, 50, -150));
561  trackManager->addPointV(Vector(900, 60, -100));
562  trackManager->addPointV(Vector(900, 60, -70));
563  trackManager->addPointV(Vector(990, 65, -15));
564  trackManager->addPointV(Vector(1050, 65, -10));
565  trackManager->addPointV(Vector(1100, 65, -20));
566  trackManager->setDuration(4);
567
568  trackManager->workOnS("testFork2");
569  trackManager->addPointV(Vector(640, 25, 20));
570  trackManager->addPointV(Vector(670, 50, 120));
571  trackManager->addPointV(Vector(700, 70, 80));
572  trackManager->addPointV(Vector(800, 70, 65));
573  trackManager->addPointV(Vector(850, 65, 65));
574  trackManager->addPointV(Vector(920, 35, 40));
575  trackManager->addPointV(Vector(945, 40, 40));
576  trackManager->addPointV(Vector(970, 24, 40));
577  trackManager->addPointV(Vector(1000, 40, -7));
578
579  trackManager->setDuration(4);
580
581
582  trackManager->joinS("testFork1,testFork2");
583
584  trackManager->addPointV(Vector(1200, 60, -50));
585  trackManager->addPointV(Vector(1300, 50, -50));
586  trackManager->addPointV(Vector(1400, 40, -50));
587  trackManager->addPointV(Vector(1500, 40, -60));
588  trackManager->addPointV(Vector(1600, 35, -55));
589  trackManager->addPointV(Vector(1700, 45, -40));
590  trackManager->addPointV(Vector(1750, 60, -40));
591  trackManager->addPointV(Vector(1770, 80, -40));
592  trackManager->addPointV(Vector(1800, 100, -40));
593  trackManager->setDuration(10);
594
595  trackManager->finalize();
596
597
598  // LIGHT initialisation
599  lightMan->setAmbientColor(.1,.1,.1);
600  lightMan->addLight();
601  lightMan->debug();
602
603  switch(this->debugWorldNr)
604    {
605      /*
606        this loads the hard-coded debug world. this only for simplicity and will be
607        removed by a reald world-loader, which interprets a world-file.
608        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
609        make whatever you want...
610      */
611    case DEBUG_WORLD_0:
612      {
613        lightMan->setPosition(-5.0, 10.0, -40.0);
614
615
616        this->localPlayer = new Player ();
617        this->localPlayer->setName ("player");
618        this->spawn (this->localPlayer);
619        this->localPlayer->setRelCoor(Vector(5,0,0));
620        /*monitor progress*/
621        this->glmis->step();
622
623
624        this->eventHandler->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
625        this->eventHandler->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
626        this->eventHandler->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
627
628        /*
629        Field* testField = new Gravity();
630        testField->setMagnitude(10);
631        new PhysicsConnection(this->localPlayer, testField);
632        */
633
634        // bind camera
635        this->localCamera = new Camera();
636        this->localCamera->setName ("camera");
637        /*monitor progress*/
638        this->glmis->step();
639
640
641        // Create SkySphere
642        this->sky = new Skysphere("pictures/sky-replace.jpg");
643        this->sky->setName("SkySphere");
644        this->spawn(this->sky);
645        this->localCamera->addChild(this->sky);
646        this->sky->setParentMode(PNODE_MOVEMENT);
647        /*monitor progress*/
648        this->glmis->step();
649
650
651        terrain = new Terrain("worlds/newGround.obj");
652        terrain->setRelCoor(Vector(0,-10,0));
653        this->spawn(terrain);
654        /*monitor progress*/
655        this->glmis->step();
656
657        this->pilotNode = new PilotNode();
658        this->spawn(this->pilotNode);
659        this->pilotNode->setAbsCoor(Vector(150, -35, 5));
660        this->pilotNode->addChild(this->localPlayer);
661        this->pilotNode->addChild(this->localCamera);
662        this->localCamera->lookAt(this->localPlayer);
663
664        this->eventHandler->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_UP);
665        this->eventHandler->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_DOWN);
666        this->eventHandler->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_LEFT);
667        this->eventHandler->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_RIGHT);
668        this->eventHandler->subscribe(this->pilotNode, ES_GAME, EV_MOUSE_MOTION);
669
670        // bind input
671        Orxonox *orx = Orxonox::getInstance ();
672        //orx->getLocalInput()->bind (this->pilotNode);
673
674        /*
675        PNode* tn = trackManager->getTrackNode();
676        tn->addChild(this->localPlayer);
677        this->localCamera->lookAt(tn);
678
679        tn->addChild(this->localCamera);
680        this->localPlayer->setParentMode(PNODE_ALL);
681        trackManager->condition(2, LEFTRIGHT, this->localPlayer);
682        */
683        this->glmis->step();
684        break;
685      }
686    case DEBUG_WORLD_1:
687      {
688
689        break;
690      }
691    case DEBUG_WORLD_2:
692      {
693
694        break;
695      }
696    default:
697      break;
698    }
699}
700
701
702
703/**
704   \brief initializes a new World shortly before start
705
706   this is the function, that will be loaded shortly before the world is
707   started
708*/
709ErrorMessage World::init()
710{
711  this->bPause = false;
712  this->pilotNode = NULL;
713}
714
715
716/**
717   \brief starts the World
718*/
719ErrorMessage World::start()
720{
721  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
722  this->bQuitOrxonox = false;
723  this->bQuitCurrentGame = false;
724  this->mainLoop();
725}
726
727/**
728   \brief stops the world.
729
730   This happens, when the player decides to end the Level.
731*/
732ErrorMessage World::stop()
733{
734  PRINTF(3)("World::stop() - got stop signal\n");
735  this->bQuitCurrentGame = true;
736}
737
738/**
739   \brief pauses the Game
740*/
741ErrorMessage World::pause()
742{
743  this->isPaused = true;
744}
745
746/**
747   \brief ends the pause Phase
748*/
749ErrorMessage World::resume()
750{
751  this->isPaused = false;
752}
753
754/**
755   \brief destroys the World
756*/
757ErrorMessage World::destroy()
758{
759
760}
761
762/**
763   \brief shows the loading screen
764*/
765void World::displayLoadScreen ()
766{
767  PRINTF(3)("World::displayLoadScreen - start\n");
768
769  //GLMenuImageScreen*
770  this->glmis = new GLMenuImageScreen();
771  this->glmis->init();
772  this->glmis->setMaximum(8);
773  //  this->glmis->draw();
774
775  PRINTF(3)("World::displayLoadScreen - end\n");
776}
777
778/**
779   \brief removes the loadscreen, and changes over to the game
780
781   \todo take out the delay
782*/
783void World::releaseLoadScreen ()
784{
785  PRINTF(3)("World::releaseLoadScreen - start\n");
786  this->glmis->setValue(this->glmis->getMaximum());
787  PRINTF(3)("World::releaseLoadScreen - end\n");
788  delete this->glmis;
789}
790
791
792/**
793   \brief gets the list of entities from the world
794   \returns entity list
795*/
796tList<WorldEntity>* World::getEntities()
797{
798  return this->entities;
799}
800
801
802/**
803   \brief this returns the current game time
804   \returns elapsed game time
805*/
806double World::getGameTime()
807{
808  return this->gameTime;
809}
810
811
812/**
813    \brief checks for collisions
814
815    This method runs through all WorldEntities known to the world and checks for collisions
816    between them. In case of collisions the collide() method of the corresponding entities
817    is called.
818*/
819void World::collide ()
820{
821  /*
822  List *a, *b;
823  WorldEntity *aobj, *bobj;
824
825  a = entities;
826
827  while( a != NULL)
828    {
829      aobj = a->nextElement();
830      if( aobj->bCollide && aobj->collisioncluster != NULL)
831        {
832          b = a->nextElement();
833          while( b != NULL )
834            {
835              bobj = b->nextElement();
836              if( bobj->bCollide && bobj->collisioncluster != NULL )
837                {
838                  unsigned long ahitflg, bhitflg;
839                  if( check_collision ( &aobj->place, aobj->collisioncluster,
840                                        &ahitflg, &bobj->place, bobj->collisioncluster,
841                                        &bhitflg) );
842                  {
843                    aobj->collide (bobj, ahitflg, bhitflg);
844                    bobj->collide (aobj, bhitflg, ahitflg);
845                  }
846                }
847              b = b->nextElement();
848            }
849        }
850      a = a->enumerate();
851    }
852  */
853}
854
855/**
856    \brief runs through all entities calling their draw() methods
857*/
858void World::draw ()
859{
860  /* draw entities */
861  WorldEntity* entity;
862  glLoadIdentity();
863  //entity = this->entities->enumerate();
864  tIterator<WorldEntity>* iterator = this->entities->getIterator();
865  entity = iterator->nextElement();
866  while( entity != NULL )
867    {
868      if( entity->bDraw ) entity->draw();
869      //entity = this->entities->nextElement();
870      entity = iterator->nextElement();
871    }
872  delete iterator;
873
874  glCallList (objectList);
875
876  particleEngine->draw(); //!< \todo should be dts like in the Trunk;
877
878  TextEngine::getInstance()->draw();
879  lightMan->draw(); // must be at the end of the drawing procedure, otherwise Light cannot be handled as PNodes //
880}
881
882
883/**
884   \brief function to put your own debug stuff into it. it can display informations about
885   the current class/procedure
886*/
887void World::debug()
888{
889  PRINTF(2)("debug() - starting debug\n");
890  PNode* p1 = NullParent::getInstance ();
891  PNode* p2 = new PNode (Vector(2, 2, 2), p1);
892  PNode* p3 = new PNode (Vector(4, 4, 4), p1);
893  PNode* p4 = new PNode (Vector(6, 6, 6), p2);
894
895  p1->debug ();
896  p2->debug ();
897  p3->debug ();
898  p4->debug ();
899
900  p1->shiftCoor (Vector(-1, -1, -1));
901
902  printf("World::debug() - shift\n");
903  p1->debug ();
904  p2->debug ();
905  p3->debug ();
906  p4->debug ();
907
908  p1->update (0);
909
910  printf ("World::debug() - update\n");
911  p1->debug ();
912  p2->debug ();
913  p3->debug ();
914  p4->debug ();
915
916  p2->shiftCoor (Vector(-1, -1, -1));
917  p1->update (0);
918
919  p1->debug ();
920  p2->debug ();
921  p3->debug ();
922  p4->debug ();
923
924  p2->setAbsCoor (Vector(1,2,3));
925
926
927 p1->update (0);
928
929  p1->debug ();
930  p2->debug ();
931  p3->debug ();
932  p4->debug ();
933
934  delete p1;
935
936
937  /*
938  WorldEntity* entity;
939  printf("counting all entities\n");
940  printf("World::debug() - enumerate()\n");
941  entity = entities->enumerate();
942  while( entity != NULL )
943    {
944      if( entity->bDraw ) printf("got an entity\n");
945      entity = entities->nextElement();
946    }
947  */
948}
949
950
951/**
952  \brief main loop of the world: executing all world relevant function
953
954  in this loop we synchronize (if networked), handle input events, give the heart-beat to
955  all other member-entities of the world (tick to player, enemies etc.), checking for
956  collisions drawing everything to the screen.
957*/
958void World::mainLoop()
959{
960  this->lastFrame = SDL_GetTicks ();
961  PRINTF(3)("World::mainLoop() - Entering main loop\n");
962  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
963    {
964      ++this->cycle;
965      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
966      // Network
967      this->synchronize ();
968      // Process input
969      this->handleInput ();
970      if( this->bQuitCurrentGame || this->bQuitOrxonox)
971          break;
972      // Process time
973      this->tick ();
974      // Update the state
975      this->update ();
976      // Process collision
977      this->collide ();
978      // Draw
979      this->display ();
980
981      //      for( int i = 0; i < 5000000; i++) {}
982      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
983    }
984  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
985}
986
987
988/**
989   \brief synchronize local data with remote data
990*/
991void World::synchronize ()
992{
993  // Get remote input
994  // Update synchronizables
995}
996
997
998/**
999   \brief run all input processing
1000
1001   the command node is the central input event dispatcher. the node uses the even-queue from
1002   sdl and has its own event-passing-queue.
1003*/
1004void World::handleInput ()
1005{
1006  // localinput
1007  //CommandNode* cn = Orxonox::getInstance()->getLocalInput();
1008  //cn->process();
1009
1010  EventHandler::getInstance()->process();
1011
1012  // remoteinput
1013}
1014
1015
1016/**
1017   \brief advance the timeline
1018
1019   this calculates the time used to process one frame (with all input handling, drawing, etc)
1020   the time is mesured in ms and passed to all world-entities and other classes that need
1021   a heart-beat.
1022*/
1023void World::tick ()
1024{
1025  Uint32 currentFrame = SDL_GetTicks();
1026  if(!this->bPause)
1027    {
1028      this->dt = currentFrame - this->lastFrame;
1029
1030      if( this->dt > 0)
1031        {
1032          float fps = 1000/dt;
1033
1034          // temporary, only for showing how fast the text-engine is
1035          char tmpChar[20];
1036          sprintf(tmpChar, "fps: %4.0f", fps);
1037        }
1038      else
1039        {
1040          /* the frame-rate is limited to 100 frames per second, all other things are for
1041             nothing.
1042          */
1043          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
1044          SDL_Delay(10);
1045          this->dt = 10;
1046        }
1047      //this->timeSlice (dt);
1048
1049      /* function to let all entities tick (iterate through list) */
1050      this->dtS = (float)this->dt / 1000.0;
1051      this->gameTime += this->dtS;
1052      //entity = entities->enumerate();
1053      tIterator<WorldEntity>* iterator = this->entities->getIterator();
1054      WorldEntity* entity = iterator->nextElement();
1055      while( entity != NULL)
1056        {
1057          entity->tick (this->dtS);
1058          entity = iterator->nextElement();
1059        }
1060      delete iterator;
1061
1062      /* update tick the rest */
1063      this->trackManager->tick(this->dt);
1064      this->localCamera->tick(this->dt);
1065      // tick the engines
1066      AnimationPlayer::getInstance()->tick(this->dtS);
1067      if (this->cycle > 5)
1068        PhysicsEngine::getInstance()->tick(this->dtS);
1069
1070      ParticleEngine::getInstance()->tick(this->dtS);
1071      GarbageCollector::getInstance()->tick(this->dtS);
1072
1073      /** actualy the Graphics Engine should tick the world not the other way around...
1074         but since we like the things not too complicated we got it this way around
1075         until there is need or time to do it the other way around.
1076         \todo: GraphicsEngine ticks world: separation of processes and data...
1077      */
1078      GraphicsEngine::getInstance()->tick(this->dtS);
1079    }
1080  this->lastFrame = currentFrame;
1081}
1082
1083
1084/**
1085   \brief this function gives the world a consistant state
1086
1087   after ticking (updating the world state) this will give a constistant
1088   state to the whole system.
1089*/
1090void World::update()
1091{
1092  this->garbageCollector->update();
1093  this->nullParent->update (this->dtS);
1094
1095  SoundEngine::getInstance()->update();
1096}
1097
1098
1099/**
1100   \brief render the current frame
1101
1102   clear all buffers and draw the world
1103*/
1104void World::display ()
1105{
1106  // clear buffer
1107  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1108  // set camera
1109  this->localCamera->apply ();
1110  // draw world
1111  this->draw();
1112  // draw HUD
1113  /* \todo draw HUD */
1114  // flip buffers
1115  SDL_GL_SwapBuffers();
1116  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
1117  //SDL_Flip (screen);
1118}
1119
1120
1121/**
1122   \brief add and spawn a new entity to this world
1123   \param entity to be added
1124*/
1125void World::spawn(WorldEntity* entity)
1126{
1127  this->entities->add (entity);
1128  entity->postSpawn ();
1129}
1130
1131
1132/**
1133   \brief add and spawn a new entity to this world
1134   \param entity to be added
1135   \param absCoor At what coordinates to add this entity.
1136   \param absDir In which direction should it look.
1137*/
1138void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1139{
1140  this->entities->add (entity);
1141
1142  entity->setAbsCoor (*absCoor);
1143  entity->setAbsDir (*absDir);
1144
1145  entity->postSpawn ();
1146}
1147
1148
1149/**
1150   \brief add and spawn a new entity to this world
1151   \param entity to be added
1152   \param entity to be added to (PNode)
1153   \param At what relative  coordinates to add this entity.
1154   \param In which relative direction should it look.
1155*/
1156void World::spawn(WorldEntity* entity, PNode* parentNode,
1157                  Vector* relCoor, Quaternion* relDir,
1158                  int parentingMode)
1159{
1160  this->nullParent = NullParent::getInstance();
1161  if( parentNode != NULL)
1162    {
1163      parentNode->addChild (entity);
1164
1165      entity->setRelCoor (*relCoor);
1166      entity->setRelDir (*relDir);
1167      entity->setParentMode(parentingMode);
1168
1169      this->entities->add (entity);
1170
1171      entity->postSpawn ();
1172    }
1173}
1174
1175
1176
1177/**
1178  \brief commands that the world must catch
1179  \returns false if not used by the world
1180*/
1181bool World::command(Command* cmd)
1182{
1183  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1184  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1185  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1186  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1187  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1188  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1189  return false;
1190}
1191
1192void World::setPath( const char* name)
1193{
1194  if (this->path)
1195    delete this->path;
1196  if (ResourceManager::isFile(name))
1197  {
1198    this->path = new char[strlen(name)+1];
1199    strcpy(this->path, name);
1200  }
1201  else
1202    {
1203      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1204      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1205    }
1206}
1207
1208const char* World::getPath( void)
1209{
1210  return path;
1211}
Note: See TracBrowser for help on using the repository browser.