Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/levelLoader/src/story_entities/world.cc @ 4253

Last change on this file since 4253 was 4253, checked in by bensch, 19 years ago

orxonox/branches/levelLoader: constifization

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