Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/openAL/src/story_entities/world.cc @ 4219

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

orxonox/branches/openAL: audio Buffers will be flushed at the End of the Level

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