Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: smoe small optimizations. now font is in front of particles

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