Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/levelloader: Implemented loadability of worlds and campaigns from files. Theoretically any Story_Entity and World_Entity can now be loaded from the files if somebody adjusts the classes to be loadable. System still needs testing

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