Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the ObjectImporter to trunk: merged with
svn merge branches/importer/src/ trunk/src/ -r 2794:HEAD

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