Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4161 was 4145, checked in by bensch, 20 years ago

orxonox/trunk: every world-entity saves the speed of its own

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