Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/levelLoader: factory not in stdincl anymore

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