Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/parenting/src/world.cc @ 3342

Last change on this file since 3342 was 3342, checked in by patrick, 19 years ago

orxonox/branches/parenting: removed old coordinates.h system now using parenting for the game

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