Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged branches/physics back to the trunk
merged with command
svn merge -r 3866:HEAD . ../../trunk/
many conflict that i tried to resolv
@patrick: i hope i did not interfere with your stuff :/

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