Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3176 was 3155, checked in by dave, 20 years ago

Bin dran die Bewegung smoother zu machen-first try

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    \brief checks for collisions
361   
362    This method runs through all WorldEntities known to the world and checks for collisions
363    between them. In case of collisions the collide() method of the corresponding entities
364    is called.
365*/
366void World::collide ()
367{
368  /*
369  List *a, *b;
370  WorldEntity *aobj, *bobj;
371   
372  a = entities;
373 
374  while( a != NULL)
375    {
376      aobj = a->nextElement();
377      if( aobj->bCollide && aobj->collisioncluster != NULL)
378        {
379          b = a->nextElement();
380          while( b != NULL )
381            {
382              bobj = b->nextElement();
383              if( bobj->bCollide && bobj->collisioncluster != NULL )
384                {
385                  unsigned long ahitflg, bhitflg;
386                  if( check_collision ( &aobj->place, aobj->collisioncluster,
387                                        &ahitflg, &bobj->place, bobj->collisioncluster,
388                                        &bhitflg) );
389                  {
390                    aobj->collide (bobj, ahitflg, bhitflg);
391                    bobj->collide (aobj, bhitflg, ahitflg);
392                  }
393                }
394              b = b->nextElement();
395            }
396        }
397      a = a->enumerate();
398    }
399  */
400}
401
402/**
403    \brief runs through all entities calling their draw() methods
404*/
405void World::draw ()
406{
407  // draw geometry
408 
409  // draw entities
410  WorldEntity* entity;
411 
412  entity = this->entities->enumerate();
413  while( entity != NULL ) 
414    { 
415      if( entity->bDraw ) entity->draw();
416      entity = this->entities->nextElement();
417    }
418 
419 
420  // draw debug coord system
421  glCallList (objectList);
422
423
424}
425
426/**
427    \brief updates Placements and notifies entities when they left the
428    world
429   
430    This runs trough all WorldEntities and maps Locations to Placements
431    if they are bound, checks whether they left the level boundaries
432    and calls appropriate functions.
433*/
434void World::update ()
435{
436  //List<WorldEntity> *l;
437  WorldEntity* entity;
438  Location* loc;
439  Placement* plc;
440  Uint32 t;
441 
442  //  l = entities->enumerate();
443  entity = this->entities->enumerate();
444  while( entity != NULL ) 
445    { 
446
447     
448      if( !entity->isFree() )
449        {
450          loc = entity->get_location();
451          plc = entity->get_placement();
452          t = loc->part;
453         
454          /* check if entity has still a legal track-id */
455          if( t >= tracklen )
456            {
457              printf("An entity is out of the game area\n");
458              entity->left_world ();
459            }
460          else
461            {
462              while( track[t].map_coords( loc, plc) )
463                {
464                  track[t].post_leave (entity);
465                  if( loc->part >= tracklen )
466                    {
467                      printf("An entity has left the game area\n");
468                      entity->left_world ();
469                      break;
470                    }
471                  track[loc->part].post_enter (entity);
472                }
473            }
474        }
475      else
476        {
477          /* TO DO: implement check whether this particular free entity
478             is out of the game area
479             TO DO: call function to notify the entity that it left
480             the game area
481          */
482        }
483     
484      entity = entities->nextElement();
485    }
486 
487}
488
489/**
490    \brief relays the passed time since the last frame to entities and Track parts
491    \param deltaT: the time passed since the last frame in milliseconds
492*/
493void World::time_slice (Uint32 deltaT)
494{
495  //List<WorldEntity> *l;
496  WorldEntity* entity;
497  float seconds = deltaT;
498 
499  seconds /= 1000;
500 
501  entity = entities->enumerate(); 
502  while( entity != NULL) 
503    { 
504      entity->tick (seconds);
505      entity = entities->nextElement();
506    }
507
508  for( int i = 0; i < tracklen; i++) track[i].tick (seconds);
509}
510
511/**
512   \brief removes level data from memory
513*/
514void World::unload()
515{
516  if( pathnodes) delete []pathnodes;
517  if( track) delete []pathnodes;
518}
519
520
521
522/**
523   \brief calls the correct mapping function to convert a given "look at"-Location to a
524   Camera Placement
525*/
526void World::calc_camera_pos (Location* loc, Placement* plc)
527{
528  track[loc->part].map_camera (loc, plc);
529}
530
531
532void World::setTrackLen(Uint32 len)
533{
534  this->tracklen = len;
535}
536
537int World::getTrackLen()
538{
539  return this->tracklen;
540}
541
542void World::debug()
543{
544  //List<WorldEntity> *l;
545  WorldEntity* entity;
546 
547  printf("counting all entities\n");
548  printf("World::debug() - enumerate()\n");
549  entity = entities->enumerate(); 
550  while( entity != NULL ) 
551    { 
552      if( entity->bDraw ) printf("got an entity\n");
553      entity = entities->nextElement();
554    }
555}
556
557
558void World::mainLoop()
559{
560  this->lastFrame = SDL_GetTicks();
561  this->bQuitOrxonox = false;
562  this->bQuitCurrentGame = false;
563  printf("World|Entering main loop\n");
564  while(!this->bQuitOrxonox && !this->bQuitCurrentGame) /* pause pause pause ?!?!?*/
565    {
566      //debug routine
567      //debug();
568      // Network
569      synchronize();
570      // Process input
571      handle_input();
572      // Process time
573      time_slice();
574      // Process collision
575      collision();
576      // Draw
577      display();
578 
579      //for(int i = 0; i < 1000000; i++){}
580
581    }
582  printf("World|Exiting the main loop\n");
583}
584
585/**
586   \brief synchronize local data with remote data
587*/
588void World::synchronize ()
589{
590  // Get remote input
591  // Update synchronizables
592}
593
594/**
595   \brief run all input processing
596*/
597void World::handle_input ()
598{
599  // localinput
600  Orxonox::getInstance()->get_localinput()->process();
601  // remoteinput
602}
603
604/**
605   \brief advance the timeline
606*/
607void World::time_slice ()
608{
609  Uint32 currentFrame = SDL_GetTicks();
610  if(!this->bPause)
611    {
612      Uint32 dt = currentFrame - this->lastFrame;
613     
614      if(dt > 0)
615        {
616          float fps = 1000/dt;
617          printf("fps = %f\n", fps);
618        }
619      else
620        {
621          printf("fps = 1000 but 0ms!\n");
622        }
623     
624      this->time_slice (dt);
625      this->update ();
626      this->localCamera->time_slice (dt);
627    }
628  this->lastFrame = currentFrame;
629}
630
631/**
632   \brief compute collision detection
633*/
634void World::collision ()
635{
636  this->collide ();
637}
638
639/**
640   \brief handle keyboard commands that are not meant for WorldEntities
641   \param cmd: the command to handle
642   \return true if the command was handled by the system or false if it may be passed to the WorldEntities
643*/
644bool World::system_command (Command* cmd)
645{
646  if( !strcmp( cmd->cmd, "quit"))
647    {
648      if( !cmd->bUp) this->bQuitOrxonox = true;
649      return true;
650    }
651  return false;
652}
653
654/**
655        \brief render the current frame
656*/
657void World::display ()
658{
659  // clear buffer
660  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
661  // set camera
662  this->localCamera->apply ();
663  // draw world
664  this->draw();
665  // draw HUD
666  // flip buffers
667  SDL_GL_SwapBuffers();
668}
669
670Camera* World::getCamera()
671{
672  return this->localCamera;
673}
674
675
676void World::spawn(WorldEntity* entity)
677{
678  Location zeroloc;
679  Location* loc = NULL;
680  WorldEntity* owner;
681
682  entities->add (entity);
683  zeroloc.dist = 0;
684  zeroloc.part = 0;
685  zeroloc.pos = Vector();
686  zeroloc.rot = Quaternion();
687  loc = &zeroloc;
688  entity->init (loc, owner);
689  if (entity->bFree)
690    {
691      this->track[loc->part].map_coords( loc, entity->get_placement());
692    }
693  entity->post_spawn ();
694}
695
696
697void World::spawn(WorldEntity* entity, Location* loc)
698{
699  Location zeroLoc;
700  WorldEntity* owner;
701  this->entities->add (entity);
702  if( loc == NULL)
703    {
704      zeroLoc.dist = 0;
705      zeroLoc.part = 0;
706      zeroLoc.pos = Vector();
707      zeroLoc.rot = Quaternion();
708      loc = &zeroLoc;
709    }
710  entity->init (loc, owner);
711  if (entity->bFree)
712    {
713      this->track[loc->part].map_coords( loc, entity->get_placement());
714    }
715  entity->post_spawn ();
716  //return entity;
717}
718
719
720void World::spawn(WorldEntity* entity, Placement* plc)
721{
722  Placement zeroPlc;
723  WorldEntity* owner;
724  if( plc == NULL)
725    {
726      zeroPlc.r = Vector();
727      zeroPlc.w = Quaternion();
728      plc = &zeroPlc;
729    }
730  this->entities->add (entity);
731  entity->init (plc, owner);
732  entity->post_spawn ();
733  //return entity;
734}
Note: See TracBrowser for help on using the repository browser.