Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/world.cc @ 2854

Last change on this file since 2854 was 2822, checked in by patrick, 20 years ago

orxonox/trunk/src: changed list to template again, will add an iterator soon. fixed a graphics bug, that was realy painful to track.

File size: 13.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"
20#include "track.h"
[2036]21#include "player.h"
[2190]22#include "command_node.h"
23#include "camera.h"
[2816]24#include "environment.h"
[2036]25
[1856]26using namespace std;
[1853]27
28
[1858]29/**
[2551]30    \brief create a new World
31   
32    This creates a new empty world!
[1858]33*/
[2636]34World::World (char* name)
[1855]35{
[2636]36  this->worldName = name;
37  this->debugWorldNr = -1;
[2822]38  this->entities = new tList<WorldEntity>();
[1855]39}
40
[2636]41World::World (int worldID)
42{
43  this->debugWorldNr = worldID;
44  this->worldName = NULL;
[2822]45  this->entities = new tList<WorldEntity>();
[2636]46}
47
[1858]48/**
[2551]49    \brief remove the World from memory
[1858]50*/
[2190]51World::~World ()
[1872]52{
[2640]53  Orxonox *orx = Orxonox::getInstance();
[2644]54  orx->get_localinput()->unbind (this->localPlayer);
55  delete this->entities;
56  delete this->localCamera;
[1872]57}
[1858]58
[2636]59
[1855]60/**
[2636]61    \brief initialize the world before use.
62*/
63Error World::init()
64{
65  this->bPause = false;
66}
67
68Error World::start()
69{
70  this->mainLoop();
71}
72
73Error World::stop()
74{
75  this->bQuitCurrentGame = true;
76  this->localCamera->setWorld(NULL);
[2816]77  this->entities->clear();
78  Orxonox::getInstance()->get_localinput()->reset();
[2640]79  this->~World();
[2636]80}
81
82Error World::pause()
83{
84  this->isPaused = true;
85}
86
87Error World::resume()
88{
89  this->isPaused = false;
90}
91
92void World::load()
93{
94  if(this->debugWorldNr != -1)
95    {
96      switch(this->debugWorldNr)
97        {
98        case DEBUG_WORLD_0:
99          {
100            // create some path nodes
101            this->pathnodes = new Vector[6];
102            this->pathnodes[0] = Vector(0, 0, 0);
[2792]103            this->pathnodes[1] = Vector(1000, 0, 0);
104            //      this->pathnodes[2] = Vector(-100, 140, 0);
105            //      this->pathnodes[3] = Vector(0, 180, 0);
106            //      this->pathnodes[4] = Vector(100, 140, 0);
107            //      this->pathnodes[5] = Vector(100, 40, 0);
[2636]108           
109            // create the tracks
[2816]110            this->tracklen = 2;
111            this->track = new Track[2];
[2636]112            for( int i = 0; i < this->tracklen; i++)
113              {
114                this->track[i] = Track( i, (i+1)%this->tracklen, &this->pathnodes[i], &this->pathnodes[(i+1)%this->tracklen]);
115              }
116           
117            // create a player
[2644]118            WorldEntity* myPlayer = new Player();
119            this->spawn(myPlayer);
[2640]120            this->localPlayer = myPlayer;           
121
[2636]122            // bind input
123            Orxonox *orx = Orxonox::getInstance();
124            orx->get_localinput()->bind (myPlayer);
125           
126            // bind camera
127            this->localCamera = new Camera(this);
128            this->getCamera()->bind (myPlayer); 
[2816]129
130            Placement* plc = new Placement;
131            plc->r = Vector(100, 10, 10);
132            plc->w = Quaternion();
133            WorldEntity* env = new Environment();
134            this->spawn(env, plc);
135
[2636]136            break;
137          }
138        case DEBUG_WORLD_1:
139          {
140            // create some path nodes
141            this->pathnodes = new Vector[6];
142            this->pathnodes[0] = Vector(0, 0, 0);
143            this->pathnodes[1] = Vector(20, 10, 10);
144            this->pathnodes[2] = Vector(40, 0, 10);
145            this->pathnodes[3] = Vector(60, 10, 0);
146            this->pathnodes[4] = Vector(80, 20, 10);
147            this->pathnodes[5] = Vector(30, 50, 0);
148           
149            // create the tracks
150            this->tracklen = 6;
151            this->track = new Track[6];
152            for( int i = 0; i < this->tracklen; i++)
153              {
154                this->track[i] = Track( i, (i+1)%this->tracklen, &this->pathnodes[i], &this->pathnodes[(i+1)%this->tracklen]);
155              }
156           
157            // create a player
[2644]158            //WorldEntity* myPlayer = (WorldEntity*) this->spawn<Player>();
159            WorldEntity* myPlayer = new Player();
160            this->spawn(myPlayer);
[2640]161            this->localPlayer = myPlayer;
[2636]162           
163            // bind input
164            Orxonox *orx = Orxonox::getInstance();
165            orx->get_localinput()->bind (myPlayer);
166           
167            // bind camera
168            this->localCamera = new Camera(this);
169            this->getCamera()->bind (myPlayer); 
170            break;
171          }
172        default:
173          printf("World::load() - no world with ID %i found", this->debugWorldNr );
174        }
175    }
176  else if(this->worldName != NULL)
177    {
178
179    }
[2731]180
181  // initialize debug coord system
182  objectList = glGenLists(1);
183  glNewList (objectList, GL_COMPILE);
184  glLoadIdentity();
[2792]185  glColor3f(1.0,0,0);
[2817]186  glBegin(GL_QUADS);
[2792]187  float height [500][100];
[2811]188  float size = 2.0;
[2792]189    for ( int i = 0; i<=200; i+=1)
190      {
191        for (int j = 0; j<=50;j+=1)
192          {
[2811]193            height[i][j] = rand()/200321400 + (j-25)*(j-25)/30;
[2792]194           
195          }
196      }
197    for ( int i = 0; i<=200; i+=1)
198      {
199        for (int j = 0; j<=50;j+=1)
200          {       
[2817]201            Vector* v1 = new Vector (size*i,        size*j-25*size,      height[i][j] -20);
202            Vector* v2 = new Vector (size*i+size,    size*j-25*size,      height[i+1][j]-20);
203            Vector* v3 = new Vector (size*i+size,    size*j+size-25*size,  height[i+1][j+1]-20);
204            Vector* v4 = new Vector (size*i,        size*j+size -25*size,  height[i][j+1]-20);
205           
206            Vector c1 = *v2 - *v1;
207            Vector c2 = *v3 - *v2;
208            Vector c3 = *v4 - *v3;
209            Vector c4 = *v1 - *v4;
210           
211            c1.cross(*v4 - *v1);
212            c2.cross(*v1 - *v2);
213            c3.cross(*v2 - *v3);
214            c4.cross(*v3 - *v4);
215
216            glNormal3f(c1.x, c1.y, c1.z);
217            glVertex3f(v1->x, v1->y, v1->z);
218            glNormal3f(c2.x, c2.y, c2.z);
219            glVertex3f(v2->x, v2->y, v2->z);
220            glNormal3f(c3.x, c3.y, c3.z);
221            glVertex3f(v3->x, v3->y, v3->z);
222            glNormal3f(c4.x, c4.y, c4.z);
223            glVertex3f(v4->x, v4->y, v4->z);
224
[2792]225          }
226      }
227glEnd();
228/* 
229  glBegin(GL_LINES);
[2731]230  for( float x = -128.0; x < 128.0; x += 25.0)
231    {
232      for( float y = -128.0; y < 128.0; y += 25.0)
233        {
234          glColor3f(1,0,0);
235          glVertex3f(x,y,-128.0);
236          glVertex3f(x,y,0.0);
237          glColor3f(0.5,0,0);
238          glVertex3f(x,y,0.0);
239          glVertex3f(x,y,128.0);
240        }
241    }
242  for( float y = -128.0; y < 128.0; y += 25.0)
243    {
244      for( float z = -128.0; z < 128.0; z += 25.0)
245        {
246          glColor3f(0,1,0);
247          glVertex3f(-128.0,y,z);
248          glVertex3f(0.0,y,z);
249          glColor3f(0,0.5,0);
250          glVertex3f(0.0,y,z);
251          glVertex3f(128.0,y,z);
252        }
253    }
254  for( float x = -128.0; x < 128.0; x += 25.0)
255    {
256      for( float z = -128.0; z < 128.0; z += 25.0)
257        {
258          glColor3f(0,0,1);
259          glVertex3f(x,-128.0,z);
260          glVertex3f(x,0.0,z);
261          glColor3f(0,0,0.5);
262          glVertex3f(x,0.0,z);
263          glVertex3f(x,128.0,z);
264        }
265     
266    }
[2792]267  */ 
[2731]268  //draw track
[2792]269  glBegin(GL_LINES);
[2731]270  glColor3f(0,1,1);
271  for( int i = 0; i < tracklen; i++)
272    {
273      glVertex3f(pathnodes[i].x,pathnodes[i].y,pathnodes[i].z);
274      glVertex3f(pathnodes[(i+1)%tracklen].x,pathnodes[(i+1)%tracklen].y,pathnodes[(i+1)%tracklen].z);
275    }
276  glEnd();
277  glEndList();
[2636]278}
279
280
281/**
[2551]282    \brief checks for collisions
283   
284    This method runs through all WorldEntities known to the world and checks for collisions
285    between them. In case of collisions the collide() method of the corresponding entities
286    is called.
[1858]287*/
[2190]288void World::collide ()
[1858]289{
[2816]290  /*
291  List *a, *b;
[2551]292  WorldEntity *aobj, *bobj;
[2816]293   
294  a = entities;
[2551]295 
296  while( a != NULL)
297    {
[2816]298      aobj = a->nextElement();
[2551]299      if( aobj->bCollide && aobj->collisioncluster != NULL)
[2190]300        {
[2816]301          b = a->nextElement();
[2551]302          while( b != NULL )
303            {
[2816]304              bobj = b->nextElement();
[2551]305              if( bobj->bCollide && bobj->collisioncluster != NULL )
[2190]306                {
[2551]307                  unsigned long ahitflg, bhitflg;
308                  if( check_collision ( &aobj->place, aobj->collisioncluster,
309                                        &ahitflg, &bobj->place, bobj->collisioncluster,
310                                        &bhitflg) );
311                  {
312                    aobj->collide (bobj, ahitflg, bhitflg);
313                    bobj->collide (aobj, bhitflg, ahitflg);
314                  }
[2190]315                }
[2816]316              b = b->nextElement();
[2551]317            }
[2190]318        }
[2816]319      a = a->enumerate();
[2551]320    }
[2816]321  */
[1858]322}
323
324/**
[2551]325    \brief runs through all entities calling their draw() methods
[1931]326*/
[2190]327void World::draw ()
[2077]328{
[2551]329  // draw geometry
330 
331  // draw entities
332  WorldEntity* entity;
333 
[2822]334  entity = this->entities->enumerate();
[2816]335  while( entity != NULL ) 
[2551]336    { 
[2822]337      if( entity->bDraw ) entity->draw();
338      entity = this->entities->nextElement();
[2551]339    }
340 
341 
342  // draw debug coord system
[2731]343  glCallList (objectList);
[2551]344
[2731]345
[1931]346}
347
348/**
[2551]349    \brief updates Placements and notifies entities when they left the
350    world
351   
352    This runs trough all WorldEntities and maps Locations to Placements
353    if they are bound, checks whether they left the level boundaries
354    and calls appropriate functions.
[1883]355*/
[2190]356void World::update ()
[1883]357{
[2816]358  //List<WorldEntity> *l;
[2551]359  WorldEntity* entity;
360  Location* loc;
361  Placement* plc;
362  Uint32 t;
363 
[2816]364  //  l = entities->enumerate();
365  entity = this->entities->enumerate();
366  while( entity != NULL ) 
[2551]367    { 
[2816]368
[2551]369     
370      if( !entity->isFree() )
371        {
372          loc = entity->get_location();
373          plc = entity->get_placement();
374          t = loc->part;
375         
376          /* check if entity has still a legal track-id */
377          if( t >= tracklen )
378            {
379              printf("An entity is out of the game area\n");
380              entity->left_world ();
381            }
382          else
383            {
384              while( track[t].map_coords( loc, plc) )
[2190]385                {
[2551]386                  track[t].post_leave (entity);
387                  if( loc->part >= tracklen )
388                    {
389                      printf("An entity has left the game area\n");
390                      entity->left_world ();
391                      break;
392                    }
393                  track[loc->part].post_enter (entity);
[2190]394                }
[2551]395            }
[2190]396        }
[2551]397      else
398        {
399          /* TO DO: implement check whether this particular free entity
400             is out of the game area
401             TO DO: call function to notify the entity that it left
402             the game area
403          */
404        }
405     
[2816]406      entity = entities->nextElement();
[2551]407    }
408 
[1883]409}
410
[2077]411/**
[2551]412    \brief relays the passed time since the last frame to entities and Track parts
413    \param deltaT: the time passed since the last frame in milliseconds
[2077]414*/
[2190]415void World::time_slice (Uint32 deltaT)
[2077]416{
[2816]417  //List<WorldEntity> *l;
[2551]418  WorldEntity* entity;
419  float seconds = deltaT;
420 
421  seconds /= 1000;
422 
[2816]423  entity = entities->enumerate(); 
424  while( entity != NULL) 
[2551]425    { 
426      entity->tick (seconds);
[2816]427      entity = entities->nextElement();
[2551]428    }
[2816]429
[2551]430  for( int i = 0; i < tracklen; i++) track[i].tick (seconds);
[2077]431}
[1883]432
[2190]433/**
[2551]434   \brief removes level data from memory
[1858]435*/
[2190]436void World::unload()
[1858]437{
[2551]438  if( pathnodes) delete []pathnodes;
439  if( track) delete []pathnodes;
[1883]440}
[1879]441
[2636]442
443
[2190]444/**
[2636]445   \brief calls the correct mapping function to convert a given "look at"-Location to a
446   Camera Placement
[1858]447*/
[2636]448void World::calc_camera_pos (Location* loc, Placement* plc)
[1858]449{
[2636]450  track[loc->part].map_camera (loc, plc);
451}
452
453
454void World::setTrackLen(Uint32 len)
455{
456  this->tracklen = len;
457}
458
459int World::getTrackLen()
460{
461  return this->tracklen;
462}
463
[2640]464void World::debug()
465{
[2816]466  //List<WorldEntity> *l;
[2640]467  WorldEntity* entity;
468 
469  printf("counting all entities\n");
[2816]470  printf("World::debug() - enumerate()\n");
471  entity = entities->enumerate(); 
472  while( entity != NULL ) 
[2640]473    { 
474      if( entity->bDraw ) printf("got an entity\n");
[2816]475      entity = entities->nextElement();
[2640]476    }
477}
[2636]478
[2640]479
[2636]480void World::mainLoop()
481{
482  this->lastFrame = SDL_GetTicks();
483  this->bQuitOrxonox = false;
484  this->bQuitCurrentGame = false;
485  printf("World|Entering main loop\n");
486  while(!this->bQuitOrxonox && !this->bQuitCurrentGame) /* pause pause pause ?!?!?*/
[2551]487    {
[2640]488      //debug routine
489      //debug();
[2636]490      // Network
491      synchronize();
492      // Process input
493      handle_input();
494      // Process time
495      time_slice();
496      // Process collision
497      collision();
498      // Draw
499      display();
[2816]500 
[2822]501      //for(int i = 0; i < 1000000; i++){}
[2816]502
[2551]503    }
[2636]504  printf("World|Exiting the main loop\n");
[1899]505}
506
[2190]507/**
[2636]508   \brief synchronize local data with remote data
[1855]509*/
[2636]510void World::synchronize ()
[1855]511{
[2636]512  // Get remote input
513  // Update synchronizables
[1855]514}
[2636]515
516/**
517   \brief run all input processing
518*/
519void World::handle_input ()
520{
521  // localinput
522  Orxonox::getInstance()->get_localinput()->process();
523  // remoteinput
524}
525
526/**
527   \brief advance the timeline
528*/
529void World::time_slice ()
530{
531  Uint32 currentFrame = SDL_GetTicks();
532  if(!this->bPause)
533    {
534      Uint32 dt = currentFrame - this->lastFrame;
[2816]535     
[2636]536      if(dt > 0)
537        {
538          float fps = 1000/dt;
539          printf("fps = %f\n", fps);
540        }
541      else
542        {
[2816]543          printf("fps = 1000 but 0ms!\n");
[2636]544        }
[2816]545     
[2636]546      this->time_slice (dt);
547      this->update ();
548      this->localCamera->time_slice (dt);
549    }
550  this->lastFrame = currentFrame;
551}
552
553/**
554   \brief compute collision detection
555*/
556void World::collision ()
557{
558  this->collide ();
559}
560
561/**
562   \brief handle keyboard commands that are not meant for WorldEntities
563   \param cmd: the command to handle
564   \return true if the command was handled by the system or false if it may be passed to the WorldEntities
565*/
566bool World::system_command (Command* cmd)
567{
568  if( !strcmp( cmd->cmd, "quit"))
569    {
570      if( !cmd->bUp) this->bQuitOrxonox = true;
571      return true;
572    }
573  return false;
574}
575
576/**
577        \brief render the current frame
578*/
579void World::display ()
580{
581  // clear buffer
582  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
583  // set camera
584  this->localCamera->apply ();
585  // draw world
586  this->draw();
587  // draw HUD
588  // flip buffers
589  SDL_GL_SwapBuffers();
590}
591
592Camera* World::getCamera()
593{
594  return this->localCamera;
595}
[2644]596
597
598void World::spawn(WorldEntity* entity)
599{
600  Location zeroloc;
601  Location* loc = NULL;
602  WorldEntity* owner;
[2816]603
604  entities->add (entity);
605  zeroloc.dist = 0;
606  zeroloc.part = 0;
607  zeroloc.pos = Vector();
608  zeroloc.rot = Quaternion();
609  loc = &zeroloc;
[2644]610  entity->init (loc, owner);
611  if (entity->bFree)
612    {
613      this->track[loc->part].map_coords( loc, entity->get_placement());
614    }
615  entity->post_spawn ();
[2816]616}
617
618
619void World::spawn(WorldEntity* entity, Location* loc)
620{
621  Location zeroLoc;
622  WorldEntity* owner;
623  this->entities->add (entity);
624  if( loc == NULL)
625    {
626      zeroLoc.dist = 0;
627      zeroLoc.part = 0;
628      zeroLoc.pos = Vector();
629      zeroLoc.rot = Quaternion();
630      loc = &zeroLoc;
631    }
632  entity->init (loc, owner);
633  if (entity->bFree)
634    {
635      this->track[loc->part].map_coords( loc, entity->get_placement());
636    }
637  entity->post_spawn ();
[2644]638  //return entity;
639}
[2816]640
641
642void World::spawn(WorldEntity* entity, Placement* plc)
643{
644  Placement zeroPlc;
645  WorldEntity* owner;
646  if( plc == NULL)
647    {
648      zeroPlc.r = Vector();
649      zeroPlc.w = Quaternion();
650      plc = &zeroPlc;
651    }
652  this->entities->add (entity);
653  entity->init (plc, owner);
654  entity->post_spawn ();
655  //return entity;
656}
Note: See TracBrowser for help on using the repository browser.