Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/dave/src/world.cc @ 3019

Last change on this file since 3019 was 2860, checked in by dave, 20 years ago

orxonox/branches/dave: das level hat jetzt form angenommen, stand:nach der Convention vom Samstag….

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