Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/shadows/src/world.cc @ 3698

Last change on this file since 3698 was 3698, checked in by dave, 19 years ago

branches/shadows: so jetzt ist die Ausgangslage geschaffen

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