Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4412 was 4412, checked in by patrick, 19 years ago

orxonox/trunk: now shooting and weapon change work again

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