Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/buerli/src/world.cc @ 3019

Last change on this file since 3019 was 2707, checked in by bensch, 20 years ago

orxonox/branches/buerli: merged back from trunk, with new configure makefile and so forth.

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