Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/md2_loader/src/story_entities/world.cc @ 4215

Last change on this file since 4215 was 4215, checked in by patrick, 19 years ago

orxonox/branches/md2_model: flushing work

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