Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: cleaned up LightManager, this was quite messy….

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