Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3220 was 3220, checked in by patrick, 19 years ago

orxonox/trunk: fixed a lot of bugs with StoryEntity management, also cleared up some old unused code

File size: 16.2 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  printf("World::~World() - deleting current world\n");
54  CommandNode* cn = Orxonox::getInstance()->get_localinput();
55  cn->unbind(this->localPlayer);
56  cn->reset();
57  this->localCamera->destroy();
58
59  WorldEntity* entity = entities->enumerate(); 
60  while( entity != NULL ) 
61    { 
62      entity->destroy();
63      entity = entities->nextElement();
64    }
65  this->entities->destroy();
66
67  delete this->entities;
68  delete this->localCamera;
69  /* this->localPlayer hasn't to be deleted explicitly, it is
70     contained in entities*/
71}
72
73
74/**
75    \brief initialize the world before use.
76*/
77Error World::init()
78{
79  this->bPause = false;
80  CommandNode* cn = Orxonox::getInstance()->get_localinput();
81  cn->addToWorld(this);
82  cn->enable(true);
83}
84
85Error World::start()
86{
87  printf("World::start() - starting current World: nr %i\n", this->debugWorldNr);
88  this->bQuitOrxonox = false;
89  this->bQuitCurrentGame = false;
90  this->mainLoop();
91}
92
93Error World::stop()
94{
95  printf("World::stop() - got stop signal\n");
96  this->bQuitCurrentGame = true;
97}
98
99Error World::pause()
100{
101  this->isPaused = true;
102}
103
104Error World::resume()
105{
106  this->isPaused = false;
107}
108
109void World::load()
110{
111  if(this->debugWorldNr != -1)
112    {
113      switch(this->debugWorldNr)
114        {
115        case DEBUG_WORLD_0:
116          {
117            // create some path nodes
118            this->pathnodes = new Vector[6];
119            this->pathnodes[0] = Vector(0, 0, 0);
120            this->pathnodes[1] = Vector(1000, 0, 0);
121            //      this->pathnodes[2] = Vector(-100, 140, 0);
122            //      this->pathnodes[3] = Vector(0, 180, 0);
123            //      this->pathnodes[4] = Vector(100, 140, 0);
124            //      this->pathnodes[5] = Vector(100, 40, 0);
125           
126            // create the tracks
127            this->tracklen = 2;
128            this->track = new Track[2];
129            for( int i = 0; i < this->tracklen; i++)
130              {
131                this->track[i] = Track( i, (i+1)%this->tracklen, &this->pathnodes[i], &this->pathnodes[(i+1)%this->tracklen]);
132              }
133            // !\todo old track-system has to be removed
134
135            // create a player
136            WorldEntity* myPlayer = new Player();
137            this->spawn(myPlayer);
138            this->localPlayer = myPlayer;           
139
140            // bind input
141            Orxonox *orx = Orxonox::getInstance();
142            orx->get_localinput()->bind (myPlayer);
143           
144            // bind camera
145            this->localCamera = new Camera(this);
146            this->getCamera()->bind (myPlayer); 
147
148            Placement* plc = new Placement;
149            plc->r = Vector(100, 10, 10);
150            plc->w = Quaternion();
151            WorldEntity* env = new Environment();
152            this->spawn(env, plc);
153
154            break;
155          }
156        case DEBUG_WORLD_1:
157          {
158            // create some path nodes
159            this->pathnodes = new Vector[6];
160            this->pathnodes[0] = Vector(0, 0, 0);
161            this->pathnodes[1] = Vector(20, 10, 10);
162            this->pathnodes[2] = Vector(40, 0, 10);
163            this->pathnodes[3] = Vector(60, 10, 0);
164            this->pathnodes[4] = Vector(80, 20, 10);
165            this->pathnodes[5] = Vector(30, 50, 0);
166           
167            // create the tracks
168            this->tracklen = 6;
169            this->track = new Track[6];
170            for( int i = 0; i < this->tracklen; i++)
171              {
172                this->track[i] = Track( i, (i+1)%this->tracklen, &this->pathnodes[i], &this->pathnodes[(i+1)%this->tracklen]);
173              }
174
175            // create a player
176            WorldEntity* myPlayer = new Player();
177            this->spawn(myPlayer);
178            this->localPlayer = myPlayer;           
179           
180            // bind input
181            Orxonox *orx = Orxonox::getInstance();
182            orx->get_localinput()->bind (myPlayer);
183           
184            // bind camera
185            this->localCamera = new Camera(this);
186            this->getCamera()->bind (myPlayer); 
187            break;
188          }
189        default:
190          printf("World::load() - no world with ID %i found", this->debugWorldNr );
191        }
192    }
193  else if(this->worldName != NULL)
194    {
195
196    }
197
198  // initialize debug coord system
199  objectList = glGenLists(1);
200  glNewList (objectList, GL_COMPILE);
201  glLoadIdentity();
202  glColor3f(1.0,0,0);
203  glBegin(GL_QUADS);
204
205  int sizeX = 100;
206  int sizeY = 80;
207  float length = 1000;
208  float width = 200;
209  float widthX = float (length /sizeX);
210  float widthY = float (width /sizeY);
211 
212  float height [sizeX][sizeY];
213  Vector normal_vectors[sizeX][sizeY];
214 
215 
216  for ( int i = 0; i<sizeX-1; i+=1)
217    for (int j = 0; j<sizeY-1;j+=1)
218      //height[i][j] = rand()/20046 + (j-25)*(j-25)/30;
219#ifdef __WIN32__
220      height[i][j]=(sin((float)j/3)*rand()*i/182400)*.5;
221#else
222      height[i][j]=(sin((float)j/3)*rand()*(long)i/6282450500.0)*.5;
223#endif
224
225  //Die Hügel ein wenig glätten
226  for (int h=1; h<2;h++)
227    for (int i=1;i<sizeX-2 ;i+=1 )
228      for(int j=1;j<sizeY-2;j+=1)
229        height[i][j]=(height[i+1][j]+height[i][j+1]+height[i-1][j]+height[i][j-1])/4;
230 
231  //Berechnung von normalen Vektoren
232
233  for(int i=1;i<sizeX-2;i+=1)
234    for(int j=1;j<sizeY-2 ;j+=1)
235      {
236        Vector v1 = Vector (widthX*(1),      widthY*(j)  ,      height[i][j]);
237        Vector v2 = Vector (widthX*(i-1),    widthY*(j)  ,      height[i-1][j]);
238        Vector v3 = Vector (widthX*(i),      widthY*(j+1),      height[i][j+1]);
239        Vector v4 = Vector (widthX*(i+1),    widthY*(j),        height[i+1][j]);
240        Vector v5 = Vector (widthX*(i),      widthY*(j-1),      height[i][j-1]);
241       
242        Vector c1 = v2 - v1;
243        Vector c2 = v3 - v1;
244        Vector c3=  v4 - v1;
245        Vector c4 = v5 - v1;
246        Vector zero = Vector (0,0,0);
247        normal_vectors[i][j]=c1.cross(v4-v2)+c2.cross(v1-v3)+c3.cross(v2-v4)+c4.cross(v3-v1);
248        normal_vectors[i][j].normalize();
249      }
250
251  int snowheight=3;
252  for ( int i = 0; i<sizeX; i+=1)
253    for (int j = 0; j<sizeY;j+=1)
254      {   
255        Vector v1 = Vector (widthX*(i),      widthY*(j)  -width/2,      height[i][j]-20 );
256        Vector v2 = Vector (widthX*(i+1),    widthY*(j)  -width/2,      height[i+1][j]-20);
257        Vector v3 = Vector (widthX*(i+1),    widthY*(j+1)-width/2,    height[i+1][j+1]-20);
258        Vector v4 = Vector (widthX*(i),      widthY*(j+1)-width/2,    height[i][j+1]-20);
259        float a[3];
260        if(height[i][j]<snowheight){
261          a[0]=0;
262          a[1]=1.0-height[i][j]/10-.3;
263          a[2]=0;
264          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
265        }
266        else{
267            a[0]=1.0;
268            a[1]=1.0;
269            a[2]=1.0;
270            glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
271           
272        }
273        glNormal3f(normal_vectors[i][j].x, normal_vectors[i][j].y, normal_vectors[i][j].z);
274        glVertex3f(v1.x, v1.y, v1.z);
275        if(height[i+1][j]<snowheight){
276          a[0]=0;
277          a[1] =1.0-height[i+1][j]/10-.3;
278          a[2]=0;
279          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
280        }
281        else{
282          a[0]=1.0;
283          a[1]=1.0;
284          a[2]=1.0;
285          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
286         
287        }
288        glNormal3f(normal_vectors[i+1][j].x, normal_vectors[i+1][j].y, normal_vectors[i+1][j].z);
289        glVertex3f(v2.x, v2.y, v2.z);
290        if(height[i+1][j+1]<snowheight){
291          a[0]=0;
292          a[1] =1.0-height[i+1][j+1]/10-.3;
293          a[2]=0;
294          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
295        }
296        else{
297          a[0]=1.0;
298          a[1]=1.0;
299          a[2]=1.0;
300          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
301         
302         
303        }
304        glNormal3f(normal_vectors[i+1][j+1].x, normal_vectors[i+1][j+1].y, normal_vectors[i+1][j+1].z);
305        glVertex3f(v3.x, v3.y, v3.z);
306        if(height[i][j+1]<snowheight){
307          a[0]=0;
308          a[1] =1.0-height[i+1][j+1]/10-.3;
309          a[2]=0;
310          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
311        }
312        else{
313          a[0]=1.0;
314          a[1]=1.0;
315          a[2]=1.0;
316          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
317        }
318        glNormal3f(normal_vectors[i][j+1].x, normal_vectors[i][j+1].y, normal_vectors[i][j+1].z);
319        glVertex3f(v4.x, v4.y, v4.z);
320       
321      }
322  glEnd();
323  /* 
324  glBegin(GL_LINES);
325  for( float x = -128.0; x < 128.0; x += 25.0)
326    {
327      for( float y = -128.0; y < 128.0; y += 25.0)
328        {
329          glColor3f(1,0,0);
330          glVertex3f(x,y,-128.0);
331          glVertex3f(x,y,0.0);
332          glColor3f(0.5,0,0);
333          glVertex3f(x,y,0.0);
334          glVertex3f(x,y,128.0);
335        }
336    }
337  for( float y = -128.0; y < 128.0; y += 25.0)
338    {
339      for( float z = -128.0; z < 128.0; z += 25.0)
340        {
341          glColor3f(0,1,0);
342          glVertex3f(-128.0,y,z);
343          glVertex3f(0.0,y,z);
344          glColor3f(0,0.5,0);
345          glVertex3f(0.0,y,z);
346          glVertex3f(128.0,y,z);
347        }
348    }
349  for( float x = -128.0; x < 128.0; x += 25.0)
350    {
351      for( float z = -128.0; z < 128.0; z += 25.0)
352        {
353          glColor3f(0,0,1);
354          glVertex3f(x,-128.0,z);
355          glVertex3f(x,0.0,z);
356          glColor3f(0,0,0.5);
357          glVertex3f(x,0.0,z);
358          glVertex3f(x,128.0,z);
359        }
360     
361    }
362  */ 
363  //draw track
364  glBegin(GL_LINES);
365  glColor3f(0,1,1);
366  for( int i = 0; i < tracklen; i++)
367    {
368      glVertex3f(pathnodes[i].x,pathnodes[i].y,pathnodes[i].z);
369      glVertex3f(pathnodes[(i+1)%tracklen].x,pathnodes[(i+1)%tracklen].y,pathnodes[(i+1)%tracklen].z);
370    }
371  glEnd();
372  glEndList();
373}
374
375
376/**
377    \brief checks for collisions
378   
379    This method runs through all WorldEntities known to the world and checks for collisions
380    between them. In case of collisions the collide() method of the corresponding entities
381    is called.
382*/
383void World::collide ()
384{
385  /*
386  List *a, *b;
387  WorldEntity *aobj, *bobj;
388   
389  a = entities;
390 
391  while( a != NULL)
392    {
393      aobj = a->nextElement();
394      if( aobj->bCollide && aobj->collisioncluster != NULL)
395        {
396          b = a->nextElement();
397          while( b != NULL )
398            {
399              bobj = b->nextElement();
400              if( bobj->bCollide && bobj->collisioncluster != NULL )
401                {
402                  unsigned long ahitflg, bhitflg;
403                  if( check_collision ( &aobj->place, aobj->collisioncluster,
404                                        &ahitflg, &bobj->place, bobj->collisioncluster,
405                                        &bhitflg) );
406                  {
407                    aobj->collide (bobj, ahitflg, bhitflg);
408                    bobj->collide (aobj, bhitflg, ahitflg);
409                  }
410                }
411              b = b->nextElement();
412            }
413        }
414      a = a->enumerate();
415    }
416  */
417}
418
419/**
420    \brief runs through all entities calling their draw() methods
421*/
422void World::draw ()
423{
424  // draw geometry
425 
426  // draw entities
427  WorldEntity* entity;
428 
429  entity = this->entities->enumerate();
430  while( entity != NULL ) 
431    { 
432      if( entity->bDraw ) entity->draw();
433      entity = this->entities->nextElement();
434    }
435 
436 
437  // draw debug coord system
438  glCallList (objectList);
439
440
441}
442
443/**
444    \brief updates Placements and notifies entities when they left the
445    world
446   
447    This runs trough all WorldEntities and maps Locations to Placements
448    if they are bound, checks whether they left the level boundaries
449    and calls appropriate functions.
450*/
451void World::update ()
452{
453  //List<WorldEntity> *l;
454  WorldEntity* entity;
455  Location* loc;
456  Placement* plc;
457  Uint32 t;
458 
459  //  l = entities->enumerate();
460  entity = this->entities->enumerate();
461  while( entity != NULL ) 
462    { 
463
464     
465      if( !entity->isFree() )
466        {
467          loc = entity->get_location();
468          plc = entity->get_placement();
469          t = loc->part;
470         
471          /* check if entity has still a legal track-id */
472          if( t >= tracklen )
473            {
474              printf("An entity is out of the game area\n");
475              entity->left_world ();
476            }
477          else
478            {
479              while( track[t].map_coords( loc, plc) )
480                {
481                  track[t].post_leave (entity);
482                  if( loc->part >= tracklen )
483                    {
484                      printf("An entity has left the game area\n");
485                      entity->left_world ();
486                      break;
487                    }
488                  track[loc->part].post_enter (entity);
489                }
490            }
491        }
492      else
493        {
494          /* TO DO: implement check whether this particular free entity
495             is out of the game area
496             TO DO: call function to notify the entity that it left
497             the game area
498          */
499        }
500     
501      entity = entities->nextElement();
502    }
503 
504}
505
506/**
507    \brief relays the passed time since the last frame to entities and Track parts
508    \param deltaT: the time passed since the last frame in milliseconds
509*/
510void World::time_slice (Uint32 deltaT)
511{
512  //List<WorldEntity> *l;
513  WorldEntity* entity;
514  float seconds = deltaT / 1000.0;
515 
516  entity = entities->enumerate(); 
517  while( entity != NULL) 
518    { 
519      entity->tick (seconds);
520      entity = entities->nextElement();
521    }
522
523  //for( int i = 0; i < tracklen; i++) track[i].tick (seconds);
524}
525
526/**
527   \brief removes level data from memory
528*/
529void World::unload()
530{
531  if( pathnodes) delete []pathnodes;
532  if( track) delete []pathnodes;
533}
534
535
536
537/**
538   \brief calls the correct mapping function to convert a given "look at"-Location to a
539   Camera Placement
540*/
541void World::calc_camera_pos (Location* loc, Placement* plc)
542{
543  track[loc->part].map_camera (loc, plc);
544}
545
546
547void World::setTrackLen(Uint32 len)
548{
549  this->tracklen = len;
550}
551
552int World::getTrackLen()
553{
554  return this->tracklen;
555}
556
557void World::debug()
558{
559  //List<WorldEntity> *l;
560  WorldEntity* entity;
561 
562  printf("counting all entities\n");
563  printf("World::debug() - enumerate()\n");
564  entity = entities->enumerate(); 
565  while( entity != NULL ) 
566    { 
567      if( entity->bDraw ) printf("got an entity\n");
568      entity = entities->nextElement();
569    }
570}
571
572
573void World::mainLoop()
574{
575  this->lastFrame = SDL_GetTicks();
576  printf("World::mainLoop() - Entering main loop\n");
577  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
578    {
579      //debug routine
580      //debug();
581      // Network
582      synchronize();
583      // Process input
584      handle_input();
585      if( this->bQuitCurrentGame || this->bQuitOrxonox)
586        {
587          printf("World::mainLoop() - leaving loop earlier...\n");
588          break;
589        }
590      // Process time
591      time_slice();
592      // Process collision
593      collision();
594      // Draw
595      display();
596 
597      for(int i = 0; i < 10000000; i++) {}
598    }
599  printf("World::mainLoop() - Exiting the main loop\n");
600}
601
602/**
603   \brief synchronize local data with remote data
604*/
605void World::synchronize ()
606{
607  // Get remote input
608  // Update synchronizables
609}
610
611/**
612   \brief run all input processing
613*/
614void World::handle_input ()
615{
616  // localinput
617  CommandNode* cn = Orxonox::getInstance()->get_localinput();
618  cn->process();
619  // remoteinput
620}
621
622/**
623   \brief advance the timeline
624*/
625void World::time_slice ()
626{
627  Uint32 currentFrame = SDL_GetTicks();
628  if(!this->bPause)
629    {
630      Uint32 dt = currentFrame - this->lastFrame;
631     
632      if(dt > 0)
633        {
634          float fps = 1000/dt;
635          printf("fps = %f\n", fps);
636        }
637      else
638        {
639          printf("fps = 1000 - frame rate is adjusted\n");
640          SDL_Delay(10);
641          dt = 10;
642        }
643     
644      this->time_slice (dt);
645      this->update ();
646      this->localCamera->time_slice (dt);
647    }
648  this->lastFrame = currentFrame;
649}
650
651
652/**
653   \brief compute collision detection
654*/
655void World::collision ()
656{
657  this->collide ();
658}
659
660
661/**
662        \brief render the current frame
663*/
664void World::display ()
665{
666  // clear buffer
667  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
668  // set camera
669  this->localCamera->apply ();
670  // draw world
671  this->draw();
672  // draw HUD
673  // flip buffers
674  SDL_GL_SwapBuffers();
675}
676
677Camera* World::getCamera()
678{
679  return this->localCamera;
680}
681
682
683void World::spawn(WorldEntity* entity)
684{
685  Location zeroloc;
686  Location* loc = NULL;
687  WorldEntity* owner;
688
689  entities->add (entity);
690  zeroloc.dist = 0;
691  zeroloc.part = 0;
692  zeroloc.pos = Vector();
693  zeroloc.rot = Quaternion();
694  loc = &zeroloc;
695  entity->init (loc, owner);
696  if (entity->bFree)
697    {
698      this->track[loc->part].map_coords( loc, entity->get_placement());
699    }
700  entity->post_spawn ();
701}
702
703
704void World::spawn(WorldEntity* entity, Location* loc)
705{
706  Location zeroLoc;
707  WorldEntity* owner;
708  this->entities->add (entity);
709  if( loc == NULL)
710    {
711      zeroLoc.dist = 0;
712      zeroLoc.part = 0;
713      zeroLoc.pos = Vector();
714      zeroLoc.rot = Quaternion();
715      loc = &zeroLoc;
716    }
717  entity->init (loc, owner);
718  if (entity->bFree)
719    {
720      this->track[loc->part].map_coords( loc, entity->get_placement());
721    }
722  entity->post_spawn ();
723  //return entity;
724}
725
726
727void World::spawn(WorldEntity* entity, Placement* plc)
728{
729  Placement zeroPlc;
730  WorldEntity* owner;
731  if( plc == NULL)
732    {
733      zeroPlc.r = Vector();
734      zeroPlc.w = Quaternion();
735      plc = &zeroPlc;
736    }
737  this->entities->add (entity);
738  entity->init (plc, owner);
739  entity->post_spawn ();
740  //return entity;
741}
742
743
744bool World::command(Command* cmd)
745{
746  return false;
747}
Note: See TracBrowser for help on using the repository browser.