Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: addChild and setParentMode via XML-loading

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