Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: ok… forces now apply to the right objects, but i don't really like the way it works…. we will see….

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