Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4593 was 4592, checked in by bensch, 20 years ago

orxonox/trunk: derivations work.
now the only thing to do is specify all the classes, and DO it CLEAN.

@patrick: is it ok, how i treated your ObjectManager??

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