Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/bezierTrack: moved Curve to its own file. I expect this class to be bigger than I thought at the beginning:

  1. Class Curve and its subclasses: a) BezierCurve b) closedBezierCurve c) Nurbs d) any other curve that might occure

this will take some time and many hours of thinking so please help

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