Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4256 was 4245, checked in by patrick, 20 years ago

orxonox/trunk: merged back the md2_loader branche manualy (a full merge was impossible).

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