Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3199 was 3199, checked in by bensch, 19 years ago

orxonox/trunk/src: heavy 3D-world of dave merged into the Trunk, I do not know if this will work on your architecture Patrick, but you just have to try.

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