Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/bezierTrack/src/world.cc @ 3017

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

orxonox/branches/bezierTrack: fixed small error with k++, ++k.

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