Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: TrackManager prepared for loading. added new overloaded functions that read in join and fork from one single string
thanks to chris, this was pretty easy… the hard part was finding the substring class :)

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