Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/bezierTrack: now Camera follows Path. heavy cleanUp of not used stuff like elyptical Camera and so on…

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 "player.h"
21#include "command_node.h"
22#include "camera.h"
23#include "environment.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 tList<WorldEntity>();
38}
39
40World::World (int worldID)
41{
42  this->debugWorldNr = worldID;
43  this->worldName = NULL;
44  this->entities = new tList<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->entities->clear();
77  Orxonox::getInstance()->get_localinput()->reset();
78  this->~World();
79}
80
81Error World::pause()
82{
83  this->isPaused = true;
84}
85
86Error World::resume()
87{
88  this->isPaused = false;
89}
90
91void World::load()
92{
93  if(this->debugWorldNr != -1)
94    {
95      switch(this->debugWorldNr)
96        {
97        case DEBUG_WORLD_0:
98          {
99            // create some path nodes
100           
101            this->tracklen = 6;
102            this->track = new Track();
103
104            track->addPoint (Vector(0, 0, 0));
105            track->addPoint (Vector(10, -5, 0));
106            track->addPoint (Vector(20, 5, 0));
107            track->addPoint (Vector(30, -5, 0));
108            track->addPoint (Vector(40, 0, 0));
109            track->addPoint (Vector(60, 0, 0));
110           
111           
112            // create a player
113            WorldEntity* myPlayer = new Player();
114            this->spawn(myPlayer);
115            this->localPlayer = myPlayer;           
116
117            // bind input
118            Orxonox *orx = Orxonox::getInstance();
119            orx->get_localinput()->bind (myPlayer);
120           
121            // bind camera
122            this->localCamera = new Camera(this);
123            this->getCamera()->bind (myPlayer); 
124
125            Placement* plc = new Placement;
126            plc->pos = Vector(100, 10, 10);
127            plc->rot = Quaternion();
128            WorldEntity* env = new Environment();
129            this->spawn(env, plc);
130
131            break;
132          }
133        case DEBUG_WORLD_1:
134          {
135            // create some path nodes
136            this->pathnodes = new Vector[6];
137            this->pathnodes[0] = Vector(0, 0, 0);
138            this->pathnodes[1] = Vector(20, 10, 10);
139            this->pathnodes[2] = Vector(40, 0, 10);
140            this->pathnodes[3] = Vector(60, 10, 0);
141            this->pathnodes[4] = Vector(80, 20, 10);
142            this->pathnodes[5] = Vector(30, 50, 0);
143           
144            // create the tracks
145            this->tracklen = 6;
146            this->track = new Track[6];
147            for( int i = 0; i < this->tracklen; i++)
148              {
149                //              this->track[i] = Track( i, (i+1)%this->tracklen, &this->pathnodes[i], &this->pathnodes[(i+1)%this->tracklen]);
150              }
151           
152            // create a player
153            //WorldEntity* myPlayer = (WorldEntity*) this->spawn<Player>();
154            WorldEntity* myPlayer = new Player();
155            this->spawn(myPlayer);
156            this->localPlayer = myPlayer;
157           
158            // bind input
159            Orxonox *orx = Orxonox::getInstance();
160            orx->get_localinput()->bind (myPlayer);
161           
162            // bind camera
163            this->localCamera = new Camera(this);
164            this->getCamera()->bind (myPlayer); 
165            break;
166          }
167        default:
168          printf("World::load() - no world with ID %i found", this->debugWorldNr );
169        }
170    }
171  else if(this->worldName != NULL)
172    {
173
174    }
175
176  // initialize debug coord system
177  objectList = glGenLists(1);
178  glNewList (objectList, GL_COMPILE);
179  glLoadIdentity();
180  glColor3f(1.0,0,0);
181  glBegin(GL_QUADS);
182  float height [500][100];
183  float size = 2.0;
184    for ( int i = 0; i<=200; i+=1)
185      {
186        for (int j = 0; j<=50;j+=1)
187          {
188            height[i][j] = rand()/200321400 + (j-25)*(j-25)/30;
189           
190          }
191      }
192    for ( int i = 0; i<=200; i+=1)
193      {
194        for (int j = 0; j<=50;j+=1)
195          {       
196            Vector* v1 = new Vector (size*i,        size*j-25*size,      height[i][j] -20);
197            Vector* v2 = new Vector (size*i+size,    size*j-25*size,      height[i+1][j]-20);
198            Vector* v3 = new Vector (size*i+size,    size*j+size-25*size,  height[i+1][j+1]-20);
199            Vector* v4 = new Vector (size*i,        size*j+size -25*size,  height[i][j+1]-20);
200           
201            Vector c1 = *v2 - *v1;
202            Vector c2 = *v3 - *v2;
203            Vector c3 = *v4 - *v3;
204            Vector c4 = *v1 - *v4;
205           
206            c1.cross(*v4 - *v1);
207            c2.cross(*v1 - *v2);
208            c3.cross(*v2 - *v3);
209            c4.cross(*v3 - *v4);
210
211
212            glVertex3f(v1->x, v1->y, v1->z);
213
214            glVertex3f(v2->x, v2->y, v2->z);
215
216            glVertex3f(v3->x, v3->y, v3->z);
217            glNormal3f(c4.x, c4.y, c4.z);
218            glVertex3f(v4->x, v4->y, v4->z);
219
220          }
221      }
222glEnd();
223/* 
224  glBegin(GL_LINES);
225  for( float x = -128.0; x < 128.0; x += 25.0)
226    {
227      for( float y = -128.0; y < 128.0; y += 25.0)
228        {
229          glColor3f(1,0,0);
230          glVertex3f(x,y,-128.0);
231          glVertex3f(x,y,0.0);
232          glColor3f(0.5,0,0);
233          glVertex3f(x,y,0.0);
234          glVertex3f(x,y,128.0);
235        }
236    }
237  for( float y = -128.0; y < 128.0; y += 25.0)
238    {
239      for( float z = -128.0; z < 128.0; z += 25.0)
240        {
241          glColor3f(0,1,0);
242          glVertex3f(-128.0,y,z);
243          glVertex3f(0.0,y,z);
244          glColor3f(0,0.5,0);
245          glVertex3f(0.0,y,z);
246          glVertex3f(128.0,y,z);
247        }
248    }
249  for( float x = -128.0; x < 128.0; x += 25.0)
250    {
251      for( float z = -128.0; z < 128.0; z += 25.0)
252        {
253          glColor3f(0,0,1);
254          glVertex3f(x,-128.0,z);
255          glVertex3f(x,0.0,z);
256          glColor3f(0,0,0.5);
257          glVertex3f(x,0.0,z);
258          glVertex3f(x,128.0,z);
259        }
260     
261    }
262  */ 
263  //draw track
264  glBegin(GL_LINE_STRIP);
265  glColor3f(0,1,1);
266  for( float i = 0; i <= 1; i+=.01)
267    {
268      glVertex3f(track->getPos(i).x, track->getPos(i).y, track->getPos(i).z);
269    }
270  glEnd();
271  glEndList();
272}
273
274
275/**
276    \brief checks for collisions
277   
278    This method runs through all WorldEntities known to the world and checks for collisions
279    between them. In case of collisions the collide() method of the corresponding entities
280    is called.
281*/
282void World::collide ()
283{
284  /*
285  List *a, *b;
286  WorldEntity *aobj, *bobj;
287   
288  a = entities;
289 
290  while( a != NULL)
291    {
292      aobj = a->nextElement();
293      if( aobj->bCollide && aobj->collisioncluster != NULL)
294        {
295          b = a->nextElement();
296          while( b != NULL )
297            {
298              bobj = b->nextElement();
299              if( bobj->bCollide && bobj->collisioncluster != NULL )
300                {
301                  unsigned long ahitflg, bhitflg;
302                  if( check_collision ( &aobj->place, aobj->collisioncluster,
303                                        &ahitflg, &bobj->place, bobj->collisioncluster,
304                                        &bhitflg) );
305                  {
306                    aobj->collide (bobj, ahitflg, bhitflg);
307                    bobj->collide (aobj, bhitflg, ahitflg);
308                  }
309                }
310              b = b->nextElement();
311            }
312        }
313      a = a->enumerate();
314    }
315  */
316}
317
318/**
319    \brief runs through all entities calling their draw() methods
320*/
321void World::draw ()
322{
323  // draw geometry
324 
325  // draw entities
326  WorldEntity* entity;
327 
328  entity = this->entities->enumerate();
329  while( entity != NULL ) 
330    { 
331      if( entity->bDraw ) entity->draw();
332      entity = this->entities->nextElement();
333    }
334 
335 
336  // draw debug coord system
337  glCallList (objectList);
338
339
340}
341
342/**
343    \brief updates Placements and notifies entities when they left the
344    world
345   
346    This runs trough all WorldEntities and maps Locations to Placements
347    if they are bound, checks whether they left the level boundaries
348    and calls appropriate functions.
349*/
350void World::update ()
351{
352  //List<WorldEntity> *l;
353  WorldEntity* entity;
354  Location* loc;
355  Placement* plc;
356  Uint32 t;
357 
358  //  l = entities->enumerate();
359  entity = this->entities->enumerate();
360  while( entity != NULL ) 
361    { 
362
363     
364      if( !entity->isFree() )
365        {
366          loc = entity->get_location();
367          plc = entity->get_placement();
368          t = loc->part;
369         
370          /* check if entity has still a legal track-id */
371          if( t >= tracklen )
372            {
373              printf("An entity is out of the game area\n");
374              entity->left_world ();
375            }
376          else
377            {
378              while( track[t].map_coords( loc, plc) )
379                {
380                  track[t].post_leave (entity);
381                  if( loc->part >= tracklen )
382                    {
383                      printf("An entity has left the game area\n");
384                      entity->left_world ();
385                      break;
386                    }
387                  track[loc->part].post_enter (entity);
388                }
389            }
390        }
391      else
392        {
393          /* TO DO: implement check whether this particular free entity
394             is out of the game area
395             TO DO: call function to notify the entity that it left
396             the game area
397          */
398        }
399     
400      entity = entities->nextElement();
401    }
402 
403}
404
405/**
406    \brief relays the passed time since the last frame to entities and Track parts
407    \param deltaT: the time passed since the last frame in milliseconds
408*/
409void World::time_slice (Uint32 deltaT)
410{
411  //List<WorldEntity> *l;
412  WorldEntity* entity;
413  float seconds = deltaT;
414 
415  seconds /= 1000;
416 
417  entity = entities->enumerate(); 
418  while( entity != NULL) 
419    { 
420      entity->tick (seconds);
421      entity = entities->nextElement();
422    }
423
424  track->tick(seconds);
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.