Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/levelLoader: minor… sleep-state

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