Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/bezierTrack: moveing possible (strange Camera-behaviour)

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 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            this->pathnodes = new Vector[6];
102            this->pathnodes[0] = Vector(0, 0, 0);
103            this->pathnodes[1] = Vector(10, 5, 0);
104            this->pathnodes[2] = Vector(20, 0, 0);
105            this->pathnodes[3] = Vector(10, 3, 0);
106            this->pathnodes[4] = Vector(50, 0, 0);
107            this->pathnodes[5] = Vector(100, 0, 0);
108           
109            // create the tracks
110            this->tracklen = 5;
111            this->track = new Track();
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                track->addPoint(this->pathnodes[i]);
116              }
117           
118            // create a player
119            WorldEntity* myPlayer = new Player();
120            this->spawn(myPlayer);
121            this->localPlayer = myPlayer;           
122
123            // bind input
124            Orxonox *orx = Orxonox::getInstance();
125            orx->get_localinput()->bind (myPlayer);
126           
127            // bind camera
128            this->localCamera = new Camera(this);
129            this->getCamera()->bind (myPlayer); 
130
131            Placement* plc = new Placement;
132            plc->r = Vector(100, 10, 10);
133            plc->w = Quaternion();
134            WorldEntity* env = new Environment();
135            this->spawn(env, plc);
136
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
218            glVertex3f(v1->x, v1->y, v1->z);
219
220            glVertex3f(v2->x, v2->y, v2->z);
221
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  WorldEntity* entity;
334 
335  entity = this->entities->enumerate();
336  while( entity != NULL ) 
337    { 
338      if( entity->bDraw ) entity->draw();
339      entity = this->entities->nextElement();
340    }
341 
342 
343  // draw debug coord system
344  glCallList (objectList);
345
346
347}
348
349/**
350    \brief updates Placements and notifies entities when they left the
351    world
352   
353    This runs trough all WorldEntities and maps Locations to Placements
354    if they are bound, checks whether they left the level boundaries
355    and calls appropriate functions.
356*/
357void World::update ()
358{
359  //List<WorldEntity> *l;
360  WorldEntity* entity;
361  Location* loc;
362  Placement* plc;
363  Uint32 t;
364 
365  //  l = entities->enumerate();
366  entity = this->entities->enumerate();
367  while( entity != NULL ) 
368    { 
369
370     
371      if( !entity->isFree() )
372        {
373          loc = entity->get_location();
374          plc = entity->get_placement();
375          t = loc->part;
376         
377          /* check if entity has still a legal track-id */
378          if( t >= tracklen )
379            {
380              printf("An entity is out of the game area\n");
381              entity->left_world ();
382            }
383          else
384            {
385              while( track[t].map_coords( loc, plc) )
386                {
387                  track[t].post_leave (entity);
388                  if( loc->part >= tracklen )
389                    {
390                      printf("An entity has left the game area\n");
391                      entity->left_world ();
392                      break;
393                    }
394                  track[loc->part].post_enter (entity);
395                }
396            }
397        }
398      else
399        {
400          /* TO DO: implement check whether this particular free entity
401             is out of the game area
402             TO DO: call function to notify the entity that it left
403             the game area
404          */
405        }
406     
407      entity = entities->nextElement();
408    }
409 
410}
411
412/**
413    \brief relays the passed time since the last frame to entities and Track parts
414    \param deltaT: the time passed since the last frame in milliseconds
415*/
416void World::time_slice (Uint32 deltaT)
417{
418  //List<WorldEntity> *l;
419  WorldEntity* entity;
420  float seconds = deltaT;
421 
422  seconds /= 1000;
423 
424  entity = entities->enumerate(); 
425  while( entity != NULL) 
426    { 
427      entity->tick (seconds);
428      entity = entities->nextElement();
429    }
430
431  //  for( int i = 0; i < tracklen; i++) track[i].tick (seconds);
432}
433
434/**
435   \brief removes level data from memory
436*/
437void World::unload()
438{
439  if( pathnodes) delete []pathnodes;
440  if( track) delete []pathnodes;
441}
442
443
444
445/**
446   \brief calls the correct mapping function to convert a given "look at"-Location to a
447   Camera Placement
448*/
449void World::calc_camera_pos (Location* loc, Placement* plc)
450{
451  track[loc->part].map_camera (loc, plc);
452}
453
454
455void World::setTrackLen(Uint32 len)
456{
457  this->tracklen = len;
458}
459
460int World::getTrackLen()
461{
462  return this->tracklen;
463}
464
465void World::debug()
466{
467  //List<WorldEntity> *l;
468  WorldEntity* entity;
469 
470  printf("counting all entities\n");
471  printf("World::debug() - enumerate()\n");
472  entity = entities->enumerate(); 
473  while( entity != NULL ) 
474    { 
475      if( entity->bDraw ) printf("got an entity\n");
476      entity = entities->nextElement();
477    }
478}
479
480
481void World::mainLoop()
482{
483  this->lastFrame = SDL_GetTicks();
484  this->bQuitOrxonox = false;
485  this->bQuitCurrentGame = false;
486  printf("World|Entering main loop\n");
487  while(!this->bQuitOrxonox && !this->bQuitCurrentGame) /* pause pause pause ?!?!?*/
488    {
489      //debug routine
490      //debug();
491      // Network
492      synchronize();
493      // Process input
494      handle_input();
495      // Process time
496      time_slice();
497      // Process collision
498      collision();
499      // Draw
500      display();
501 
502      //for(int i = 0; i < 1000000; i++){}
503
504    }
505  printf("World|Exiting the main loop\n");
506}
507
508/**
509   \brief synchronize local data with remote data
510*/
511void World::synchronize ()
512{
513  // Get remote input
514  // Update synchronizables
515}
516
517/**
518   \brief run all input processing
519*/
520void World::handle_input ()
521{
522  // localinput
523  Orxonox::getInstance()->get_localinput()->process();
524  // remoteinput
525}
526
527/**
528   \brief advance the timeline
529*/
530void World::time_slice ()
531{
532  Uint32 currentFrame = SDL_GetTicks();
533  if(!this->bPause)
534    {
535      Uint32 dt = currentFrame - this->lastFrame;
536     
537      if(dt > 0)
538        {
539          float fps = 1000/dt;
540          printf("fps = %f\n", fps);
541        }
542      else
543        {
544          printf("fps = 1000 but 0ms!\n");
545        }
546     
547      this->time_slice (dt);
548      this->update ();
549      this->localCamera->time_slice (dt);
550    }
551  this->lastFrame = currentFrame;
552}
553
554/**
555   \brief compute collision detection
556*/
557void World::collision ()
558{
559  this->collide ();
560}
561
562/**
563   \brief handle keyboard commands that are not meant for WorldEntities
564   \param cmd: the command to handle
565   \return true if the command was handled by the system or false if it may be passed to the WorldEntities
566*/
567bool World::system_command (Command* cmd)
568{
569  if( !strcmp( cmd->cmd, "quit"))
570    {
571      if( !cmd->bUp) this->bQuitOrxonox = true;
572      return true;
573    }
574  return false;
575}
576
577/**
578        \brief render the current frame
579*/
580void World::display ()
581{
582  // clear buffer
583  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
584  // set camera
585  this->localCamera->apply ();
586  // draw world
587  this->draw();
588  // draw HUD
589  // flip buffers
590  SDL_GL_SwapBuffers();
591}
592
593Camera* World::getCamera()
594{
595  return this->localCamera;
596}
597
598
599void World::spawn(WorldEntity* entity)
600{
601  Location zeroloc;
602  Location* loc = NULL;
603  WorldEntity* owner;
604
605  entities->add (entity);
606  zeroloc.dist = 0;
607  zeroloc.part = 0;
608  zeroloc.pos = Vector();
609  zeroloc.rot = Quaternion();
610  loc = &zeroloc;
611  entity->init (loc, owner);
612  if (entity->bFree)
613    {
614      this->track[loc->part].map_coords( loc, entity->get_placement());
615    }
616  entity->post_spawn ();
617}
618
619
620void World::spawn(WorldEntity* entity, Location* loc)
621{
622  Location zeroLoc;
623  WorldEntity* owner;
624  this->entities->add (entity);
625  if( loc == NULL)
626    {
627      zeroLoc.dist = 0;
628      zeroLoc.part = 0;
629      zeroLoc.pos = Vector();
630      zeroLoc.rot = Quaternion();
631      loc = &zeroLoc;
632    }
633  entity->init (loc, owner);
634  if (entity->bFree)
635    {
636      this->track[loc->part].map_coords( loc, entity->get_placement());
637    }
638  entity->post_spawn ();
639  //return entity;
640}
641
642
643void World::spawn(WorldEntity* entity, Placement* plc)
644{
645  Placement zeroPlc;
646  WorldEntity* owner;
647  if( plc == NULL)
648    {
649      zeroPlc.r = Vector();
650      zeroPlc.w = Quaternion();
651      plc = &zeroPlc;
652    }
653  this->entities->add (entity);
654  entity->init (plc, owner);
655  entity->post_spawn ();
656  //return entity;
657}
Note: See TracBrowser for help on using the repository browser.