Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3279 was 3279, checked in by dave, 19 years ago

branches/old.dave: Die Neigung des Raumschiffes ist jetzt nicht mehr so stark, und jetzt kann man auch 2 Tasten aufs mal drücken, ohne dass das Raumschiffsche jedes mal anhält:)

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