Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2776 was 2731, checked in by bensch, 20 years ago

orxonox/trunk: applyed List to world object too

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