Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: fixed importer autoconf in configure.ac

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