Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/src: new list implemented

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