Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/md2_loader/src/story_entities/world.cc @ 4066

Last change on this file since 4066 was 4066, checked in by patrick, 19 years ago

orxonox/branches/md2_loader: now it displays the fps, will do this better an look for a good font.

File size: 30.9 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer: Christian Meyer
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
19
20#include "world.h"
21
22#include "orxonox.h"
23
24#include "p_node.h"
25#include "null_parent.h"
26#include "helper_parent.h"
27#include "track_node.h"
28#include "world_entity.h"
29#include "player.h"
30#include "camera.h"
31#include "environment.h"
32#include "skysphere.h"
33#include "skybox.h"
34#include "satellite.h"
35#include "terrain.h"
36#include "light.h"
37#include "text_engine.h"
38
39#include "track_manager.h"
40#include "garbage_collector.h"
41#include "animation_player.h"
42#include "graphics_engine.h"
43
44#include "command_node.h"
45#include "glmenu_imagescreen.h"
46#include "list.h"
47#include "game_loader.h"
48
49#include "animation3d.h"
50
51#include "substring.h"
52
53using namespace std;
54
55WorldInterface* WorldInterface::singletonRef = 0;
56
57
58/**
59   \brief private constructor because of singleton
60*/
61WorldInterface::WorldInterface()
62{
63  this->worldIsInitialized = false;
64  this->worldReference = NULL;
65}
66
67/**
68   \brief public deconstructor
69*/
70WorldInterface::~WorldInterface()
71{
72  this->singletonRef = NULL;
73  this->worldIsInitialized = false;
74  this->worldReference = NULL;
75}
76
77/**
78   \brief gets the singleton instance
79   \returns singleton instance
80*/
81WorldInterface* WorldInterface::getInstance()
82{
83  if( singletonRef == NULL)
84    singletonRef = new WorldInterface();
85  return singletonRef;
86}
87
88
89/**
90   \brief initializes the interface
91   \param reference to the world
92
93   if the worldinterface is not initilizes, there wont be any
94   useable interface
95*/
96void WorldInterface::init(World* world)
97{
98  this->worldReference = world;
99  if( world != NULL)
100    {
101      this->worldIsInitialized = true;
102      PRINTF(3)("WorldInterface up and running\n");
103    }
104}
105
106
107/**
108   \brief gets the entity list from the world
109   \return entity list
110*/
111tList<WorldEntity>* WorldInterface::getEntityList()
112{
113  if( this->worldIsInitialized)
114    return this->worldReference->getEntities();
115  PRINT(1)("Someone tried to use the WorldInterface before it has been initizlized! this can result in SEGFAULTs!\n");
116  return NULL;
117}
118
119CREATE_FACTORY(World);
120
121World::World( TiXmlElement* root)
122{
123  this->constuctorInit("", -1);
124
125  const char *string;
126  char *name;
127  int id;
128 
129  PRINTF0("Creating a World\n");
130 
131  // identifier
132  string = grabParameter( root, "identifier");
133  if( string == NULL || sscanf(string, "%d", &id) != 1)
134    {
135      PRINTF0("World is missing a proper 'identifier'\n");
136      this->setStoryID( -1);
137    }
138  else setStoryID( id);
139
140  // next id
141  string = grabParameter( root, "nextid");
142  if( string == NULL || sscanf(string, "%d", &id) != 1)
143    {
144      PRINTF0("World is missing a proper 'nextid'\n");
145      this->setStoryID( -1);
146    }
147  else setNextStoryID( id);
148 
149
150  // path
151  string = grabParameter( root, "path");
152  if( string == NULL)
153    {
154      PRINTF0("World is missing a proper 'path'\n");
155      this->setPath( NULL);
156    }
157  else
158    {
159      name = new char[strlen(string + 2)];
160      strcpy( name, string);
161      this->setPath( name);
162    }
163}
164
165/**
166    \brief create a new World
167   
168    This creates a new empty world!
169*/
170World::World (char* name)
171{
172  this->constuctorInit(name, -1);
173  //NullParent* np = NullParent::getInstance();
174}
175
176/**
177   \brief creates a new World...
178   \param worldID with this ID
179*/
180World::World (int worldID)
181{
182  this->constuctorInit(NULL, worldID);
183}
184
185/**
186    \brief remove the World from memory
187   
188    delete everything explicitly, that isn't contained in the parenting tree!
189    things contained in the tree are deleted automaticaly
190*/
191World::~World ()
192{
193  PRINTF(3)("World::~World() - deleting current world\n");
194  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
195  cn->unbind(this->localPlayer);
196  cn->reset();
197
198  ResourceManager::getInstance()->debug();
199  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
200  ResourceManager::getInstance()->debug();
201
202  delete WorldInterface::getInstance();
203
204  delete this->nullParent;
205  delete this->entities;
206  delete this->lightMan;
207  delete this->trackManager;
208  TextEngine::getInstance()->flush();
209
210  AnimationPlayer::getInstance()->debug();
211  delete AnimationPlayer::getInstance(); // this should be at the end of the unloading sequence.
212  //delete garbagecollecor
213  //delete animator
214
215
216}
217
218/**
219   \brief initializes the world.
220
221   set all stuff here that is world generic and does not use to much memory
222   because the real init() function StoryEntity::init() will be called
223   shortly before start of the game. 
224   since all worlds are initiated/referenced before they will be started.
225   NO LEVEL LOADING HERE - NEVER!
226*/
227void World::constuctorInit(char* name, int worldID)
228{
229  this->setClassName ("World");
230
231  //this->worldName = name;
232  //this->worldName = new char[strlen(name)+1];
233  //strcpy(this->worldName, name);
234  this->debugWorldNr = worldID;
235  this->entities = new tList<WorldEntity>();
236}
237
238
239/**
240   \brief this is executed before load
241
242   since the load function sometimes needs data, that has been init before
243   the load and after the proceeding storyentity has finished
244*/
245ErrorMessage World::preLoad()
246{
247  /* init the world interface */
248  WorldInterface* wi = WorldInterface::getInstance();
249  wi->init(this);
250  this->garbageCollector = GarbageCollector::getInstance();
251
252  this->trackManager = TrackManager::getInstance();
253  this->lightMan = LightManager::getInstance();
254  this->nullParent = NullParent::getInstance ();
255  this->nullParent->setName ("NullParent");
256
257  AnimationPlayer::getInstance(); // initializes the animationPlayer
258
259  this->localCamera = new Camera();
260  this->localCamera->setName ("camera");
261 
262  GraphicsEngine::getInstance()->displayFPS(true);
263}
264
265
266/**
267   \brief loads the World by initializing all resources, and set their default values.
268*/
269ErrorMessage World::load()
270{       
271  PRINTF0("> Loading world: '%s'\n", getPath());
272 
273  GameLoader* loader = GameLoader::getInstance();
274 
275  if( getPath() == NULL)
276    {
277      PRINTF0("World has no path specified for loading");
278      return (ErrorMessage){213,"Path not specified","World::load()"};
279    }
280 
281  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
282  // load the campaign document
283  if( !XMLDoc->LoadFile())
284    //this->glmis->step();
285 
286  {
287    // report an error
288    PRINTF0("Error loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
289    delete XMLDoc;
290    return (ErrorMessage){213,"XML File parsing error","World::load()"};
291  }
292 
293  // check basic validity
294  TiXmlElement* root = XMLDoc->RootElement();
295  assert( root != NULL);
296 
297  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
298    {
299      // report an error
300      PRINTF0("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
301      delete XMLDoc;
302      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
303    }
304 
305  // load the parameters
306  // name
307  char* temp;
308  const char* string = grabParameter( root, "name");
309  if( string == NULL)
310    {
311      PRINTF0("World is missing a proper 'name'\n");
312      string = "Unknown";
313      temp = new char[strlen(string + 2)];
314      strcpy( temp, string);
315      this->worldName = temp;
316    }
317  else
318    {
319      temp = new char[strlen(string + 2)];
320      strcpy( temp, string);
321      this->worldName = temp;
322    }
323 
324 
325  // find WorldEntities
326  TiXmlElement* element = root->FirstChildElement( "WorldEntities");
327 
328  if( element == NULL)
329    {
330      PRINTF0("World is missing 'WorldEntities'\n");
331    }
332  else
333    {
334      element = element->FirstChildElement();
335      // load Players/Objects/Whatever
336      PRINTF0("Loading WorldEntities\n");
337      while( element != NULL)
338        {
339          WorldEntity* created = (WorldEntity*) loader->fabricate( element);
340          if( created != NULL) this->spawn( created);
341          // if we load a 'Player' we use it as localPlayer
342          //todo do this more elegant
343          if( element->Value() != NULL && !strcmp( element->Value(), "Player")) localPlayer = (Player*) created;
344          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
345          element = element->NextSiblingElement();
346        }
347      PRINTF0("Done loading WorldEntities\n");
348    }
349 
350  // find Track
351  /*element = root->FirstChildElement( "Track");
352  if( element == NULL)
353    {
354      PRINTF0("============>>>>>>>>>>>>>>>>>World is missing a 'Track'\n");
355    }
356  else
357    {   
358      //load track
359      PRINTF0("============>>>>>>>>>>>>>>>>Loading Track\n");
360
361      trackManager->loadTrack( element);
362      trackManager->finalize();
363      PRINTF0("============>>>>>>>>>>>>>>>>Done loading Track\n");
364    }*/
365 
366  // free the XML data
367
368  delete XMLDoc;
369  /* GENERIC LOADING PROCESS FINISHED */
370 
371  // bind input
372  Orxonox *orx = Orxonox::getInstance ();
373  orx->getLocalInput()->bind (localPlayer);
374 
375  // bind camera
376  //this->localCamera->bind (localPlayer);
377  this->localPlayer->addChild (this->localCamera);
378 
379 
380  // stuff beyond this point remains to be loaded properly
381 
382      // initializing the TrackManager
383  this->trackManager = TrackManager::getInstance();
384      //trackManager->addPoint(Vector(0,0,0));
385      trackManager->addPoint(Vector(150, -35, 5));
386      trackManager->addPoint(Vector(200,-35, 5));
387      trackManager->addPoint(Vector(250, -35, 5));
388      trackManager->addPoint(Vector(320,-33,-.55));
389      trackManager->setDuration(2);
390      trackManager->setSavePoint();
391
392      trackManager->addPoint(Vector(410, 0, 0));
393      trackManager->addPoint(Vector(510, 20, -10));
394      trackManager->addPoint(Vector(550, 20, -10));
395      trackManager->addPoint(Vector(570, 20, -10));
396      trackManager->setDuration(5);
397     
398      int fork11, fork12;
399      trackManager->fork(2, &fork11, &fork12);
400      trackManager->workOn(fork11);
401      trackManager->addPoint(Vector(640, 25, -30));
402      trackManager->addPoint(Vector(700, 40, -120));
403      trackManager->addPoint(Vector(800, 50, -150));
404      trackManager->addPoint(Vector(900, 60, -100));
405      trackManager->addPoint(Vector(900, 60, -70));
406      trackManager->addPoint(Vector(990, 65, -15));
407      trackManager->addPoint(Vector(1050, 65, -10));
408      trackManager->addPoint(Vector(1100, 65, -20));
409      trackManager->setDuration(10);
410
411      trackManager->workOn(fork12);
412      trackManager->addPoint(Vector(640, 25, 20));
413      trackManager->addPoint(Vector(670, 50, 120));
414      trackManager->addPoint(Vector(700, 70, 80));
415      trackManager->addPoint(Vector(800, 70, 65));
416      trackManager->addPoint(Vector(850, 65, 65));
417      trackManager->addPoint(Vector(920, 35, 40));
418      trackManager->addPoint(Vector(945, 40, 40));
419      trackManager->addPoint(Vector(970, 24, 40));
420      trackManager->addPoint(Vector(1000, 40, -7));
421      trackManager->setDuration(10);
422     
423
424      trackManager->join(2, fork11, fork12);
425
426      trackManager->workOn(5);
427      trackManager->addPoint(Vector(1200, 60, -50));
428      trackManager->addPoint(Vector(1300, 50, -50));
429      trackManager->addPoint(Vector(1400, 40, -50));
430      trackManager->addPoint(Vector(1500, 40, -60));
431      trackManager->addPoint(Vector(1600, 35, -55));
432      trackManager->addPoint(Vector(1700, 45, -40));
433      trackManager->addPoint(Vector(1750, 60, -40));
434      trackManager->addPoint(Vector(1770, 80, -40));
435      trackManager->addPoint(Vector(1800, 100, -40));
436      trackManager->setDuration(10);
437
438      trackManager->finalize();
439
440     
441  lightMan->setAmbientColor(.1,.1,.1);
442  lightMan->addLight();
443  //      lightMan->setAttenuation(1.0, .01, 0.0);
444  //      lightMan->setDiffuseColor(1,1,1);
445  //  lightMan->addLight(1);
446  //  lightMan->setPosition(20, 10, -20);
447  //  lightMan->setDiffuseColor(0,0,0);
448  lightMan->debug();
449  lightMan->setPosition(-5.0, 10.0, -40.0);
450 
451  //        trackManager->setBindSlave(env);
452  PNode* tn = trackManager->getTrackNode();
453  tn->addChild(this->localPlayer);
454 
455  //localCamera->setParent(TrackNode::getInstance());
456  tn->addChild(this->localCamera);
457  localCamera->lookAt(tn);
458  this->localPlayer->setMode(PNODE_ALL);
459  Vector* cameraOffset = new Vector (0, 5, -10);
460  trackManager->condition(2, LEFTRIGHT, this->localPlayer);
461 
462  this->sky->setParent(this->localCamera);
463
464  // initialize debug coord system
465  objectList = glGenLists(1);
466  glNewList (objectList, GL_COMPILE);
467 
468  //  trackManager->drawGraph(.01);
469  trackManager->debug(2);
470  glEndList();
471
472  terrain = new Terrain("../data/worlds/newGround.obj");
473  terrain->setRelCoor(Vector(0,-10,0));
474  this->spawn(terrain);
475
476}
477
478void World::loadDebugWorld(int worldID)
479{
480  /*monitor progress*/
481  this->glmis->step();
482
483  // LIGHT initialisation
484
485  lightMan->setAmbientColor(.1,.1,.1);
486  lightMan->addLight();
487  //      lightMan->setAttenuation(1.0, .01, 0.0);
488  //      lightMan->setDiffuseColor(1,1,1);
489  //  lightMan->addLight(1);
490  //  lightMan->setPosition(20, 10, -20);
491  //  lightMan->setDiffuseColor(0,0,0);
492  lightMan->debug();
493
494  switch(this->debugWorldNr)
495    {
496      /*
497        this loads the hard-coded debug world. this only for simplicity and will be
498        removed by a reald world-loader, which interprets a world-file.
499        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
500        make whatever you want...
501      */
502    case DEBUG_WORLD_0:
503      {
504        lightMan->setPosition(-5.0, 10.0, -40.0);
505
506        // !\todo old track-system has to be removed
507
508        //create helper for player
509        //HelperParent* hp = new HelperParent ();
510        /* the player has to be added to this helper */
511
512        // create a player
513        this->localPlayer = new Player ();
514        this->localPlayer->setName ("player");
515        this->spawn (this->localPlayer);
516        /*monitor progress*/
517        //this->glmis->step();
518        this->glmis->step();
519
520        // bind input
521        Orxonox *orx = Orxonox::getInstance ();
522        orx->getLocalInput()->bind (this->localPlayer);
523           
524        // bind camera
525        this->localCamera = new Camera();
526        this->localCamera->setName ("camera");
527           
528        /*monitor progress*/
529        this->glmis->step();
530
531        sky = new SkyBox();
532        //      (SkyBox*)(sky)->setTexture("pictures/sky/skybox", "jpg");
533        sky->setParent(localCamera);
534        this->spawn(sky);
535
536        /*monitor progress*/
537        this->glmis->step();
538
539           
540        WorldEntity* env = new Environment();
541        env->setName ("env");
542        this->spawn(env);
543
544           
545        /*
546          Vector* es = new Vector (10, 5, 0);
547          Quaternion* qs = new Quaternion ();
548          WorldEntity* pr = new Primitive(P_CYLINDER);
549          pr->setName("primitive");
550          this->spawn(pr, this->localPlayer, es, qs, PNODE_MOVEMENT);
551        */
552
553        /*monitor progress*/
554        this->glmis->step();
555
556        //          trackManager->setBindSlave(env);
557        PNode* tn = trackManager->getTrackNode();
558        tn->addChild(this->localPlayer);
559        this->localCamera->lookAt(tn);
560
561        //localCamera->setParent(TrackNode::getInstance());
562        tn->addChild(this->localCamera);
563        //          localCamera->lookAt(tn);
564        this->localPlayer->setMode(PNODE_ALL);
565        //Vector* cameraOffset = new Vector (0, 5, -10);
566        trackManager->condition(2, LEFTRIGHT, this->localPlayer);
567        this->glmis->step();
568        break;
569      }
570    case DEBUG_WORLD_1:
571      {
572        lightMan->setPosition(.0, .0, .0);
573        lightMan->setAttenuation(1.0, .01, 0.0);
574        lightMan->setSpecularColor(1,0,0);
575        this->nullParent = NullParent::getInstance ();
576        this->nullParent->setName ("NullParent");
577
578        // create a player
579        WorldEntity* myPlayer = new Player();
580        myPlayer->setName ("player");
581        this->spawn(myPlayer);
582        this->localPlayer = myPlayer;       
583           
584        // bind input
585        Orxonox *orx = Orxonox::getInstance();
586        orx->getLocalInput()->bind (myPlayer);
587           
588        // bind camera
589        this->localCamera = new Camera ();
590        this->localCamera->setName ("camera");
591        this->localCamera->lookAt(LightManager::getInstance()->getLight(0));
592        this->localCamera->setParent(this->localPlayer);
593
594        // Create SkySphere
595        sky = new Skysphere("../data/pictures/sky-replace.jpg");
596        this->localPlayer->addChild(this->sky);
597        this->spawn(this->sky);
598        Vector* es = new Vector (20, 0, 0);
599        Quaternion* qs = new Quaternion ();
600
601        lightMan->getLight(0)->setParent(trackManager->getTrackNode());
602        break;
603      }
604    case DEBUG_WORLD_2:
605      {
606        lightMan->setAmbientColor(.1,.1,.1);
607        lightMan->addLight();
608        lightMan->setPosition(-5.0, 10.0, -40.0);
609        this->nullParent = NullParent::getInstance ();
610        this->nullParent->setName ("NullParent");
611
612        // !\todo old track-system has to be removed
613
614        //create helper for player
615        //HelperParent* hp = new HelperParent ();
616        /* the player has to be added to this helper */
617
618        // create a player
619        this->localPlayer = new Player ();
620        this->localPlayer->setName ("player");
621        this->spawn (this->localPlayer);
622        /*monitor progress*/
623        //this->glmis->step();     
624        this->glmis->step();
625
626        // bind input
627        Orxonox *orx = Orxonox::getInstance ();
628        orx->getLocalInput()->bind (this->localPlayer);
629           
630        // bind camera
631        this->localCamera = new Camera();
632        this->localCamera->setName ("camera");
633        this->localCamera->lookAt(this->localPlayer);
634        this->localCamera->setParent(this->localPlayer);
635           
636        /*monitor progress*/
637        this->glmis->step();
638
639        // Create SkySphere
640        this->sky = new Skysphere("../data/pictures/sky-replace.jpg");
641        this->sky->setName("SkySphere");
642        this->spawn(this->sky);
643        this->localCamera->addChild(this->sky);
644        this->sky->setMode(PNODE_MOVEMENT);
645        /*monitor progress*/
646        this->glmis->step();
647
648
649        WorldEntity* baseNode = new Satellite(Vector(1,0,1), 1.2);
650        this->localPlayer->addChild(baseNode);
651        baseNode->setRelCoor(Vector(10.0, 2.0, 1.0));
652        this->spawn(baseNode);
653
654        WorldEntity* secondNode = new Satellite(Vector(0,0,1), 2.0);
655        baseNode->addChild(secondNode);
656        secondNode->setRelCoor(Vector(0.0, 0.0, 3.0));
657        this->spawn(secondNode);
658
659
660        WorldEntity* thirdNode = new Satellite(Vector(0,0,1), 1.0);
661        secondNode->addChild(thirdNode);
662        thirdNode->setRelCoor(Vector(2.0, 0.0, 0.0));
663        this->spawn(thirdNode);
664
665           
666   
667        WorldEntity* c = new Environment();
668        this->localPlayer->addChild(c);
669        c->setRelCoor(Vector(10.0, 2.0, -1.0));
670        this->spawn(c);
671
672
673           
674        Animation3D* animation = new Animation3D(c);
675        animation->setInfinity(ANIM_INF_REPLAY);
676
677
678        animation->addKeyFrame(Vector(0, 0, 0), Quaternion(0, Vector(0,1,0)), 1.0, ANIM_NEG_EXP, ANIM_LINEAR); 
679        animation->addKeyFrame(Vector(0, 2, 0), Quaternion(M_PI, Vector(0,1,0)), 1.0, ANIM_NEG_EXP, ANIM_LINEAR); 
680        animation->addKeyFrame(Vector(0, 0, 0), Quaternion(0, Vector(0,1,0)), 1.0, ANIM_NEG_EXP, ANIM_LINEAR); 
681
682
683
684
685
686
687        /*         
688          KeyFrame* f1 = new KeyFrame;
689          f1->position = new Vector(-1.1, 0.0, 2.6);
690          f1->direction = new Quaternion();
691          f1->time = 1.0;
692          f1->mode = NEG_EXP;
693                 
694                 
695          KeyFrame* f2 = new KeyFrame;
696          f2->position = new Vector(-2.1, 0.0, 2.6);
697          f2->direction = new Quaternion();
698          f2->time = 0.1;
699          f2->mode = NEG_EXP;
700                 
701          KeyFrame* f3 = new KeyFrame;
702          f3->position = new Vector(10.0, 2.0, -1.0);
703          f3->direction = new Quaternion();
704          f3->time = 0.2;
705          f3->mode = NEG_EXP;
706                 
707          KeyFrame* f4 = new KeyFrame;
708          f4->position = new Vector(10.0, 5.0, -1.0);
709          f4->direction = new Quaternion();
710          f4->time = 1.0;
711          f4->mode = NEG_EXP;
712                 
713                 
714                 
715          this->simpleAnimation->animatorBegin();
716          this->simpleAnimation->selectObject(b);
717          this->simpleAnimation->setAnimationMode(SINGLE);
718          this->simpleAnimation->addKeyFrame(f1);
719          this->simpleAnimation->addKeyFrame(f2);
720          this->simpleAnimation->start();
721          this->simpleAnimation->selectObject(c);
722          this->simpleAnimation->addKeyFrame(f3);
723          this->simpleAnimation->addKeyFrame(f4);
724          this->simpleAnimation->start();
725          this->simpleAnimation->animatorEnd();
726        */
727
728        /*
729          Vector* es = new Vector (10, 5, 0);
730          Quaternion* qs = new Quaternion ();
731          WorldEntity* pr = new Primitive(P_CYLINDER);
732          pr->setName("primitive");
733          this->spawn(pr, this->localPlayer, es, qs, PNODE_MOVEMENT);
734        */
735
736        /*monitor progress*/
737        this->glmis->step();
738
739        //          trackManager->setBindSlave(env);
740        PNode* tn = trackManager->getTrackNode();
741        tn->addChild(this->localPlayer);
742
743        //localCamera->setParent(TrackNode::getInstance());
744        tn->addChild(this->localCamera);
745        //          localCamera->lookAt(tn);
746        this->localPlayer->setMode(PNODE_ALL);
747        //Vector* cameraOffset = new Vector (0, 5, -10);
748        trackManager->condition(2, LEFTRIGHT, this->localPlayer);
749        this->glmis->step();
750
751        break;
752      }
753    default:
754      printf("World::load() - no world with ID %i found", this->debugWorldNr );
755    }
756}
757
758
759
760/**
761   \brief initializes a new World shortly before start
762
763   this is the function, that will be loaded shortly before the world is
764   started
765*/
766ErrorMessage World::init()
767{
768  this->bPause = false;
769  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
770  cn->addToWorld(this);
771  cn->enable(true);
772}
773
774
775/**
776   \brief starts the World
777*/
778ErrorMessage World::start()
779{
780  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
781  this->bQuitOrxonox = false;
782  this->bQuitCurrentGame = false;
783  this->mainLoop();
784}
785
786/**
787   \brief stops the world.
788
789   This happens, when the player decides to end the Level.
790*/
791ErrorMessage World::stop()
792{
793  PRINTF(3)("World::stop() - got stop signal\n");
794  this->bQuitCurrentGame = true;
795}
796
797/**
798   \brief pauses the Game
799*/
800ErrorMessage World::pause()
801{
802  this->isPaused = true;
803}
804
805/**
806   \brief ends the pause Phase
807*/
808ErrorMessage World::resume()
809{
810  this->isPaused = false;
811}
812
813/**
814   \brief destroys the World
815*/
816ErrorMessage World::destroy()
817{
818
819}
820
821/**
822   \brief shows the loading screen
823*/
824void World::displayLoadScreen ()
825{
826  PRINTF(3)("World::displayLoadScreen - start\n"); 
827 
828  //GLMenuImageScreen*
829  this->glmis = GLMenuImageScreen::getInstance();
830  this->glmis->init();
831  this->glmis->setMaximum(8);
832  this->glmis->draw();
833 
834  PRINTF(3)("World::displayLoadScreen - end\n"); 
835}
836
837/**
838   \brief removes the loadscreen, and changes over to the game
839
840   \todo take out the delay
841*/
842void World::releaseLoadScreen ()
843{
844  PRINTF(3)("World::releaseLoadScreen - start\n"); 
845  this->glmis->setValue(this->glmis->getMaximum());
846  //SDL_Delay(500);
847  PRINTF(3)("World::releaseLoadScreen - end\n"); 
848}
849
850
851/**
852   \brief gets the list of entities from the world
853   \returns entity list
854*/
855tList<WorldEntity>* World::getEntities()
856{
857  return this->entities;
858}
859
860
861/**
862   \brief this returns the current game time
863   \returns elapsed game time
864*/
865double World::getGameTime()
866{
867  return this->gameTime;
868}
869
870
871/**
872    \brief checks for collisions
873   
874    This method runs through all WorldEntities known to the world and checks for collisions
875    between them. In case of collisions the collide() method of the corresponding entities
876    is called.
877*/
878void World::collide ()
879{
880  /*
881  List *a, *b;
882  WorldEntity *aobj, *bobj;
883   
884  a = entities;
885 
886  while( a != NULL)
887    {
888      aobj = a->nextElement();
889      if( aobj->bCollide && aobj->collisioncluster != NULL)
890        {
891          b = a->nextElement();
892          while( b != NULL )
893            {
894              bobj = b->nextElement();
895              if( bobj->bCollide && bobj->collisioncluster != NULL )
896                {
897                  unsigned long ahitflg, bhitflg;
898                  if( check_collision ( &aobj->place, aobj->collisioncluster,
899                                        &ahitflg, &bobj->place, bobj->collisioncluster,
900                                        &bhitflg) );
901                  {
902                    aobj->collide (bobj, ahitflg, bhitflg);
903                    bobj->collide (aobj, bhitflg, ahitflg);
904                  }
905                }
906              b = b->nextElement();
907            }
908        }
909      a = a->enumerate();
910    }
911  */
912}
913
914/**
915    \brief runs through all entities calling their draw() methods
916*/
917void World::draw ()
918{
919  /* draw entities */
920  WorldEntity* entity;
921  glLoadIdentity();
922
923  //entity = this->entities->enumerate();
924  tIterator<WorldEntity>* iterator = this->entities->getIterator();
925  entity = iterator->nextElement();
926  while( entity != NULL ) 
927    { 
928      if( entity->bDraw ) entity->draw();
929      //entity = this->entities->nextElement();
930      entity = iterator->nextElement();
931    }
932  delete iterator;
933 
934  glCallList (objectList);
935
936  TextEngine::getInstance()->draw();
937  lightMan->draw(); // must be at the end of the drawing procedure, otherwise Light cannot be handled as PNodes //
938}
939
940
941/**
942   \brief function to put your own debug stuff into it. it can display informations about
943   the current class/procedure
944*/
945void World::debug()
946{
947  PRINTF(2)("debug() - starting debug\n");
948  PNode* p1 = NullParent::getInstance ();
949  PNode* p2 = new PNode (Vector(2, 2, 2), p1);
950  PNode* p3 = new PNode (Vector(4, 4, 4), p1);
951  PNode* p4 = new PNode (Vector(6, 6, 6), p2);
952
953  p1->debug ();
954  p2->debug ();
955  p3->debug ();
956  p4->debug ();
957
958  p1->shiftCoor (Vector(-1, -1, -1));
959
960  printf("World::debug() - shift\n");
961  p1->debug ();
962  p2->debug ();
963  p3->debug ();
964  p4->debug ();
965 
966  p1->update (0);
967
968  printf ("World::debug() - update\n");
969  p1->debug ();
970  p2->debug ();
971  p3->debug ();
972  p4->debug ();
973
974  p2->shiftCoor (Vector(-1, -1, -1));
975  p1->update (0);
976
977  p1->debug ();
978  p2->debug ();
979  p3->debug ();
980  p4->debug ();
981
982  p2->setAbsCoor (Vector(1,2,3));
983
984
985 p1->update (0);
986
987  p1->debug ();
988  p2->debug ();
989  p3->debug ();
990  p4->debug ();
991
992  delete p1;
993 
994 
995  /*
996  WorldEntity* entity;
997  printf("counting all entities\n");
998  printf("World::debug() - enumerate()\n");
999  entity = entities->enumerate(); 
1000  while( entity != NULL )
1001    {
1002      if( entity->bDraw ) printf("got an entity\n");
1003      entity = entities->nextElement();
1004    }
1005  */
1006}
1007
1008
1009/**
1010  \brief main loop of the world: executing all world relevant function
1011
1012  in this loop we synchronize (if networked), handle input events, give the heart-beat to
1013  all other member-entities of the world (tick to player, enemies etc.), checking for
1014  collisions drawing everything to the screen.
1015*/
1016void World::mainLoop()
1017{
1018  this->lastFrame = SDL_GetTicks ();
1019  PRINTF(3)("World::mainLoop() - Entering main loop\n");
1020  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
1021    {
1022      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
1023      // Network
1024      this->synchronize ();
1025      // Process input
1026      this->handleInput ();
1027      if( this->bQuitCurrentGame || this->bQuitOrxonox)
1028          break;
1029      // Process time
1030      this->tick ();
1031      // Update the state
1032      this->update ();     
1033      // Process collision
1034      this->collide ();
1035      // Draw
1036      this->display ();
1037
1038      //      for( int i = 0; i < 5000000; i++) {}
1039      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
1040    }
1041  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
1042}
1043
1044
1045/**
1046   \brief synchronize local data with remote data
1047*/
1048void World::synchronize ()
1049{
1050  // Get remote input
1051  // Update synchronizables
1052}
1053
1054
1055/**
1056   \brief run all input processing
1057
1058   the command node is the central input event dispatcher. the node uses the even-queue from
1059   sdl and has its own event-passing-queue.
1060*/
1061void World::handleInput ()
1062{
1063  // localinput
1064  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
1065  cn->process();
1066  // remoteinput
1067}
1068
1069
1070/**
1071   \brief advance the timeline
1072
1073   this calculates the time used to process one frame (with all input handling, drawing, etc)
1074   the time is mesured in ms and passed to all world-entities and other classes that need
1075   a heart-beat.
1076*/
1077void World::tick ()
1078{
1079  Uint32 currentFrame = SDL_GetTicks();
1080  if(!this->bPause)
1081    {
1082      this->dt = currentFrame - this->lastFrame;
1083     
1084      if( this->dt > 0)
1085        {
1086          float fps = 1000/dt;
1087
1088          // temporary, only for showing how fast the text-engine is
1089          char tmpChar[20];
1090          sprintf(tmpChar, "fps: %4.0f", fps);
1091        }
1092      else
1093        {
1094          /* the frame-rate is limited to 100 frames per second, all other things are for
1095             nothing.
1096          */
1097          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
1098          SDL_Delay(10);
1099          this->dt = 10;
1100        }
1101      //this->timeSlice (dt);
1102     
1103      /* function to let all entities tick (iterate through list) */
1104      float seconds = this->dt / 1000.0;     
1105      this->gameTime += seconds;
1106      //entity = entities->enumerate();
1107      tIterator<WorldEntity>* iterator = this->entities->getIterator();
1108      WorldEntity* entity = iterator->nextElement();
1109      while( entity != NULL) 
1110        { 
1111          entity->tick (seconds);
1112          entity = iterator->nextElement();
1113        }
1114      delete iterator;
1115
1116      /* update tick the rest */
1117      this->trackManager->tick(this->dt);
1118      this->localCamera->tick(this->dt);
1119      this->garbageCollector->tick(seconds);
1120         
1121          /* actualy the Graphics Engine should tick the world not the other way around...
1122                 but since we like the things not too complicated we got it this way around
1123                 until there is need or time to do it the other way around.
1124                 \todo: GraphicsEngine ticks world: separation of processes and data...
1125          */
1126      GraphicsEngine::getInstance()->tick(seconds);
1127          AnimationPlayer::getInstance()->tick(seconds);
1128    }
1129  this->lastFrame = currentFrame;
1130}
1131
1132
1133/**
1134   \brief this function gives the world a consistant state
1135
1136   after ticking (updating the world state) this will give a constistant
1137   state to the whole system.
1138*/
1139void World::update()
1140{
1141  this->garbageCollector->update();
1142  this->nullParent->update (dt);
1143}
1144
1145
1146/**
1147   \brief render the current frame
1148   
1149   clear all buffers and draw the world
1150*/
1151void World::display ()
1152{
1153  // clear buffer
1154  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1155  // set camera
1156  this->localCamera->apply ();
1157  // draw world
1158  this->draw();
1159  // draw HUD
1160  /* \todo draw HUD */
1161  // flip buffers
1162  SDL_GL_SwapBuffers();
1163  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
1164  //SDL_Flip (screen);
1165}
1166
1167
1168/**
1169   \brief add and spawn a new entity to this world
1170   \param entity to be added
1171*/
1172void World::spawn(WorldEntity* entity)
1173{
1174  this->entities->add (entity);
1175  entity->postSpawn ();
1176}
1177
1178
1179/**
1180   \brief add and spawn a new entity to this world
1181   \param entity to be added
1182   \param absCoor At what coordinates to add this entity.
1183   \param absDir In which direction should it look.
1184*/
1185void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1186{
1187  this->entities->add (entity);
1188
1189  entity->setAbsCoor (*absCoor);
1190  entity->setAbsDir (*absDir);
1191
1192  entity->postSpawn ();
1193}
1194
1195
1196/**
1197   \brief add and spawn a new entity to this world
1198   \param entity to be added
1199   \param entity to be added to (PNode)
1200   \param At what relative  coordinates to add this entity.
1201   \param In which relative direction should it look.
1202*/
1203void World::spawn(WorldEntity* entity, PNode* parentNode, 
1204                  Vector* relCoor, Quaternion* relDir, 
1205                  int parentingMode)
1206{
1207  this->nullParent = NullParent::getInstance();
1208  if( parentNode != NULL)
1209    {
1210      parentNode->addChild (entity);
1211     
1212      entity->setRelCoor (*relCoor);
1213      entity->setRelDir (*relDir);
1214      entity->setMode(parentingMode);
1215     
1216      this->entities->add (entity);
1217     
1218      entity->postSpawn ();
1219    }
1220}
1221
1222
1223
1224/**
1225  \brief commands that the world must catch
1226  \returns false if not used by the world
1227*/
1228bool World::command(Command* cmd)
1229{
1230  if( !strcmp( cmd->cmd, "view0")) this->localCamera->setViewMode(VIEW_NORMAL);
1231  else if( !strcmp( cmd->cmd, "view1")) this->localCamera->setViewMode(VIEW_BEHIND);
1232  else if( !strcmp( cmd->cmd, "view2")) this->localCamera->setViewMode(VIEW_FRONT);
1233  else if( !strcmp( cmd->cmd, "view3")) this->localCamera->setViewMode(VIEW_LEFT);
1234  else if( !strcmp( cmd->cmd, "view4")) this->localCamera->setViewMode(VIEW_RIGHT);
1235  else if( !strcmp( cmd->cmd, "view5")) this->localCamera->setViewMode(VIEW_TOP);
1236
1237  return false;
1238}
1239
1240void World::setPath( const char* name)
1241{
1242  this->path = new char[strlen(name)+1];
1243  strcpy(this->path, name);
1244}
1245
1246const char* World::getPath( void)
1247{
1248  return path;
1249}
Note: See TracBrowser for help on using the repository browser.