Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2793 was 2792, checked in by bensch, 20 years ago

orxonox/trunk: redesigned the world.

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