Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3341 was 3339, checked in by patrick, 20 years ago

orxonox/branches/parenting: some little changes of the LoadScreen, delay and Mipmaping filter

File size: 24.8 KB
RevLine 
[1853]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.
[1855]11
12   ### File Specific:
13   main-programmer: Patrick Boenzli
[2190]14   co-programmer: Christian Meyer
[1853]15*/
16
[2190]17#include "world.h"
18#include "world_entity.h"
19#include "collision.h"
[3335]20#include "track_manager.h"
[2190]21#include "track.h"
[2036]22#include "player.h"
[2190]23#include "command_node.h"
24#include "camera.h"
[2816]25#include "environment.h"
[3265]26#include "p_node.h"
[3276]27#include "null_parent.h"
[3311]28#include "helper_parent.h"
[2036]29
[3337]30#include <SDL/SDL_image.h>
31
[1856]32using namespace std;
[1853]33
34
[1858]35/**
[2551]36    \brief create a new World
37   
38    This creates a new empty world!
[1858]39*/
[2636]40World::World (char* name)
[1855]41{
[3302]42  this->setClassName ("World");
[2636]43  this->worldName = name;
44  this->debugWorldNr = -1;
[2822]45  this->entities = new tList<WorldEntity>();
[1855]46}
47
[2636]48World::World (int worldID)
49{
50  this->debugWorldNr = worldID;
51  this->worldName = NULL;
[2822]52  this->entities = new tList<WorldEntity>();
[2636]53}
54
[1858]55/**
[2551]56    \brief remove the World from memory
[3309]57   
58    delete everything explicitly, that isn't contained in the parenting tree!
59    things contained in the tree are deleted automaticaly
[1858]60*/
[2190]61World::~World ()
[1872]62{
[3220]63  printf("World::~World() - deleting current world\n");
[3226]64  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
[3220]65  cn->unbind(this->localPlayer);
66  cn->reset();
67  this->localCamera->destroy();
68
[3309]69  this->nullParent->destroy ();
70
[3337]71  //delete this->testCurve;
72
[3309]73  /*
[3220]74  WorldEntity* entity = entities->enumerate(); 
75  while( entity != NULL )
76    {
77      entity->destroy();
78      entity = entities->nextElement();
79    }
80  this->entities->destroy();
[3309]81  */
[3220]82
[3277]83  /* FIX the parent list has to be cleared - not possible if we got the old list also*/
84
[3309]85
86  //delete this->entities;
87  //delete this->localCamera;
[3220]88  /* this->localPlayer hasn't to be deleted explicitly, it is
89     contained in entities*/
[1872]90}
[1858]91
[3311]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}};
[2636]95
[3311]96
[3222]97ErrorMessage World::init()
[2636]98{
99  this->bPause = false;
[3226]100  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
[3216]101  cn->addToWorld(this);
102  cn->enable(true);
[3265]103
[3311]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 );
[2636]110}
111
[3311]112
113
[3222]114ErrorMessage World::start()
[2636]115{
[3220]116  printf("World::start() - starting current World: nr %i\n", this->debugWorldNr);
117  this->bQuitOrxonox = false;
118  this->bQuitCurrentGame = false;
[2636]119  this->mainLoop();
120}
121
[3222]122ErrorMessage World::stop()
[2636]123{
[3220]124  printf("World::stop() - got stop signal\n");
[2636]125  this->bQuitCurrentGame = true;
126}
127
[3222]128ErrorMessage World::pause()
[2636]129{
130  this->isPaused = true;
131}
132
[3222]133ErrorMessage World::resume()
[2636]134{
135  this->isPaused = false;
136}
137
[3221]138void World::destroy()
139{
140
141}
142
[3311]143
[3337]144void World::displayLoadScreen ()
145{
146  printf ("World::displayLoadScreen - start\n"); 
147 
[3338]148  int w = 680;
149  int h = 480;
150
151  glViewport(0,0,w,h);
[3337]152 
[3338]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;
[3337]163 
[3338]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!
[3337]169    {
[3338]170      printf (" Failed loading %s\n", strFileName);
[3337]171      SDL_Quit ();
172    }
[3338]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]);
[3337]176 
[3338]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*/
[3337]183 
[3338]184  int bytesPerPixel = pBitmap[0]->format->BytesPerPixel; 
[3337]185 
[3338]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);
[3339]219  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   
[3338]220  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
[3337]221
[3338]222  delete [] newData;   
223  SDL_FreeSurface(pBitmap[0]);
[3337]224
225
[3338]226  /* ------------painten */
[3337]227
[3338]228  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
229  glLoadIdentity();
230  gluLookAt(0, 0, 6,     0, 0, 0,     0, 1, 0);
[3337]231
[3338]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);
[3337]265
[3338]266  glEnd();
[3337]267 
[3338]268  SDL_GL_SwapBuffers();                   
[3337]269
[3338]270  glDisable (GL_TEXTURE_2D);
271  glDeleteTextures (1, &textureArray[textureID]);
[3339]272  SDL_Delay (1000);
[3338]273  printf ("World::displayLoadScreen - end\n"); 
274}
[3337]275
276
[3338]277void World::releaseLoadScreen ()
278{
279  printf ("World::releaseLoadScreen - start\n"); 
[3337]280
281
282
283  printf ("World::releaseLoadScreen - end\n"); 
284}
285
286
[2636]287void World::load()
288{
289  if(this->debugWorldNr != -1)
290    {
[3335]291      trackManager = TrackManager::getInstance();
[2636]292      switch(this->debugWorldNr)
293        {
[3225]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           */
[2636]300        case DEBUG_WORLD_0:
301          {
[3311]302            this->nullParent = NullParent::getInstance ();
[3302]303            this->nullParent->setName ("NullParent");
[3277]304
[2636]305            // create some path nodes
306            this->pathnodes = new Vector[6];
307            this->pathnodes[0] = Vector(0, 0, 0);
[2792]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);
[2636]313           
314            // create the tracks
[2816]315            this->tracklen = 2;
316            this->track = new Track[2];
[2636]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              }
[3194]321            // !\todo old track-system has to be removed
322
[3311]323            //create helper for player
324            HelperParent* hp = new HelperParent ();
325            /* the player has to be added to this helper */
326
[2636]327            // create a player
[3311]328            WorldEntity* myPlayer = new Player ();
[3302]329            myPlayer->setName ("player");
[3311]330            this->spawn (myPlayer);
[2640]331            this->localPlayer = myPlayer;           
332
[2636]333            // bind input
[3311]334            Orxonox *orx = Orxonox::getInstance ();
[3226]335            orx->getLocalInput()->bind (myPlayer);
[2636]336           
337            // bind camera
338            this->localCamera = new Camera(this);
[3302]339            this->localCamera->setName ("camera");
340            this->getCamera()->bind (myPlayer);
341            this->localPlayer->addChild (this->localCamera);
[3277]342           
[3308]343
[3337]344            Vector* es = new Vector (50, 2, 0);
[3308]345            Quaternion* qs = new Quaternion ();
[2816]346            WorldEntity* env = new Environment();
[3309]347            env->setName ("env");
[3308]348            this->spawn(env, es, qs);
[2816]349
[3308]350
[2636]351            break;
352          }
353        case DEBUG_WORLD_1:
354          {
[3337]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
[3311]365            this->nullParent = NullParent::getInstance ();
366            this->nullParent->setName ("NullParent");
[3277]367
[2636]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           
[3311]377
378
379
[2636]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              }
[3194]387
[2636]388            // create a player
[2644]389            WorldEntity* myPlayer = new Player();
[3308]390            myPlayer->setName ("player");
[2644]391            this->spawn(myPlayer);
[3194]392            this->localPlayer = myPlayer;           
[2636]393           
394            // bind input
395            Orxonox *orx = Orxonox::getInstance();
[3226]396            orx->getLocalInput()->bind (myPlayer);
[2636]397           
398            // bind camera
[3308]399            this->localCamera = new Camera (this);
400            this->localCamera->setName ("camera");
[2636]401            this->getCamera()->bind (myPlayer); 
[3308]402            this->localPlayer->addChild (this->localCamera);
[2636]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    }
[2731]413
414  // initialize debug coord system
415  objectList = glGenLists(1);
416  glNewList (objectList, GL_COMPILE);
417  glLoadIdentity();
[2792]418  glColor3f(1.0,0,0);
[2817]419  glBegin(GL_QUADS);
[3200]420
421  int sizeX = 100;
[3323]422  int sizeZ = 80;
[3200]423  float length = 1000;
424  float width = 200;
425  float widthX = float (length /sizeX);
[3323]426  float widthZ = float (width /sizeZ);
[3199]427 
[3323]428  float height [sizeX][sizeZ];
429  Vector normal_vectors[sizeX][sizeZ];
[3199]430 
[3200]431 
432  for ( int i = 0; i<sizeX-1; i+=1)
[3323]433    for (int j = 0; j<sizeZ-1;j+=1)
[3200]434      //height[i][j] = rand()/20046 + (j-25)*(j-25)/30;
[3199]435#ifdef __WIN32__
[3200]436      height[i][j]=(sin((float)j/3)*rand()*i/182400)*.5;
[3199]437#else
[3200]438      height[i][j]=(sin((float)j/3)*rand()*(long)i/6282450500.0)*.5;
[3199]439#endif
[3200]440
[3323]441  //Die Huegel ein wenig glaetten
[3199]442  for (int h=1; h<2;h++)
[3200]443    for (int i=1;i<sizeX-2 ;i+=1 )
[3323]444      for(int j=1;j<sizeZ-2;j+=1)
[3199]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
[3200]448  for(int i=1;i<sizeX-2;i+=1)
[3323]449    for(int j=1;j<sizeZ-2 ;j+=1)
[2792]450      {
[3323]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));
[3199]456       
[3200]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);
[3324]462        normal_vectors[i][j]=c1.cross(v3-v5)+c2.cross(v4-v2)+c3.cross(v5-v3)+c4.cross(v2-v4);
[3199]463        normal_vectors[i][j].normalize();
[3200]464      }
465
466  int snowheight=3;
467  for ( int i = 0; i<sizeX; i+=1)
[3323]468    for (int j = 0; j<sizeZ;j+=1)
[3200]469      {   
[3323]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);
[3200]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);
[3199]480        }
[3200]481        else{
[3199]482            a[0]=1.0;
483            a[1]=1.0;
484            a[2]=1.0;
485            glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
[2817]486           
[3199]487        }
[3200]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      }
[3199]537  glEnd();
538  /* 
[2792]539  glBegin(GL_LINES);
[2731]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    }
[2792]577  */ 
[2731]578  //draw track
[2792]579  glBegin(GL_LINES);
[3311]580  glColor3f(0.0, 1.0, 1.0);
[2731]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();
[3311]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();
[3337]595
[2731]596  glEndList();
[2636]597}
598
599
600/**
[2551]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.
[1858]606*/
[2190]607void World::collide ()
[1858]608{
[2816]609  /*
610  List *a, *b;
[2551]611  WorldEntity *aobj, *bobj;
[2816]612   
613  a = entities;
[2551]614 
615  while( a != NULL)
616    {
[2816]617      aobj = a->nextElement();
[2551]618      if( aobj->bCollide && aobj->collisioncluster != NULL)
[2190]619        {
[2816]620          b = a->nextElement();
[2551]621          while( b != NULL )
622            {
[2816]623              bobj = b->nextElement();
[2551]624              if( bobj->bCollide && bobj->collisioncluster != NULL )
[2190]625                {
[2551]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                  }
[2190]634                }
[2816]635              b = b->nextElement();
[2551]636            }
[2190]637        }
[2816]638      a = a->enumerate();
[2551]639    }
[2816]640  */
[1858]641}
642
643/**
[2551]644    \brief runs through all entities calling their draw() methods
[1931]645*/
[2190]646void World::draw ()
[2077]647{
[2551]648  // draw entities
649  WorldEntity* entity;
[2822]650  entity = this->entities->enumerate();
[2816]651  while( entity != NULL ) 
[2551]652    { 
[2822]653      if( entity->bDraw ) entity->draw();
654      entity = this->entities->nextElement();
[3307]655    } 
[2551]656 
657  // draw debug coord system
[2731]658  glCallList (objectList);
[2551]659
[1931]660}
661
662/**
[2551]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.
[1883]669*/
[2190]670void World::update ()
[1883]671{
[3302]672  /*
[2816]673  //List<WorldEntity> *l;
[2551]674  WorldEntity* entity;
675  Location* loc;
676  Placement* plc;
677  Uint32 t;
678 
[2816]679  //  l = entities->enumerate();
680  entity = this->entities->enumerate();
681  while( entity != NULL )
[2551]682    {
[2816]683
[2551]684     
685      if( !entity->isFree() )
686        {
[3233]687          loc = entity->getLocation();
688          plc = entity->getPlacement();
[2551]689          t = loc->part;
690         
691          if( t >= tracklen )
692            {
693              printf("An entity is out of the game area\n");
[3233]694              entity->leftWorld ();
[2551]695            }
696          else
697            {
[3233]698              while( track[t].mapCoords( loc, plc) )
[2190]699                {
[3233]700                  track[t].postLeave (entity);
[2551]701                  if( loc->part >= tracklen )
702                    {
703                      printf("An entity has left the game area\n");
[3233]704                      entity->leftWorld ();
[2551]705                      break;
706                    }
[3233]707                  track[loc->part].postEnter (entity);
[2190]708                }
[2551]709            }
[2190]710        }
[2551]711      else
712        {
713        }
714     
[2816]715      entity = entities->nextElement();
[2551]716    }
[3302]717  */ 
[1883]718}
719
[2077]720/**
[2551]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
[2077]723*/
[3225]724void World::timeSlice (Uint32 deltaT)
[2077]725{
[2816]726  //List<WorldEntity> *l;
[2551]727  WorldEntity* entity;
[3175]728  float seconds = deltaT / 1000.0;
[2551]729 
[3302]730  this->nullParent->update (seconds);
[3306]731  //this->nullParent->processTick (seconds);
[3302]732
[2816]733  entity = entities->enumerate(); 
734  while( entity != NULL) 
[2551]735    { 
736      entity->tick (seconds);
[2816]737      entity = entities->nextElement();
[2551]738    }
[2816]739
[3209]740  //for( int i = 0; i < tracklen; i++) track[i].tick (seconds);
[2077]741}
[1883]742
[2190]743/**
[2551]744   \brief removes level data from memory
[1858]745*/
[2190]746void World::unload()
[1858]747{
[2551]748  if( pathnodes) delete []pathnodes;
749  if( track) delete []pathnodes;
[1883]750}
[1879]751
[2636]752
753
[2190]754/**
[2636]755   \brief calls the correct mapping function to convert a given "look at"-Location to a
756   Camera Placement
[1858]757*/
[3225]758void World::calcCameraPos (Location* loc, Placement* plc)
[1858]759{
[3233]760  track[loc->part].mapCamera (loc, plc);
[2636]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
[3225]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*/
[2640]780void World::debug()
781{
[3269]782  printf ("World::debug() - starting debug\n");
[3311]783  PNode* p1 = NullParent::getInstance ();
[3265]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
[3269]803  printf ("World::debug() - update\n");
[3265]804  p1->debug ();
805  p2->debug ();
806  p3->debug ();
807  p4->debug ();
808
[3269]809  p2->shiftCoor (new Vector(-1, -1, -1));
810  p1->update (2);
[3265]811
[3269]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 ();
[3277]826
827  p1->destroy ();
828 
829 
[3265]830  /*
[2640]831  WorldEntity* entity;
832  printf("counting all entities\n");
[2816]833  printf("World::debug() - enumerate()\n");
834  entity = entities->enumerate(); 
835  while( entity != NULL )
[2640]836    {
837      if( entity->bDraw ) printf("got an entity\n");
[2816]838      entity = entities->nextElement();
[2640]839    }
[3265]840  */
[2640]841}
[2636]842
[2640]843
[3225]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*/
[2636]851void World::mainLoop()
852{
[3302]853  this->lastFrame = SDL_GetTicks ();
[3220]854  printf("World::mainLoop() - Entering main loop\n");
[3215]855  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
[2551]856    {
[2636]857      // Network
[3302]858      this->synchronize ();
[2636]859      // Process input
[3302]860      this->handleInput ();
[3215]861      if( this->bQuitCurrentGame || this->bQuitOrxonox)
862        {
863          printf("World::mainLoop() - leaving loop earlier...\n");
864          break;
865        }
[2636]866      // Process time
[3302]867      this->timeSlice ();
[2636]868      // Process collision
[3302]869      this->collision ();
[2636]870      // Draw
[3302]871      this->display ();
[2816]872 
[3338]873      for( int i = 0; i < 5000000; i++) {}
874      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
[2551]875    }
[3215]876  printf("World::mainLoop() - Exiting the main loop\n");
[1899]877}
878
[2190]879/**
[2636]880   \brief synchronize local data with remote data
[1855]881*/
[2636]882void World::synchronize ()
[1855]883{
[2636]884  // Get remote input
885  // Update synchronizables
[1855]886}
[2636]887
888/**
889   \brief run all input processing
[3225]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.
[2636]893*/
[3225]894void World::handleInput ()
[2636]895{
896  // localinput
[3225]897  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
[3216]898  cn->process();
[2636]899  // remoteinput
900}
901
902/**
903   \brief advance the timeline
[3225]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.
[2636]908*/
[3225]909void World::timeSlice ()
[2636]910{
911  Uint32 currentFrame = SDL_GetTicks();
912  if(!this->bPause)
913    {
914      Uint32 dt = currentFrame - this->lastFrame;
[2816]915     
[2636]916      if(dt > 0)
917        {
918          float fps = 1000/dt;
919          printf("fps = %f\n", fps);
920        }
921      else
922        {
[3225]923          /* the frame-rate is limited to 100 frames per second, all other things are for
924             nothing.
925          */
[3194]926          printf("fps = 1000 - frame rate is adjusted\n");
927          SDL_Delay(10);
928          dt = 10;
[2636]929        }
[3225]930      this->timeSlice (dt);
[2636]931      this->update ();
[3225]932      this->localCamera->timeSlice(dt);
[2636]933    }
934  this->lastFrame = currentFrame;
935}
936
[3216]937
[2636]938/**
939   \brief compute collision detection
940*/
941void World::collision ()
942{
943  this->collide ();
944}
945
946
947/**
[3225]948   \brief render the current frame
949   
950   clear all buffers and draw the world
[2636]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
[3337]961  /* \todo draw HUD */
[2636]962  // flip buffers
963  SDL_GL_SwapBuffers();
[3337]964  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
965  //SDL_Flip (screen);
[2636]966}
967
[3225]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*/
[2636]974Camera* World::getCamera()
975{
976  return this->localCamera;
977}
[2644]978
979
[3225]980/**
981   \brief add and spawn a new entity to this world
982   \param entity to be added
983*/
[2644]984void World::spawn(WorldEntity* entity)
985{
[3306]986  if( this->nullParent != NULL && entity->parent == NULL)
[3277]987    this->nullParent->addChild (entity);
988
[3306]989  this->entities->add (entity);
990
[3233]991  entity->postSpawn ();
[2816]992}
993
994
[3225]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*/
[3306]1000void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
[2816]1001{
[3306]1002  entity->setAbsCoor (absCoor);
1003  entity->setAbsDir (absDir);
1004 
1005  if( this->nullParent != NULL && entity->parent == NULL)
[3277]1006    this->nullParent->addChild (entity);
1007
[2816]1008  this->entities->add (entity);
[3306]1009
[3233]1010  entity->postSpawn ();
[2644]1011}
[2816]1012
1013
[3277]1014
[3225]1015/*
1016  \brief commands that the world must catch
1017  \returns false if not used by the world
1018*/
[3216]1019bool World::command(Command* cmd)
1020{
1021  return false;
1022}
[3265]1023
[3338]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.