Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/parenting: implemented a simple LoadScreen that just displays a bmp image (format will change - not important yet). You must copy a bmp file to the src directory to see the effect. if there is no bmp file, the LoadScreen won't appear. I have made a little bmp, that can be found on the server

File size: 24.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
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 (5000);
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
753
754/**
755   \brief calls the correct mapping function to convert a given "look at"-Location to a
756   Camera Placement
757*/
758void World::calcCameraPos (Location* loc, Placement* plc)
759{
760  track[loc->part].mapCamera (loc, plc);
761}
762
763
764void World::setTrackLen(Uint32 len)
765{
766  this->tracklen = len;
767}
768
769int World::getTrackLen()
770{
771  return this->tracklen;
772}
773
774
775
776/**
777   \brief function to put your own debug stuff into it. it can display informations about
778   the current class/procedure
779*/
780void World::debug()
781{
782  printf ("World::debug() - starting debug\n");
783  PNode* p1 = NullParent::getInstance ();
784  PNode* p2 = new PNode (new Vector(2, 2, 2), p1);
785  PNode* p3 = new PNode (new Vector(4, 4, 4), p1);
786  PNode* p4 = new PNode (new Vector(6, 6, 6), p2);
787
788  p1->debug ();
789  p2->debug ();
790  p3->debug ();
791  p4->debug ();
792
793  p1->shiftCoor (new Vector(-1, -1, -1));
794
795  printf("World::debug() - shift\n");
796  p1->debug ();
797  p2->debug ();
798  p3->debug ();
799  p4->debug ();
800 
801  p1->update (1);
802
803  printf ("World::debug() - update\n");
804  p1->debug ();
805  p2->debug ();
806  p3->debug ();
807  p4->debug ();
808
809  p2->shiftCoor (new Vector(-1, -1, -1));
810  p1->update (2);
811
812  p1->debug ();
813  p2->debug ();
814  p3->debug ();
815  p4->debug ();
816
817  p2->setAbsCoor (new Vector(1,2,3));
818
819
820 p1->update (2);
821
822  p1->debug ();
823  p2->debug ();
824  p3->debug ();
825  p4->debug ();
826
827  p1->destroy ();
828 
829 
830  /*
831  WorldEntity* entity;
832  printf("counting all entities\n");
833  printf("World::debug() - enumerate()\n");
834  entity = entities->enumerate(); 
835  while( entity != NULL )
836    {
837      if( entity->bDraw ) printf("got an entity\n");
838      entity = entities->nextElement();
839    }
840  */
841}
842
843
844/*
845  \brief main loop of the world: executing all world relevant function
846
847  in this loop we synchronize (if networked), handle input events, give the heart-beat to
848  all other member-entities of the world (tick to player, enemies etc.), checking for
849  collisions drawing everything to the screen.
850*/
851void World::mainLoop()
852{
853  this->lastFrame = SDL_GetTicks ();
854  printf("World::mainLoop() - Entering main loop\n");
855  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
856    {
857      // Network
858      this->synchronize ();
859      // Process input
860      this->handleInput ();
861      if( this->bQuitCurrentGame || this->bQuitOrxonox)
862        {
863          printf("World::mainLoop() - leaving loop earlier...\n");
864          break;
865        }
866      // Process time
867      this->timeSlice ();
868      // Process collision
869      this->collision ();
870      // Draw
871      this->display ();
872 
873      for( int i = 0; i < 5000000; i++) {}
874      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
875    }
876  printf("World::mainLoop() - Exiting the main loop\n");
877}
878
879/**
880   \brief synchronize local data with remote data
881*/
882void World::synchronize ()
883{
884  // Get remote input
885  // Update synchronizables
886}
887
888/**
889   \brief run all input processing
890
891   the command node is the central input event dispatcher. the node uses the even-queue from
892   sdl and has its own event-passing-queue.
893*/
894void World::handleInput ()
895{
896  // localinput
897  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
898  cn->process();
899  // remoteinput
900}
901
902/**
903   \brief advance the timeline
904
905   this calculates the time used to process one frame (with all input handling, drawing, etc)
906   the time is mesured in ms and passed to all world-entities and other classes that need
907   a heart-beat.
908*/
909void World::timeSlice ()
910{
911  Uint32 currentFrame = SDL_GetTicks();
912  if(!this->bPause)
913    {
914      Uint32 dt = currentFrame - this->lastFrame;
915     
916      if(dt > 0)
917        {
918          float fps = 1000/dt;
919          printf("fps = %f\n", fps);
920        }
921      else
922        {
923          /* the frame-rate is limited to 100 frames per second, all other things are for
924             nothing.
925          */
926          printf("fps = 1000 - frame rate is adjusted\n");
927          SDL_Delay(10);
928          dt = 10;
929        }
930      this->timeSlice (dt);
931      this->update ();
932      this->localCamera->timeSlice(dt);
933    }
934  this->lastFrame = currentFrame;
935}
936
937
938/**
939   \brief compute collision detection
940*/
941void World::collision ()
942{
943  this->collide ();
944}
945
946
947/**
948   \brief render the current frame
949   
950   clear all buffers and draw the world
951*/
952void World::display ()
953{
954  // clear buffer
955  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
956  // set camera
957  this->localCamera->apply ();
958  // draw world
959  this->draw();
960  // draw HUD
961  /* \todo draw HUD */
962  // flip buffers
963  SDL_GL_SwapBuffers();
964  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
965  //SDL_Flip (screen);
966}
967
968/**
969   \brief give back active camera
970   
971   this passes back the actualy active camera
972   \todo ability to define more than one camera or camera-places
973*/
974Camera* World::getCamera()
975{
976  return this->localCamera;
977}
978
979
980/**
981   \brief add and spawn a new entity to this world
982   \param entity to be added
983*/
984void World::spawn(WorldEntity* entity)
985{
986  if( this->nullParent != NULL && entity->parent == NULL)
987    this->nullParent->addChild (entity);
988
989  this->entities->add (entity);
990
991  entity->postSpawn ();
992}
993
994
995/**
996   \brief add and spawn a new entity to this world
997   \param entity to be added
998   \param location where to add
999*/
1000void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1001{
1002  entity->setAbsCoor (absCoor);
1003  entity->setAbsDir (absDir);
1004 
1005  if( this->nullParent != NULL && entity->parent == NULL)
1006    this->nullParent->addChild (entity);
1007
1008  this->entities->add (entity);
1009
1010  entity->postSpawn ();
1011}
1012
1013
1014
1015/*
1016  \brief commands that the world must catch
1017  \returns false if not used by the world
1018*/
1019bool World::command(Command* cmd)
1020{
1021  return false;
1022}
1023
1024
1025
1026
1027void World::swap (unsigned char &a, unsigned char &b)
1028{
1029  unsigned char temp;
1030  temp = a;
1031  a    = b;
1032  b    = temp;
1033}
Note: See TracBrowser for help on using the repository browser.