Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/story_entities/world.cc @ 3593

Last change on this file since 3593 was 3590, checked in by bensch, 20 years ago

orxonox/trunk: updated debug.h: now possibility to log per module (compile-time)

  1. write in the cc-file at the beginnig !!BEFORE ANY INCLUDES!!

#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_[MODULENAME]
where [MODULNAME] is a name of a module that can be defined in debug.h

  1. define a new MODULE: easy just write a new one under the other ones in DEBUG.h
  1. if you do not wish special loggin everything stays as is, and you do not have to worry. (then de verbose will be set from orxonox.cc: int verbose)
File size: 17.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#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
18
19#include "world.h"
20#include "world_entity.h"
21#include "track_manager.h"
22#include "player.h"
23#include "command_node.h"
24#include "camera.h"
25#include "environment.h"
26#include "primitive.h"
27#include "p_node.h"
28#include "null_parent.h"
29#include "helper_parent.h"
30#include "glmenu_imagescreen.h"
31#include "skysphere.h"
32#include "light.h"
33#include "fontset.h"
34#include "track_node.h"
35#include "terrain.h"
36
37using namespace std;
38
39
40/**
41    \brief create a new World
42   
43    This creates a new empty world!
44*/
45World::World (char* name)
46{
47  this->init(name, -1);
48  //NullParent* np = NullParent::getInstance();
49}
50
51/**
52   \brief creates a new World...
53   \param worldID with this ID
54*/
55World::World (int worldID)
56{
57  this->init(NULL, worldID);
58}
59
60/**
61    \brief remove the World from memory
62   
63    delete everything explicitly, that isn't contained in the parenting tree!
64    things contained in the tree are deleted automaticaly
65*/
66World::~World ()
67{
68  PRINTF(3)("World::~World() - deleting current world\n");
69  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
70  cn->unbind(this->localPlayer);
71  cn->reset();
72
73  delete this->nullParent;
74  delete this->entities;
75  delete this->light;
76  delete this->trackManager;
77}
78
79/**
80   \brief initializes a new World
81*/
82void World::init(char* name, int worldID)
83{
84  this->setClassName ("World");
85
86  this->worldName = name;
87  this->debugWorldNr = worldID;
88  this->entities = new tList<WorldEntity>();
89
90  // Enable default GL stuff
91  glEnable(GL_DEPTH_TEST);
92
93}
94
95
96/**
97   \brief loads the World by initializing all resources, and set their default values.
98*/
99ErrorMessage World::load()
100{
101  //  BezierCurve* tmpCurve = new BezierCurve();
102  if(this->debugWorldNr != -1)
103    {
104      // initializing Font
105      testFont = new FontSet();
106      testFont->buildFont("../data/pictures/font.tga");
107
108      // initializing the TrackManager
109      trackManager = TrackManager::getInstance();
110      trackManager->addPoint(Vector(0,0,0));
111      trackManager->addPoint(Vector(100, -40, 5));
112      trackManager->addPoint(Vector(200,-40,-8));
113      trackManager->addPoint(Vector(250, -35, -2));
114      trackManager->addPoint(Vector(320,-33,-.55));
115      trackManager->setDuration(1);
116      trackManager->setSavePoint();
117      trackManager->addPoint(Vector(410, 0, 0));
118      trackManager->addPoint(Vector(510, 20, -10));
119      trackManager->addPoint(Vector(550, 20, -10));
120      trackManager->addPoint(Vector(570, 20, -10));
121      trackManager->setDuration(1);
122     
123      int fork11, fork12;
124      trackManager->fork(2, &fork11, &fork12);
125      trackManager->workOn(fork11);
126      trackManager->addPoint(Vector(640, 25, -30));
127      trackManager->addPoint(Vector(700, 40, -120));
128      trackManager->addPoint(Vector(800, 50, -150));
129      trackManager->addPoint(Vector(900, 60, -100));
130      trackManager->addPoint(Vector(900, 60, -70));
131      trackManager->addPoint(Vector(990, 65, -15));
132      trackManager->addPoint(Vector(1050, 65, -10));
133      trackManager->addPoint(Vector(1100, 65, -20));
134      trackManager->setDuration(4);
135
136      trackManager->workOn(fork12);
137      trackManager->addPoint(Vector(640, 25, 20));
138      trackManager->addPoint(Vector(670, 50, 120));
139      trackManager->addPoint(Vector(700, 70, 80));
140      trackManager->addPoint(Vector(800, 70, 65));
141      trackManager->addPoint(Vector(850, 65, 65));
142      trackManager->addPoint(Vector(920, 35, 40));
143      trackManager->addPoint(Vector(945, 40, 40));
144      trackManager->addPoint(Vector(970, 24, 40));
145      trackManager->addPoint(Vector(1000, 40, -7));
146      trackManager->setDuration(4);
147     
148
149      trackManager->join(2, fork11, fork12);
150
151      trackManager->workOn(5);
152      trackManager->addPoint(Vector(1200, 60, -50));
153      trackManager->addPoint(Vector(1300, 50, -50));
154      trackManager->addPoint(Vector(1400, 40, -50));
155      trackManager->addPoint(Vector(1500, 40, -60));
156      trackManager->addPoint(Vector(1600, 35, -55));
157      trackManager->addPoint(Vector(1700, 45, -40));
158      trackManager->addPoint(Vector(1750, 60, -40));
159      trackManager->addPoint(Vector(1770, 80, -40));
160      trackManager->addPoint(Vector(1800, 100, -40));
161      trackManager->setDuration(4);
162
163      trackManager->finalize();
164
165     
166      /*monitor progress*/
167      this->glmis->step();
168
169      switch(this->debugWorldNr)
170        {
171          /*
172            this loads the hard-coded debug world. this only for simplicity and will be
173            removed by a reald world-loader, which interprets a world-file.
174            if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
175            make whatever you want...
176           */
177        case DEBUG_WORLD_0:
178          {
179            this->nullParent = NullParent::getInstance ();
180            this->nullParent->setName ("NullParent");
181
182            // !\todo old track-system has to be removed
183
184            //create helper for player
185            //HelperParent* hp = new HelperParent ();
186            /* the player has to be added to this helper */
187
188            // create a player
189            this->localPlayer = new Player ();
190            this->localPlayer->setName ("player");
191            this->spawn (this->localPlayer);
192            /*monitor progress*/
193            this->glmis->step();           
194
195            // bind input
196            Orxonox *orx = Orxonox::getInstance ();
197            orx->getLocalInput()->bind (this->localPlayer);
198           
199            // bind camera
200            this->localCamera = new Camera(this);
201            this->localCamera->setName ("camera");
202            this->localCamera->bind (this->localPlayer);
203            /*monitor progress*/
204            this->glmis->step();           
205
206            // Create SkySphere
207            this->skySphere = new Skysphere("../data/pictures/sky-replace.jpg");
208            this->skySphere->setName("SkySphere");
209            this->localCamera->addChild(this->skySphere);
210            this->skySphere->setMode(PNODE_MOVEMENT);
211
212            /*monitor progress*/
213            this->glmis->step();
214
215           
216            WorldEntity* env = new Environment();
217            env->setName ("env");
218            this->spawn(env);
219
220           
221            Vector* es = new Vector (10, 5, 0);
222            Quaternion* qs = new Quaternion ();
223            WorldEntity* pr = new Primitive(PSPHERE);
224            pr->setName("primitive");
225            this->spawn(pr, this->localPlayer, es, qs, PNODE_MOVEMENT);
226           
227
228            /*monitor progress*/
229            this->glmis->step();
230
231            //      trackManager->setBindSlave(env);
232            PNode* tn = trackManager->getTrackNode();
233            tn->addChild(this->localPlayer);
234
235            //localCamera->setParent(TrackNode::getInstance());
236            tn->addChild (this->localCamera);
237            this->localPlayer->setMode(PNODE_ROTATE_AND_MOVE);
238            //Vector* cameraOffset = new Vector (0, 5, -10);
239            Vector* cameraOffset = new Vector (-10, 5, 0);
240            this->localCamera->setRelCoor (cameraOffset);
241            trackManager->condition(2, NEAREST, this->localPlayer);
242
243            break;
244          }
245        case DEBUG_WORLD_1:
246          {
247            this->nullParent = NullParent::getInstance ();
248            this->nullParent->setName ("NullParent");
249
250            // create a player
251            WorldEntity* myPlayer = new Player();
252            myPlayer->setName ("player");
253            this->spawn(myPlayer);
254            this->localPlayer = myPlayer;           
255           
256            // bind input
257            Orxonox *orx = Orxonox::getInstance();
258            orx->getLocalInput()->bind (myPlayer);
259           
260            // bind camera
261            this->localCamera = new Camera (this);
262            this->localCamera->setName ("camera");
263            this->localCamera->bind (myPlayer); 
264            this->localPlayer->addChild (this->localCamera);
265
266            // Create SkySphere
267            skySphere = new Skysphere("../data/pictures/sky-replace.jpg");
268            this->localPlayer->addChild(this->skySphere);
269
270            Vector* es = new Vector (20, 0, 0);
271            Quaternion* qs = new Quaternion ();
272            WorldEntity* pr = new Primitive(PSPHERE);
273            pr->setName("primitive");
274            this->spawn(pr, this->localPlayer, es, qs, PNODE_ROTATE_AND_MOVE);
275
276            break;
277          }
278        default:
279          printf("World::load() - no world with ID %i found", this->debugWorldNr );
280        }
281    }
282  else if(this->worldName != NULL)
283    {
284
285    }
286
287  // initialize debug coord system
288  objectList = glGenLists(1);
289  glNewList (objectList, GL_COMPILE);
290 
291  trackManager->drawGraph(.01);
292  trackManager->debug(2);
293  glEndList();
294
295  terrain = new Terrain("../data/worlds/newGround.obj");
296  terrain->setRelCoor(new Vector(0,-10,0));
297  this->spawn(terrain);
298  // LIGHT initialisation
299  light = Light::getInstance();
300  light->setAmbientColor(.1,.1,.1);
301  light->addLight();
302  light->setAttenuation(QUADRATIC, 1.0);
303  light->setAttenuation(CONSTANT, 2.0);
304  light->setAttenuation(QUADRATIC, 1.0);
305  light->setPosition(10.0, 30.0, 10.0);
306  light->setDiffuseColor(1,1,1);
307  //  light->addLight(1);
308  //  light->setPosition(20, 10, -20);
309  //  light->setDiffuseColor(0,0,0);
310  light->debug();
311
312
313}
314
315/**
316   \brief initializes a new World
317*/
318ErrorMessage World::init()
319{
320  this->bPause = false;
321  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
322  cn->addToWorld(this);
323  cn->enable(true);
324
325}
326
327
328/**
329   \brief starts the World
330*/
331ErrorMessage World::start()
332{
333  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
334  this->bQuitOrxonox = false;
335  this->bQuitCurrentGame = false;
336  this->mainLoop();
337}
338
339/**
340   \brief stops the world.
341
342   This happens, when the player decides to end the Level.
343*/
344ErrorMessage World::stop()
345{
346  PRINTF(3)("World::stop() - got stop signal\n");
347  this->bQuitCurrentGame = true;
348}
349
350/**
351   \brief pauses the Game
352*/
353ErrorMessage World::pause()
354{
355  this->isPaused = true;
356}
357
358/**
359   \brief ends the pause Phase
360*/
361ErrorMessage World::resume()
362{
363  this->isPaused = false;
364}
365
366/**
367   \brief destroys the World
368*/
369ErrorMessage World::destroy()
370{
371
372}
373
374/**
375   \brief shows the loading screen
376*/
377void World::displayLoadScreen ()
378{
379  PRINTF(3)("World::displayLoadScreen - start\n"); 
380 
381  //GLMenuImageScreen*
382  this->glmis = GLMenuImageScreen::getInstance();
383  this->glmis->init();
384  this->glmis->setMaximum(10);
385  this->glmis->draw();
386 
387  PRINTF(3)("World::displayLoadScreen - end\n"); 
388}
389
390/**
391   \brief removes the loadscreen, and changes over to the game
392
393   \todo take out the delay
394*/
395void World::releaseLoadScreen ()
396{
397  PRINTF(3)("World::releaseLoadScreen - start\n"); 
398  this->glmis->setValue(this->glmis->getMaximum());
399  SDL_Delay(500);
400  PRINTF(3)("World::releaseLoadScreen - end\n"); 
401}
402
403
404/**
405    \brief checks for collisions
406   
407    This method runs through all WorldEntities known to the world and checks for collisions
408    between them. In case of collisions the collide() method of the corresponding entities
409    is called.
410*/
411void World::collide ()
412{
413  /*
414  List *a, *b;
415  WorldEntity *aobj, *bobj;
416   
417  a = entities;
418 
419  while( a != NULL)
420    {
421      aobj = a->nextElement();
422      if( aobj->bCollide && aobj->collisioncluster != NULL)
423        {
424          b = a->nextElement();
425          while( b != NULL )
426            {
427              bobj = b->nextElement();
428              if( bobj->bCollide && bobj->collisioncluster != NULL )
429                {
430                  unsigned long ahitflg, bhitflg;
431                  if( check_collision ( &aobj->place, aobj->collisioncluster,
432                                        &ahitflg, &bobj->place, bobj->collisioncluster,
433                                        &bhitflg) );
434                  {
435                    aobj->collide (bobj, ahitflg, bhitflg);
436                    bobj->collide (aobj, bhitflg, ahitflg);
437                  }
438                }
439              b = b->nextElement();
440            }
441        }
442      a = a->enumerate();
443    }
444  */
445}
446
447/**
448    \brief runs through all entities calling their draw() methods
449*/
450void World::draw ()
451{
452  /* draw entities */
453  WorldEntity* entity;
454  glLoadIdentity();
455
456  entity = this->entities->enumerate();
457  while( entity != NULL ) 
458    { 
459      if( entity->bDraw ) entity->draw();
460      entity = this->entities->nextElement();
461    } 
462 
463  glCallList (objectList);
464  //! \todo skysphere is a WorldEntity and should be inside of the world-entity-list.
465  skySphere->draw();
466
467  testFont->printText(0, 0, 1, "orxonox_" PACKAGE_VERSION);
468
469}
470
471
472/**
473   \brief function to put your own debug stuff into it. it can display informations about
474   the current class/procedure
475*/
476void World::debug()
477{
478  PRINTF(2)("debug() - starting debug\n");
479  PNode* p1 = NullParent::getInstance ();
480  PNode* p2 = new PNode (new Vector(2, 2, 2), p1);
481  PNode* p3 = new PNode (new Vector(4, 4, 4), p1);
482  PNode* p4 = new PNode (new Vector(6, 6, 6), p2);
483
484  p1->debug ();
485  p2->debug ();
486  p3->debug ();
487  p4->debug ();
488
489  p1->shiftCoor (new Vector(-1, -1, -1));
490
491  printf("World::debug() - shift\n");
492  p1->debug ();
493  p2->debug ();
494  p3->debug ();
495  p4->debug ();
496 
497  p1->update ();
498
499  printf ("World::debug() - update\n");
500  p1->debug ();
501  p2->debug ();
502  p3->debug ();
503  p4->debug ();
504
505  p2->shiftCoor (new Vector(-1, -1, -1));
506  p1->update ();
507
508  p1->debug ();
509  p2->debug ();
510  p3->debug ();
511  p4->debug ();
512
513  p2->setAbsCoor (new Vector(1,2,3));
514
515
516 p1->update ();
517
518  p1->debug ();
519  p2->debug ();
520  p3->debug ();
521  p4->debug ();
522
523  delete p1;
524 
525 
526  /*
527  WorldEntity* entity;
528  printf("counting all entities\n");
529  printf("World::debug() - enumerate()\n");
530  entity = entities->enumerate(); 
531  while( entity != NULL )
532    {
533      if( entity->bDraw ) printf("got an entity\n");
534      entity = entities->nextElement();
535    }
536  */
537}
538
539
540/**
541  \brief main loop of the world: executing all world relevant function
542
543  in this loop we synchronize (if networked), handle input events, give the heart-beat to
544  all other member-entities of the world (tick to player, enemies etc.), checking for
545  collisions drawing everything to the screen.
546*/
547void World::mainLoop()
548{
549  this->lastFrame = SDL_GetTicks ();
550  PRINTF(3)("World::mainLoop() - Entering main loop\n");
551  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
552    {
553      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
554      // Network
555      this->synchronize ();
556      // Process input
557      this->handleInput ();
558      if( this->bQuitCurrentGame || this->bQuitOrxonox)
559          break;
560      // Process time
561      this->tick ();
562      // Update the state
563      this->update ();     
564      // Process collision
565      this->collide ();
566      // Draw
567      this->display ();
568
569      //      for( int i = 0; i < 5000000; i++) {}
570      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
571    }
572  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
573}
574
575
576/**
577   \brief synchronize local data with remote data
578*/
579void World::synchronize ()
580{
581  // Get remote input
582  // Update synchronizables
583}
584
585
586/**
587   \brief run all input processing
588
589   the command node is the central input event dispatcher. the node uses the even-queue from
590   sdl and has its own event-passing-queue.
591*/
592void World::handleInput ()
593{
594  // localinput
595  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
596  cn->process();
597  // remoteinput
598}
599
600
601/**
602   \brief advance the timeline
603
604   this calculates the time used to process one frame (with all input handling, drawing, etc)
605   the time is mesured in ms and passed to all world-entities and other classes that need
606   a heart-beat.
607*/
608void World::tick ()
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(3)("fps = %f\n", fps);
619        }
620      else
621        {
622          /* the frame-rate is limited to 100 frames per second, all other things are for
623             nothing.
624          */
625          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
626          SDL_Delay(10);
627          dt = 10;
628        }
629      //this->timeSlice (dt);
630     
631      /* function to let all entities tick (iterate through list) */
632      WorldEntity* entity;
633      float seconds = dt / 1000.0;     
634      entity = entities->enumerate(); 
635      while( entity != NULL) 
636        { 
637          entity->tick (seconds);
638          entity = entities->nextElement();
639        }
640      //skySphere->updatePosition(localCamera->absCoordinate);
641     
642      /* update tick the rest */
643      this->localCamera->tick(dt);
644      this->trackManager->tick(dt);
645    }
646  this->lastFrame = currentFrame;
647}
648
649
650/**
651   \brief this function gives the world a consistant state
652
653   after ticking (updating the world state) this will give a constistant
654   state to the whole system.
655*/
656void World::update()
657{
658  this->nullParent->update ();
659}
660
661
662/**
663   \brief render the current frame
664   
665   clear all buffers and draw the world
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  /* \todo draw HUD */
677  // flip buffers
678  SDL_GL_SwapBuffers();
679  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
680  //SDL_Flip (screen);
681}
682
683
684/**
685   \brief add and spawn a new entity to this world
686   \param entity to be added
687*/
688void World::spawn(WorldEntity* entity)
689{
690  this->entities->add (entity);
691  entity->postSpawn ();
692}
693
694
695/**
696   \brief add and spawn a new entity to this world
697   \param entity to be added
698   \param absCoor At what coordinates to add this entity.
699   \param absDir In which direction should it look.
700*/
701void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
702{
703  this->entities->add (entity);
704
705  entity->setAbsCoor (absCoor);
706  entity->setAbsDir (absDir);
707
708  entity->postSpawn ();
709}
710
711
712/**
713   \brief add and spawn a new entity to this world
714   \param entity to be added
715   \param entity to be added to (PNode)
716   \param At what relative  coordinates to add this entity.
717   \param In which relative direction should it look.
718*/
719void World::spawn(WorldEntity* entity, PNode* parentNode, 
720                  Vector* relCoor, Quaternion* relDir, 
721                  int parentingMode)
722{
723  this->nullParent = NullParent::getInstance();
724  if( parentNode != NULL)
725    {
726      parentNode->addChild (entity);
727     
728      entity->setRelCoor (relCoor);
729      entity->setRelDir (relDir);
730      entity->setMode(parentingMode);
731     
732      this->entities->add (entity);
733     
734      entity->postSpawn ();
735    }
736}
737
738
739
740/**
741  \brief commands that the world must catch
742  \returns false if not used by the world
743*/
744bool World::command(Command* cmd)
745{
746  return false;
747}
748
Note: See TracBrowser for help on using the repository browser.