Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/physics/src/story_entities/world.cc @ 4332

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

orxonox/branches/physics: merged the trunk back to the physics-branche
merged with command:
svn merge -r 4301:HEAD trunk/ branches/physics/
little conflict in particle-system resolved easily

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