Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/levelloader/src/story_entities/world.cc @ 3530

Last change on this file since 3530 was 3530, checked in by chris, 19 years ago

orxonox/branches/levelloader: Got the system to compile, the basic backbone now runs. What remains to be done is implementing all necessary functions to load all vital classes into a world

File size: 22.0 KB
Line 
1
2/*
3   orxonox - the future of 3D-vertical-scrollers
4
5   Copyright (C) 2004 orx
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2, or (at your option)
10   any later version.
11
12   ### File Specific:
13   main-programmer: Patrick Boenzli
14   co-programmer: Christian Meyer
15*/
16
17#include "world.h"
18#include "world_entity.h"
19#include "track_manager.h"
20#include "player.h"
21#include "command_node.h"
22#include "camera.h"
23#include "environment.h"
24#include "p_node.h"
25#include "null_parent.h"
26#include "helper_parent.h"
27#include "glmenu_imagescreen.h"
28#include "skysphere.h"
29#include "light.h"
30#include "fontset.h"
31#include "factory.h"
32#include "game_loader.h"
33
34using namespace std;
35
36CREATE_FACTORY(World);
37
38World::World( TiXmlElement* root)
39{
40        const char *string;
41        char *name;
42        int id;
43
44        // identifier
45        string = grabParameter( root, "identifier");
46        if( string == NULL || sscanf(string, "%d", &id) != 1)
47        {
48                PRINTF(1)("World is missing a proper 'identifier'\n");
49                this->setStoryID( -1);
50        }
51        else setStoryID( id);
52       
53        // path
54        string = grabParameter( root, "path");
55        if( string == NULL)
56        {
57                PRINTF(1)("World is missing a proper 'path'\n");
58                this->setPath( NULL);
59        }
60        else
61        {
62                name = new char[strlen(string + 2)];
63                strcpy( name, string);
64                this->setPath( name);
65        }
66       
67       
68}
69
70/**
71    \brief create a new World
72   
73    This creates a new empty world!
74*/
75World::World (char* name)
76{
77  this->setClassName ("World");
78  this->worldName = name;
79  this->debugWorldNr = -1;
80  this->entities = new tList<WorldEntity>();
81}
82
83/**
84   \brief creates a new World...
85   \param worldID with this ID
86*/
87World::World (int worldID)
88{
89  this->debugWorldNr = worldID;
90  this->worldName = NULL;
91  this->entities = new tList<WorldEntity>();
92}
93
94/**
95    \brief remove the World from memory
96   
97    delete everything explicitly, that isn't contained in the parenting tree!
98    things contained in the tree are deleted automaticaly
99*/
100World::~World ()
101{
102  printf("World::~World() - deleting current world\n");
103  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
104  cn->unbind(this->localPlayer);
105  cn->reset();
106
107  this->localCamera->destroy();
108  this->nullParent->destroy(); 
109  delete this->skySphere;
110  if( this->worldName) delete this->worldName;
111  if( this->path) delete this->path;
112
113  //delete this->trackManager;
114
115  /*
116  WorldEntity* entity = entities->enumerate(); 
117  while( entity != NULL )
118    {
119      entity->destroy();
120      entity = entities->nextElement();
121    }
122  this->entities->destroy();
123  */
124
125  /* FIX the parent list has to be cleared - not possible if we got the old list also*/
126
127
128  //delete this->entities;
129  //delete this->localCamera;
130  /* this->localPlayer hasn't to be deleted explicitly, it is
131     contained in entities*/
132}
133
134
135/**
136   \brief loads the World by initializing all resources, and set their default values.
137*/
138ErrorMessage World::load()
139{
140        GameLoader* loader = GameLoader::getInstance();
141       
142  if( getPath() == NULL)
143  {
144                PRINTF(1)("World has no path specified for loading");
145                return (ErrorMessage){213,"Path not specified","World::load()"};
146  }
147 
148        TiXmlDocument* XMLDoc = new TiXmlDocument( path);
149        // load the campaign document
150        if( !XMLDoc->LoadFile())
151        {
152                // report an error
153                PRINTF(1)("Error loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
154                delete XMLDoc;
155                return (ErrorMessage){213,"XML File parsing error","World::load()"};
156        }
157       
158        // check basic validity
159        TiXmlElement* root = XMLDoc->RootElement();
160        assert( root != NULL);
161       
162        TiXmlElement* element = root->FirstChildElement( "WorldDataFile");
163       
164        if( root == NULL )
165        {
166                // report an error
167                PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
168                delete XMLDoc;
169                return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
170        }
171       
172        // load the parameters
173                // name
174        char* temp;
175        const char* string = grabParameter( root, "name");
176        if( string == NULL)
177        {
178                PRINTF(1)("World is missing a proper 'name'\n");
179                this->setStoryID( -1);
180        }
181        else
182        {
183                temp = new char[strlen(string + 2)];
184                this->worldName = temp;
185        }
186       
187       
188        // find WorldEntities
189  element = root->FirstChildElement( "WorldEntities");
190 
191  if( element == NULL)
192  {
193                PRINTF(1)("World is missing 'WorldEntities'\n");
194  }
195  else
196  {
197        element = element->FirstChildElement();
198          // load Players/Objects/Whatever
199                while( element != NULL)
200                {
201                        WorldEntity* created = (WorldEntity*) loader->fabricate( element);
202                        if( created != NULL) spawn( created);
203                        element = element->NextSiblingElement();
204                }
205        }
206       
207        // find Track
208  element = root->FirstChildElement( "Track");
209  if( element == NULL)
210  {
211                PRINTF(1)("World is missing a 'Track'\n");
212  }
213  else
214  {     
215        //load track
216        trackManager = TrackManager::getInstance();
217        trackManager->loadTrack( element);
218        }
219 
220       
221        // free the XML data
222        delete XMLDoc;
223       
224  //  BezierCurve* tmpCurve = new BezierCurve();
225  if(this->debugWorldNr != -1)
226    {
227      // initializing Font
228      testFont = new FontSet();
229      testFont->buildFont("../data/pictures/font.tga");
230
231      /*monitor progress*/
232      this->glmis->step();
233
234      /*
235        tmpCurve->addNode(Vector(10,  -1,  -1));
236        tmpCurve->addNode(Vector(10,  -2,   2));
237        tmpCurve->addNode(Vector(10,   3,   3));
238        tmpCurve->addNode(Vector(10,   4,  -4), 0);
239        tmpCurve->addNode(Vector(10,  -1,  -1));
240        tmpCurve->addNode(Vector(10,  -2,   2));
241        tmpCurve->addNode(Vector(10,   3,   3));
242        tmpCurve->addNode(Vector(10,   4,  -4), 0);
243        tmpCurve->debug();
244      */
245      switch(this->debugWorldNr)
246        {
247          /*
248            this loads the hard-coded debug world. this only for simplicity and will be
249            removed by a reald world-loader, which interprets a world-file.
250            if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
251            make whatever you want...
252           */
253        case DEBUG_WORLD_0:
254          {
255            this->nullParent = NullParent::getInstance ();
256            this->nullParent->setName ("NullParent");
257
258            // !\todo old track-system has to be removed
259
260            //create helper for player
261            HelperParent* hp = new HelperParent ();
262            /* the player has to be added to this helper */
263
264            // create a player
265            WorldEntity* myPlayer = new Player ();
266            myPlayer->setName ("player");
267            this->spawn (myPlayer);
268            this->localPlayer = myPlayer;
269            /*monitor progress*/
270            this->glmis->step();           
271
272            // bind input
273            Orxonox *orx = Orxonox::getInstance ();
274            orx->getLocalInput()->bind (myPlayer);
275           
276            // bind camera
277            this->localCamera = new Camera(this);
278            this->localCamera->setName ("camera");
279            this->localCamera->bind (myPlayer);
280            this->localPlayer->addChild (this->localCamera);
281
282            // Create SkySphere
283            skySphere = new Skysphere("../data/pictures/sky-replace.jpg");
284
285            /*monitor progress*/
286            this->glmis->step();
287
288            Vector* es = new Vector (50, 2, 0);
289            Quaternion* qs = new Quaternion ();
290            WorldEntity* env = new Environment();
291            env->setName ("env");
292            this->spawn(env, es, qs);
293           
294            /*monitor progress*/
295            this->glmis->step();
296
297            trackManager->setBindSlave(env);
298
299            break;
300          }
301        case DEBUG_WORLD_1:
302          {
303            /*
304            this->testCurve = new UPointCurve();
305            this->testCurve->addNode(Vector( 0, 0, 0));
306            this->testCurve->addNode(Vector(10, 0, 5));
307            this->testCurve->addNode(Vector(20, -5,-5));
308            this->testCurve->addNode(Vector(30, 5, 10));
309            this->testCurve->addNode(Vector(40, 0,-10));
310            this->testCurve->addNode(Vector(50, 0,-10));
311            */
312
313            this->nullParent = NullParent::getInstance ();
314            this->nullParent->setName ("NullParent");
315
316
317
318            // create a player
319            WorldEntity* myPlayer = new Player();
320            myPlayer->setName ("player");
321            this->spawn(myPlayer);
322            this->localPlayer = myPlayer;           
323           
324            // bind input
325            Orxonox *orx = Orxonox::getInstance();
326            orx->getLocalInput()->bind (myPlayer);
327           
328            // bind camera
329            this->localCamera = new Camera (this);
330            this->localCamera->setName ("camera");
331            this->localCamera->bind (myPlayer); 
332            this->localPlayer->addChild (this->localCamera);
333
334            // Create SkySphere
335            skySphere = new Skysphere("../data/pictures/sky-replace.jpg");
336
337            break;
338
339
340          }
341        default:
342          printf("World::load() - no world with ID %i found", this->debugWorldNr );
343        }
344    }
345  else if(this->worldName != NULL)
346    {
347
348    }
349
350  // initialize debug coord system
351  objectList = glGenLists(1);
352  glNewList (objectList, GL_COMPILE);
353  glLoadIdentity();
354  glColor3f(1.0,0,0);
355  glBegin(GL_QUADS);
356
357  int sizeX = 100;
358  int sizeZ = 80;
359  float length = 1000;
360  float width = 200;
361  float widthX = float (length /sizeX);
362  float widthZ = float (width /sizeZ);
363 
364  float height [sizeX][sizeZ];
365  Vector normal_vectors[sizeX][sizeZ];
366 
367 
368  for ( int i = 0; i<sizeX-1; i+=1)
369    for (int j = 0; j<sizeZ-1;j+=1)
370      //height[i][j] = rand()/20046 + (j-25)*(j-25)/30;
371#ifdef __WIN32__
372      height[i][j]=(sin((float)j/3)*rand()*i/182400)*.5;
373#else
374      height[i][j]=(sin((float)j/3)*rand()*(long)i/6282450500.0)*.5;
375#endif
376
377  //Die Huegel ein wenig glaetten
378  for (int h=1; h<2;h++)
379    for (int i=1;i<sizeX-2 ;i+=1 )
380      for(int j=1;j<sizeZ-2;j+=1)
381        height[i][j]=(height[i+1][j]+height[i][j+1]+height[i-1][j]+height[i][j-1])/4;
382 
383  //Berechnung von normalen Vektoren
384  for(int i=1;i<sizeX-2;i+=1)
385    for(int j=1;j<sizeZ-2 ;j+=1)
386      {
387        Vector v1 = Vector (widthX*(1),      height[i][j],      widthZ*(j) );
388        Vector v2 = Vector (widthX*(i-1),    height[i-1][j],    widthZ*(j));
389        Vector v3 = Vector (widthX*(i),      height[i][j+1],    widthZ*(j+1));
390        Vector v4 = Vector (widthX*(i+1),    height[i+1][j],    widthZ*(j));
391        Vector v5 = Vector (widthX*(i),      height[i][j-1],    widthZ*(j-1));
392       
393        Vector c1 = v2 - v1;
394        Vector c2 = v3 - v1;
395        Vector c3=  v4 - v1;
396        Vector c4 = v5 - v1;
397        Vector zero = Vector (0,0,0);
398        normal_vectors[i][j]=c1.cross(v3-v5)+c2.cross(v4-v2)+c3.cross(v5-v3)+c4.cross(v2-v4);
399        normal_vectors[i][j].normalize();
400      }
401
402  int snowheight=3;
403  for ( int i = 0; i<sizeX; i+=1)
404    for (int j = 0; j<sizeZ;j+=1)
405      {   
406        Vector v1 = Vector (widthX*(i),      height[i][j]-20,       widthZ*(j)  -width/2);
407        Vector v2 = Vector (widthX*(i+1),    height[i+1][j]-20,     widthZ*(j)  -width/2);
408        Vector v3 = Vector (widthX*(i+1),    height[i+1][j+1]-20,   widthZ*(j+1)-width/2);
409        Vector v4 = Vector (widthX*(i),      height[i][j+1]-20,     widthZ*(j+1)-width/2);
410        float a[3];
411        if(height[i][j]<snowheight){
412          a[0]=0;
413          a[1]=1.0-height[i][j]/10-.3;
414          a[2]=0;
415          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
416        }
417        else{
418            a[0]=1.0;
419            a[1]=1.0;
420            a[2]=1.0;
421            glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
422           
423        }
424        glNormal3f(normal_vectors[i][j].x, normal_vectors[i][j].y, normal_vectors[i][j].z);
425        glVertex3f(v1.x, v1.y, v1.z);
426        if(height[i+1][j]<snowheight){
427          a[0]=0;
428          a[1] =1.0-height[i+1][j]/10-.3;
429          a[2]=0;
430          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
431        }
432        else{
433          a[0]=1.0;
434          a[1]=1.0;
435          a[2]=1.0;
436          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
437         
438        }
439        glNormal3f(normal_vectors[i+1][j].x, normal_vectors[i+1][j].y, normal_vectors[i+1][j].z);
440        glVertex3f(v2.x, v2.y, v2.z);
441        if(height[i+1][j+1]<snowheight){
442          a[0]=0;
443          a[1] =1.0-height[i+1][j+1]/10-.3;
444          a[2]=0;
445          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
446        }
447        else{
448          a[0]=1.0;
449          a[1]=1.0;
450          a[2]=1.0;
451          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
452         
453         
454        }
455        glNormal3f(normal_vectors[i+1][j+1].x, normal_vectors[i+1][j+1].y, normal_vectors[i+1][j+1].z);
456        glVertex3f(v3.x, v3.y, v3.z);
457        if(height[i][j+1]<snowheight){
458          a[0]=0;
459          a[1] =1.0-height[i+1][j+1]/10-.3;
460          a[2]=0;
461          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
462        }
463        else{
464          a[0]=1.0;
465          a[1]=1.0;
466          a[2]=1.0;
467          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
468        }
469        glNormal3f(normal_vectors[i][j+1].x, normal_vectors[i][j+1].y, normal_vectors[i][j+1].z);
470        glVertex3f(v4.x, v4.y, v4.z);
471       
472      }
473  glEnd();
474  /* 
475  glBegin(GL_LINES);
476  for( float x = -128.0; x < 128.0; x += 25.0)
477    {
478      for( float y = -128.0; y < 128.0; y += 25.0)
479        {
480          glColor3f(1,0,0);
481          glVertex3f(x,y,-128.0);
482          glVertex3f(x,y,0.0);
483          glColor3f(0.5,0,0);
484          glVertex3f(x,y,0.0);
485          glVertex3f(x,y,128.0);
486        }
487    }
488  for( float y = -128.0; y < 128.0; y += 25.0)
489    {
490      for( float z = -128.0; z < 128.0; z += 25.0)
491        {
492          glColor3f(0,1,0);
493          glVertex3f(-128.0,y,z);
494          glVertex3f(0.0,y,z);
495          glColor3f(0,0.5,0);
496          glVertex3f(0.0,y,z);
497          glVertex3f(128.0,y,z);
498        }
499    }
500  for( float x = -128.0; x < 128.0; x += 25.0)
501    {
502      for( float z = -128.0; z < 128.0; z += 25.0)
503        {
504          glColor3f(0,0,1);
505          glVertex3f(x,-128.0,z);
506          glVertex3f(x,0.0,z);
507          glColor3f(0,0,0.5);
508          glVertex3f(x,0.0,z);
509          glVertex3f(x,128.0,z);
510        }
511     
512    }
513  */ 
514  /*
515  glBegin(GL_LINE_STRIP);
516  glColor3f(1.0, 5.0, 1.0);
517  for( int i = 0; i <= 30; i++)
518    {
519      glEvalCoord1f ((GLfloat) i/30.0);
520    }
521  glEnd();
522  */
523
524  trackManager->drawGraph(.01);
525  trackManager->debug(2);
526  /* 
527  glBegin(GL_LINES);
528  float i;
529  for(i = 0.0; i<1; i+=.01)
530    {
531      printf("%f, %f, %f\n",tmpCurve->calcPos(i).x, tmpCurve->calcPos(i).y, tmpCurve->calcPos(i).z);
532      glVertex3f(tmpCurve->calcPos(i).x, tmpCurve->calcPos(i).y, tmpCurve->calcPos(i).z);
533    }
534  glEnd();
535  */
536  glEndList();
537  // LIGHT initialisation
538  light = Light::getInstance();
539  light->addLight(0);
540  light->setAttenuation(QUADRATIC, 1.0);
541  light->setAttenuation(CONSTANT, 2.0);
542  light->setAttenuation(QUADRATIC, 1.0);
543  light->setPosition(10.0, 10.0, 50.0);
544  light->setDiffuseColor(1,1,1);
545  //  light->addLight(1);
546  //  light->setPosition(20, 10, -20);
547  //  light->setDiffuseColor(0,0,0);
548  light->debug();
549
550
551}
552
553/**
554   \brief initializes a new World
555*/
556ErrorMessage World::init()
557{
558  this->bPause = false;
559  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
560  cn->addToWorld(this);
561  cn->enable(true);
562
563  //glMap1f (GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
564  //glEnable (GL_MAP1_VERTEX_3);
565 
566  //theNurb = gluNewNurbsRenderer ();
567  //gluNurbsProperty (theNurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
568  //gluNurbsProperty (theNurb, GLU_NURBS_VERTEX, vertexCallback );
569
570}
571
572
573/**
574   \brief starts the World
575*/
576ErrorMessage World::start()
577{
578  printf("World::start() - starting current World: nr %i\n", this->debugWorldNr);
579  this->bQuitOrxonox = false;
580  this->bQuitCurrentGame = false;
581  this->mainLoop();
582}
583
584/**
585   \brief stops the world.
586
587   This happens, when the player decides to end the Level.
588*/
589ErrorMessage World::stop()
590{
591  printf("World::stop() - got stop signal\n");
592  this->bQuitCurrentGame = true;
593}
594
595/**
596   \brief pauses the Game
597*/
598ErrorMessage World::pause()
599{
600  this->isPaused = true;
601}
602
603/**
604   \brief ends the pause Phase
605*/
606ErrorMessage World::resume()
607{
608  this->isPaused = false;
609}
610
611/**
612   \brief destroys the World
613*/
614ErrorMessage World::destroy()
615{
616  delete trackManager;
617}
618
619/**
620   \brief shows the loading screen
621*/
622void World::displayLoadScreen ()
623{
624  printf ("World::displayLoadScreen - start\n"); 
625 
626  //GLMenuImageScreen*
627  this->glmis = GLMenuImageScreen::getInstance();
628  this->glmis->init();
629  this->glmis->setMaximum(10);
630  this->glmis->draw();
631 
632  printf ("World::displayLoadScreen - end\n"); 
633}
634
635/**
636   \brief removes the loadscreen, and changes over to the game
637
638   \todo take out the delay
639*/
640void World::releaseLoadScreen ()
641{
642  printf ("World::releaseLoadScreen - start\n"); 
643  this->glmis->setValue(this->glmis->getMaximum());
644  SDL_Delay(500);
645  printf ("World::releaseLoadScreen - end\n"); 
646}
647
648
649/**
650    \brief checks for collisions
651   
652    This method runs through all WorldEntities known to the world and checks for collisions
653    between them. In case of collisions the collide() method of the corresponding entities
654    is called.
655*/
656void World::collide ()
657{
658  /*
659  List *a, *b;
660  WorldEntity *aobj, *bobj;
661   
662  a = entities;
663 
664  while( a != NULL)
665    {
666      aobj = a->nextElement();
667      if( aobj->bCollide && aobj->collisioncluster != NULL)
668        {
669          b = a->nextElement();
670          while( b != NULL )
671            {
672              bobj = b->nextElement();
673              if( bobj->bCollide && bobj->collisioncluster != NULL )
674                {
675                  unsigned long ahitflg, bhitflg;
676                  if( check_collision ( &aobj->place, aobj->collisioncluster,
677                                        &ahitflg, &bobj->place, bobj->collisioncluster,
678                                        &bhitflg) );
679                  {
680                    aobj->collide (bobj, ahitflg, bhitflg);
681                    bobj->collide (aobj, bhitflg, ahitflg);
682                  }
683                }
684              b = b->nextElement();
685            }
686        }
687      a = a->enumerate();
688    }
689  */
690}
691
692/**
693    \brief runs through all entities calling their draw() methods
694*/
695void World::draw ()
696{
697  /* draw entities */
698  WorldEntity* entity;
699  entity = this->entities->enumerate();
700  while( entity != NULL ) 
701    { 
702      if( entity->bDraw ) entity->draw();
703      entity = this->entities->nextElement();
704    } 
705 
706  glCallList (objectList);
707  //! \todo skysphere is a WorldEntity and should be inside of the world-entity-list.
708  skySphere->draw();
709
710  testFont->printText(0, 0, 1, "orxonox_" PACKAGE_VERSION);
711
712}
713
714
715/**
716   \brief function to put your own debug stuff into it. it can display informations about
717   the current class/procedure
718*/
719void World::debug()
720{
721  printf ("World::debug() - starting debug\n");
722  PNode* p1 = NullParent::getInstance ();
723  PNode* p2 = new PNode (new Vector(2, 2, 2), p1);
724  PNode* p3 = new PNode (new Vector(4, 4, 4), p1);
725  PNode* p4 = new PNode (new Vector(6, 6, 6), p2);
726
727  p1->debug ();
728  p2->debug ();
729  p3->debug ();
730  p4->debug ();
731
732  p1->shiftCoor (new Vector(-1, -1, -1));
733
734  printf("World::debug() - shift\n");
735  p1->debug ();
736  p2->debug ();
737  p3->debug ();
738  p4->debug ();
739 
740  p1->update (1);
741
742  printf ("World::debug() - update\n");
743  p1->debug ();
744  p2->debug ();
745  p3->debug ();
746  p4->debug ();
747
748  p2->shiftCoor (new Vector(-1, -1, -1));
749  p1->update (2);
750
751  p1->debug ();
752  p2->debug ();
753  p3->debug ();
754  p4->debug ();
755
756  p2->setAbsCoor (new Vector(1,2,3));
757
758
759 p1->update (2);
760
761  p1->debug ();
762  p2->debug ();
763  p3->debug ();
764  p4->debug ();
765
766  p1->destroy ();
767 
768 
769  /*
770  WorldEntity* entity;
771  printf("counting all entities\n");
772  printf("World::debug() - enumerate()\n");
773  entity = entities->enumerate(); 
774  while( entity != NULL )
775    {
776      if( entity->bDraw ) printf("got an entity\n");
777      entity = entities->nextElement();
778    }
779  */
780}
781
782
783/**
784  \brief main loop of the world: executing all world relevant function
785
786  in this loop we synchronize (if networked), handle input events, give the heart-beat to
787  all other member-entities of the world (tick to player, enemies etc.), checking for
788  collisions drawing everything to the screen.
789*/
790void World::mainLoop()
791{
792  this->lastFrame = SDL_GetTicks ();
793  printf("World::mainLoop() - Entering main loop\n");
794  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
795    {
796      // Network
797      this->synchronize ();
798      // Process input
799      this->handleInput ();
800      if( this->bQuitCurrentGame || this->bQuitOrxonox)
801        {
802          printf("World::mainLoop() - leaving loop earlier...\n");
803          break;
804        }
805      // Process time
806      this->timeSlice ();
807      // Process collision
808      this->collide ();
809      // Draw
810      this->display ();
811 
812      for( int i = 0; i < 5000000; i++) {}
813      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
814    }
815  printf("World::mainLoop() - Exiting the main loop\n");
816}
817
818
819/**
820   \brief synchronize local data with remote data
821*/
822void World::synchronize ()
823{
824  // Get remote input
825  // Update synchronizables
826}
827
828
829/**
830   \brief run all input processing
831
832   the command node is the central input event dispatcher. the node uses the even-queue from
833   sdl and has its own event-passing-queue.
834*/
835void World::handleInput ()
836{
837  // localinput
838  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
839  cn->process();
840  // remoteinput
841}
842
843
844/**
845   \brief advance the timeline
846
847   this calculates the time used to process one frame (with all input handling, drawing, etc)
848   the time is mesured in ms and passed to all world-entities and other classes that need
849   a heart-beat.
850*/
851void World::timeSlice ()
852{
853  Uint32 currentFrame = SDL_GetTicks();
854  if(!this->bPause)
855    {
856      Uint32 dt = currentFrame - this->lastFrame;
857     
858      if(dt > 0)
859        {
860          float fps = 1000/dt;
861          printf("fps = %f\n", fps);
862        }
863      else
864        {
865          /* the frame-rate is limited to 100 frames per second, all other things are for
866             nothing.
867          */
868          printf("fps = 1000 - frame rate is adjusted\n");
869          SDL_Delay(10);
870          dt = 10;
871        }
872      //this->timeSlice (dt);
873     
874      /* function to let all entities tick (iterate through list) */
875      WorldEntity* entity;
876      float seconds = dt / 1000.0;     
877      this->nullParent->update (seconds);
878      entity = entities->enumerate(); 
879      while( entity != NULL) 
880        { 
881          entity->tick (seconds);
882          entity = entities->nextElement();
883        }
884      skySphere->updatePosition(localCamera->absCoordinate);
885     
886      /* update tick the rest */
887      this->localCamera->timeSlice(dt);
888      this->trackManager->tick(dt);
889    }
890  this->lastFrame = currentFrame;
891}
892
893
894/**
895   \brief render the current frame
896   
897   clear all buffers and draw the world
898*/
899void World::display ()
900{
901  // clear buffer
902  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
903  // set camera
904  this->localCamera->apply ();
905  // draw world
906  this->draw();
907  // draw HUD
908  /* \todo draw HUD */
909  // flip buffers
910  SDL_GL_SwapBuffers();
911  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
912  //SDL_Flip (screen);
913}
914
915
916/**
917   \brief add and spawn a new entity to this world
918   \param entity to be added
919*/
920void World::spawn(WorldEntity* entity)
921{
922  if( this->nullParent != NULL && entity->parent == NULL)
923    this->nullParent->addChild (entity);
924
925  this->entities->add (entity);
926
927  entity->postSpawn ();
928}
929
930
931/**
932   \brief add and spawn a new entity to this world
933   \param entity to be added
934   \param absCoor At what coordinates to add this entity.
935   \param absDir In which direction should it look.
936*/
937void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
938{
939  entity->setAbsCoor (absCoor);
940  entity->setAbsDir (absDir);
941 
942  if( this->nullParent != NULL && entity->parent == NULL)
943    this->nullParent->addChild (entity);
944
945  this->entities->add (entity);
946
947  entity->postSpawn ();
948}
949
950
951
952/**
953  \brief commands that the world must catch
954  \returns false if not used by the world
955*/
956bool World::command(Command* cmd)
957{
958  return false;
959}
960
961void World::setPath( char* name)
962{
963        path = name;
964}
965
966char* World::getPath()
967{
968        return path;
969}
Note: See TracBrowser for help on using the repository browser.