Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/md2_loader: now the model gets displayed at the first track fork location - no texture until now. doesn't look that bad… actualy looks quite good :))

File size: 31.9 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->setDuration(10);
448
449      trackManager->finalize();
450
451     
452  lightMan->setAmbientColor(.1,.1,.1);
453  lightMan->addLight();
454  //      lightMan->setAttenuation(1.0, .01, 0.0);
455  //      lightMan->setDiffuseColor(1,1,1);
456  //  lightMan->addLight(1);
457  //  lightMan->setPosition(20, 10, -20);
458  //  lightMan->setDiffuseColor(0,0,0);
459  //lightMan->debug();
460  lightMan->setPosition(-5.0, 10.0, -40.0);
461 
462  //        trackManager->setBindSlave(env);
463  PNode* tn = trackManager->getTrackNode();
464  tn->addChild(this->localPlayer);
465 
466  //localCamera->setParent(TrackNode::getInstance());
467  tn->addChild(this->localCamera);
468  localCamera->lookAt(tn);
469  localCamera->setMode(PNODE_MOVEMENT);
470  this->localPlayer->setMode(PNODE_ALL);
471  Vector* cameraOffset = new Vector (0, 5, -10);
472  trackManager->condition(2, LEFTRIGHT, this->localPlayer);
473 
474  this->sky->setParent(this->localCamera);
475
476  // initialize debug coord system
477  objectList = glGenLists(1);
478  glNewList (objectList, GL_COMPILE);
479 
480  //trackManager->drawGraph(.01);
481  //trackManager->debug(2);
482  glEndList();
483
484  terrain = new Terrain("worlds/newGround.obj");
485  terrain->setRelCoor(Vector(0,-10,0));
486  this->spawn(terrain);
487
488  WorldEntity* testEntity = new TestEntity();
489  testEntity->setRelCoor(Vector(570, 10, -15));
490  testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
491  this->spawn(testEntity);
492  //this->localPlayer->addChild(testEntity);
493
494}
495
496
497void World::loadDebugWorld(int worldID)
498{
499  /*monitor progress*/
500  this->glmis->step();
501
502  // LIGHT initialisation
503
504  lightMan->setAmbientColor(.1,.1,.1);
505  lightMan->addLight();
506  //      lightMan->setAttenuation(1.0, .01, 0.0);
507  //      lightMan->setDiffuseColor(1,1,1);
508  //  lightMan->addLight(1);
509  //  lightMan->setPosition(20, 10, -20);
510  //  lightMan->setDiffuseColor(0,0,0);
511  lightMan->debug();
512
513  switch(this->debugWorldNr)
514    {
515      /*
516        this loads the hard-coded debug world. this only for simplicity and will be
517        removed by a reald world-loader, which interprets a world-file.
518        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
519        make whatever you want...
520      */
521    case DEBUG_WORLD_0:
522      {
523        lightMan->setPosition(-5.0, 10.0, -40.0);
524
525        // !\todo old track-system has to be removed
526
527        //create helper for player
528        //HelperParent* hp = new HelperParent ();
529        /* the player has to be added to this helper */
530
531        // create a player
532        this->localPlayer = new Player ();
533        this->localPlayer->setName ("player");
534        this->spawn (this->localPlayer);
535        /*monitor progress*/
536        //this->glmis->step();
537        this->glmis->step();
538
539        // bind input
540        Orxonox *orx = Orxonox::getInstance ();
541        orx->getLocalInput()->bind (this->localPlayer);
542           
543        // bind camera
544        this->localCamera = new Camera();
545        this->localCamera->setName ("camera");
546           
547        /*monitor progress*/
548        this->glmis->step();
549
550        sky = new SkyBox();
551        //      (SkyBox*)(sky)->setTexture("pictures/sky/skybox", "jpg");
552        sky->setParent(localCamera);
553        this->spawn(sky);
554
555        /*monitor progress*/
556        this->glmis->step();
557
558           
559        WorldEntity* env = new Environment();
560        env->setName ("env");
561        this->spawn(env);
562
563           
564        /*
565          Vector* es = new Vector (10, 5, 0);
566          Quaternion* qs = new Quaternion ();
567          WorldEntity* pr = new Primitive(P_CYLINDER);
568          pr->setName("primitive");
569          this->spawn(pr, this->localPlayer, es, qs, PNODE_MOVEMENT);
570        */
571
572        /*monitor progress*/
573        this->glmis->step();
574
575        //          trackManager->setBindSlave(env);
576        PNode* tn = trackManager->getTrackNode();
577        tn->addChild(this->localPlayer);
578        this->localCamera->lookAt(tn);
579
580        //localCamera->setParent(TrackNode::getInstance());
581        tn->addChild(this->localCamera);
582        //          localCamera->lookAt(tn);
583        this->localPlayer->setMode(PNODE_ALL);
584        //Vector* cameraOffset = new Vector (0, 5, -10);
585        trackManager->condition(2, LEFTRIGHT, this->localPlayer);
586        this->glmis->step();
587        break;
588      }
589    case DEBUG_WORLD_1:
590      {
591        lightMan->setPosition(.0, .0, .0);
592        lightMan->setAttenuation(1.0, .01, 0.0);
593        lightMan->setSpecularColor(1,0,0);
594        this->nullParent = NullParent::getInstance ();
595        this->nullParent->setName ("NullParent");
596
597        // create a player
598        WorldEntity* myPlayer = new Player();
599        myPlayer->setName ("player");
600        this->spawn(myPlayer);
601        this->localPlayer = myPlayer;       
602           
603        // bind input
604        Orxonox *orx = Orxonox::getInstance();
605        orx->getLocalInput()->bind (myPlayer);
606           
607        // bind camera
608        this->localCamera = new Camera ();
609        this->localCamera->setName ("camera");
610        this->localCamera->lookAt(LightManager::getInstance()->getLight(0));
611        this->localCamera->setParent(this->localPlayer);
612
613        // Create SkySphere
614        sky = new Skysphere("pictures/sky-replace.jpg");
615        this->localPlayer->addChild(this->sky);
616        this->spawn(this->sky);
617        Vector* es = new Vector (20, 0, 0);
618        Quaternion* qs = new Quaternion ();
619
620        lightMan->getLight(0)->setParent(trackManager->getTrackNode());
621        break;
622      }
623    case DEBUG_WORLD_2:
624      {
625        lightMan->setAmbientColor(.1,.1,.1);
626        lightMan->addLight();
627        lightMan->setPosition(-5.0, 10.0, -40.0);
628        this->nullParent = NullParent::getInstance ();
629        this->nullParent->setName ("NullParent");
630
631        // !\todo old track-system has to be removed
632
633        //create helper for player
634        //HelperParent* hp = new HelperParent ();
635        /* the player has to be added to this helper */
636
637        // create a player
638        this->localPlayer = new Player ();
639        this->localPlayer->setName ("player");
640        this->spawn (this->localPlayer);
641        /*monitor progress*/
642        //this->glmis->step();     
643        this->glmis->step();
644
645        // bind input
646        Orxonox *orx = Orxonox::getInstance ();
647        orx->getLocalInput()->bind (this->localPlayer);
648           
649        // bind camera
650        this->localCamera = new Camera();
651        this->localCamera->setName ("camera");
652        this->localCamera->lookAt(this->localPlayer);
653        this->localCamera->setParent(this->localPlayer);
654           
655        /*monitor progress*/
656        this->glmis->step();
657
658        // Create SkySphere
659        this->sky = new Skysphere("pictures/sky-replace.jpg");
660        this->sky->setName("SkySphere");
661        this->spawn(this->sky);
662        this->localCamera->addChild(this->sky);
663        this->sky->setMode(PNODE_MOVEMENT);
664        /*monitor progress*/
665        this->glmis->step();
666
667
668        WorldEntity* baseNode = new Satellite(Vector(1,0,1), 1.2);
669        this->localPlayer->addChild(baseNode);
670        baseNode->setRelCoor(Vector(10.0, 2.0, 1.0));
671        this->spawn(baseNode);
672
673        WorldEntity* secondNode = new Satellite(Vector(0,0,1), 2.0);
674        baseNode->addChild(secondNode);
675        secondNode->setRelCoor(Vector(0.0, 0.0, 3.0));
676        this->spawn(secondNode);
677
678
679        WorldEntity* thirdNode = new Satellite(Vector(0,0,1), 1.0);
680        secondNode->addChild(thirdNode);
681        thirdNode->setRelCoor(Vector(2.0, 0.0, 0.0));
682        this->spawn(thirdNode);
683
684           
685   
686        WorldEntity* c = new Environment();
687        this->localPlayer->addChild(c);
688        c->setRelCoor(Vector(10.0, 2.0, -1.0));
689        this->spawn(c);
690
691
692           
693        Animation3D* animation = new Animation3D(c);
694        animation->setInfinity(ANIM_INF_REPLAY);
695
696
697        animation->addKeyFrame(Vector(0, 0, 0), Quaternion(0, Vector(0,1,0)), 1.0, ANIM_NEG_EXP, ANIM_LINEAR); 
698        animation->addKeyFrame(Vector(0, 2, 0), Quaternion(M_PI, Vector(0,1,0)), 1.0, ANIM_NEG_EXP, ANIM_LINEAR); 
699        animation->addKeyFrame(Vector(0, 0, 0), Quaternion(0, Vector(0,1,0)), 1.0, ANIM_NEG_EXP, ANIM_LINEAR); 
700
701
702
703
704
705
706        /*         
707          KeyFrame* f1 = new KeyFrame;
708          f1->position = new Vector(-1.1, 0.0, 2.6);
709          f1->direction = new Quaternion();
710          f1->time = 1.0;
711          f1->mode = NEG_EXP;
712                 
713                 
714          KeyFrame* f2 = new KeyFrame;
715          f2->position = new Vector(-2.1, 0.0, 2.6);
716          f2->direction = new Quaternion();
717          f2->time = 0.1;
718          f2->mode = NEG_EXP;
719                 
720          KeyFrame* f3 = new KeyFrame;
721          f3->position = new Vector(10.0, 2.0, -1.0);
722          f3->direction = new Quaternion();
723          f3->time = 0.2;
724          f3->mode = NEG_EXP;
725                 
726          KeyFrame* f4 = new KeyFrame;
727          f4->position = new Vector(10.0, 5.0, -1.0);
728          f4->direction = new Quaternion();
729          f4->time = 1.0;
730          f4->mode = NEG_EXP;
731                 
732                 
733                 
734          this->simpleAnimation->animatorBegin();
735          this->simpleAnimation->selectObject(b);
736          this->simpleAnimation->setAnimationMode(SINGLE);
737          this->simpleAnimation->addKeyFrame(f1);
738          this->simpleAnimation->addKeyFrame(f2);
739          this->simpleAnimation->start();
740          this->simpleAnimation->selectObject(c);
741          this->simpleAnimation->addKeyFrame(f3);
742          this->simpleAnimation->addKeyFrame(f4);
743          this->simpleAnimation->start();
744          this->simpleAnimation->animatorEnd();
745        */
746
747        /*
748          Vector* es = new Vector (10, 5, 0);
749          Quaternion* qs = new Quaternion ();
750          WorldEntity* pr = new Primitive(P_CYLINDER);
751          pr->setName("primitive");
752          this->spawn(pr, this->localPlayer, es, qs, PNODE_MOVEMENT);
753        */
754
755        /*monitor progress*/
756        this->glmis->step();
757
758        //          trackManager->setBindSlave(env);
759        PNode* tn = trackManager->getTrackNode();
760        tn->addChild(this->localPlayer);
761
762        //localCamera->setParent(TrackNode::getInstance());
763        tn->addChild(this->localCamera);
764        //          localCamera->lookAt(tn);
765        this->localPlayer->setMode(PNODE_ALL);
766        //Vector* cameraOffset = new Vector (0, 5, -10);
767        trackManager->condition(2, LEFTRIGHT, this->localPlayer);
768        this->glmis->step();
769
770        break;
771      }
772    default:
773      printf("World::load() - no world with ID %i found", this->debugWorldNr );
774    }
775}
776
777
778
779/**
780   \brief initializes a new World shortly before start
781
782   this is the function, that will be loaded shortly before the world is
783   started
784*/
785ErrorMessage World::init()
786{
787  this->bPause = false;
788  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
789  cn->addToWorld(this);
790  cn->enable(true);
791}
792
793
794/**
795   \brief starts the World
796*/
797ErrorMessage World::start()
798{
799  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
800  this->bQuitOrxonox = false;
801  this->bQuitCurrentGame = false;
802  this->mainLoop();
803}
804
805/**
806   \brief stops the world.
807
808   This happens, when the player decides to end the Level.
809*/
810ErrorMessage World::stop()
811{
812  PRINTF(3)("World::stop() - got stop signal\n");
813  this->bQuitCurrentGame = true;
814}
815
816/**
817   \brief pauses the Game
818*/
819ErrorMessage World::pause()
820{
821  this->isPaused = true;
822}
823
824/**
825   \brief ends the pause Phase
826*/
827ErrorMessage World::resume()
828{
829  this->isPaused = false;
830}
831
832/**
833   \brief destroys the World
834*/
835ErrorMessage World::destroy()
836{
837
838}
839
840/**
841   \brief shows the loading screen
842*/
843void World::displayLoadScreen ()
844{
845  PRINTF(3)("World::displayLoadScreen - start\n"); 
846 
847  //GLMenuImageScreen*
848  this->glmis = new GLMenuImageScreen();
849  this->glmis->init();
850  this->glmis->setMaximum(8);
851  //  this->glmis->draw();
852 
853  PRINTF(3)("World::displayLoadScreen - end\n"); 
854}
855
856/**
857   \brief removes the loadscreen, and changes over to the game
858
859   \todo take out the delay
860*/
861void World::releaseLoadScreen ()
862{
863  PRINTF(3)("World::releaseLoadScreen - start\n"); 
864  this->glmis->setValue(this->glmis->getMaximum());
865  PRINTF(3)("World::releaseLoadScreen - end\n"); 
866  delete this->glmis;
867}
868
869
870/**
871   \brief gets the list of entities from the world
872   \returns entity list
873*/
874tList<WorldEntity>* World::getEntities()
875{
876  return this->entities;
877}
878
879
880/**
881   \brief this returns the current game time
882   \returns elapsed game time
883*/
884double World::getGameTime()
885{
886  return this->gameTime;
887}
888
889
890/**
891    \brief checks for collisions
892   
893    This method runs through all WorldEntities known to the world and checks for collisions
894    between them. In case of collisions the collide() method of the corresponding entities
895    is called.
896*/
897void World::collide ()
898{
899  /*
900  List *a, *b;
901  WorldEntity *aobj, *bobj;
902   
903  a = entities;
904 
905  while( a != NULL)
906    {
907      aobj = a->nextElement();
908      if( aobj->bCollide && aobj->collisioncluster != NULL)
909        {
910          b = a->nextElement();
911          while( b != NULL )
912            {
913              bobj = b->nextElement();
914              if( bobj->bCollide && bobj->collisioncluster != NULL )
915                {
916                  unsigned long ahitflg, bhitflg;
917                  if( check_collision ( &aobj->place, aobj->collisioncluster,
918                                        &ahitflg, &bobj->place, bobj->collisioncluster,
919                                        &bhitflg) );
920                  {
921                    aobj->collide (bobj, ahitflg, bhitflg);
922                    bobj->collide (aobj, bhitflg, ahitflg);
923                  }
924                }
925              b = b->nextElement();
926            }
927        }
928      a = a->enumerate();
929    }
930  */
931}
932
933/**
934    \brief runs through all entities calling their draw() methods
935*/
936void World::draw ()
937{
938  /* draw entities */
939  WorldEntity* entity;
940  glLoadIdentity();
941
942  //entity = this->entities->enumerate();
943  tIterator<WorldEntity>* iterator = this->entities->getIterator();
944  entity = iterator->nextElement();
945  while( entity != NULL ) 
946    { 
947      if( entity->bDraw ) entity->draw();
948      //entity = this->entities->nextElement();
949      entity = iterator->nextElement();
950    }
951  delete iterator;
952 
953  glCallList (objectList);
954
955  TextEngine::getInstance()->draw();
956  lightMan->draw(); // must be at the end of the drawing procedure, otherwise Light cannot be handled as PNodes //
957}
958
959
960/**
961   \brief function to put your own debug stuff into it. it can display informations about
962   the current class/procedure
963*/
964void World::debug()
965{
966  PRINTF(2)("debug() - starting debug\n");
967  PNode* p1 = NullParent::getInstance ();
968  PNode* p2 = new PNode (Vector(2, 2, 2), p1);
969  PNode* p3 = new PNode (Vector(4, 4, 4), p1);
970  PNode* p4 = new PNode (Vector(6, 6, 6), p2);
971
972  p1->debug ();
973  p2->debug ();
974  p3->debug ();
975  p4->debug ();
976
977  p1->shiftCoor (Vector(-1, -1, -1));
978
979  printf("World::debug() - shift\n");
980  p1->debug ();
981  p2->debug ();
982  p3->debug ();
983  p4->debug ();
984 
985  p1->update (0);
986
987  printf ("World::debug() - update\n");
988  p1->debug ();
989  p2->debug ();
990  p3->debug ();
991  p4->debug ();
992
993  p2->shiftCoor (Vector(-1, -1, -1));
994  p1->update (0);
995
996  p1->debug ();
997  p2->debug ();
998  p3->debug ();
999  p4->debug ();
1000
1001  p2->setAbsCoor (Vector(1,2,3));
1002
1003
1004 p1->update (0);
1005
1006  p1->debug ();
1007  p2->debug ();
1008  p3->debug ();
1009  p4->debug ();
1010
1011  delete p1;
1012 
1013 
1014  /*
1015  WorldEntity* entity;
1016  printf("counting all entities\n");
1017  printf("World::debug() - enumerate()\n");
1018  entity = entities->enumerate(); 
1019  while( entity != NULL )
1020    {
1021      if( entity->bDraw ) printf("got an entity\n");
1022      entity = entities->nextElement();
1023    }
1024  */
1025}
1026
1027
1028/**
1029  \brief main loop of the world: executing all world relevant function
1030
1031  in this loop we synchronize (if networked), handle input events, give the heart-beat to
1032  all other member-entities of the world (tick to player, enemies etc.), checking for
1033  collisions drawing everything to the screen.
1034*/
1035void World::mainLoop()
1036{
1037  this->lastFrame = SDL_GetTicks ();
1038  PRINTF(3)("World::mainLoop() - Entering main loop\n");
1039  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
1040    {
1041      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
1042      // Network
1043      this->synchronize ();
1044      // Process input
1045      this->handleInput ();
1046      if( this->bQuitCurrentGame || this->bQuitOrxonox)
1047          break;
1048      // Process time
1049      this->tick ();
1050      // Update the state
1051      this->update ();     
1052      // Process collision
1053      this->collide ();
1054      // Draw
1055      this->display ();
1056
1057      //      for( int i = 0; i < 5000000; i++) {}
1058      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
1059    }
1060  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
1061}
1062
1063
1064/**
1065   \brief synchronize local data with remote data
1066*/
1067void World::synchronize ()
1068{
1069  // Get remote input
1070  // Update synchronizables
1071}
1072
1073
1074/**
1075   \brief run all input processing
1076
1077   the command node is the central input event dispatcher. the node uses the even-queue from
1078   sdl and has its own event-passing-queue.
1079*/
1080void World::handleInput ()
1081{
1082  // localinput
1083  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
1084  cn->process();
1085  // remoteinput
1086}
1087
1088
1089/**
1090   \brief advance the timeline
1091
1092   this calculates the time used to process one frame (with all input handling, drawing, etc)
1093   the time is mesured in ms and passed to all world-entities and other classes that need
1094   a heart-beat.
1095*/
1096void World::tick ()
1097{
1098  Uint32 currentFrame = SDL_GetTicks();
1099  if(!this->bPause)
1100    {
1101      this->dt = currentFrame - this->lastFrame;
1102     
1103      if( this->dt > 0)
1104        {
1105          float fps = 1000/dt;
1106
1107          // temporary, only for showing how fast the text-engine is
1108          char tmpChar[20];
1109          sprintf(tmpChar, "fps: %4.0f", fps);
1110        }
1111      else
1112        {
1113          /* the frame-rate is limited to 100 frames per second, all other things are for
1114             nothing.
1115          */
1116          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
1117          SDL_Delay(10);
1118          this->dt = 10;
1119        }
1120      //this->timeSlice (dt);
1121     
1122      /* function to let all entities tick (iterate through list) */
1123      float seconds = this->dt / 1000.0;     
1124      this->gameTime += seconds;
1125      //entity = entities->enumerate();
1126      tIterator<WorldEntity>* iterator = this->entities->getIterator();
1127      WorldEntity* entity = iterator->nextElement();
1128      while( entity != NULL) 
1129        { 
1130          entity->tick (seconds);
1131          entity = iterator->nextElement();
1132        }
1133      delete iterator;
1134
1135      /* update tick the rest */
1136      this->trackManager->tick(this->dt);
1137      this->localCamera->tick(this->dt);
1138      this->garbageCollector->tick(seconds);
1139         
1140          /* actualy the Graphics Engine should tick the world not the other way around...
1141                 but since we like the things not too complicated we got it this way around
1142                 until there is need or time to do it the other way around.
1143                 \todo: GraphicsEngine ticks world: separation of processes and data...
1144          */
1145      GraphicsEngine::getInstance()->tick(seconds);
1146          AnimationPlayer::getInstance()->tick(seconds);
1147    }
1148  this->lastFrame = currentFrame;
1149}
1150
1151
1152/**
1153   \brief this function gives the world a consistant state
1154
1155   after ticking (updating the world state) this will give a constistant
1156   state to the whole system.
1157*/
1158void World::update()
1159{
1160  this->garbageCollector->update();
1161  this->nullParent->update (dt);
1162}
1163
1164
1165/**
1166   \brief render the current frame
1167   
1168   clear all buffers and draw the world
1169*/
1170void World::display ()
1171{
1172  // clear buffer
1173  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1174  // set camera
1175  this->localCamera->apply ();
1176  // draw world
1177  this->draw();
1178  // draw HUD
1179  /* \todo draw HUD */
1180  // flip buffers
1181  SDL_GL_SwapBuffers();
1182  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
1183  //SDL_Flip (screen);
1184}
1185
1186
1187/**
1188   \brief add and spawn a new entity to this world
1189   \param entity to be added
1190*/
1191void World::spawn(WorldEntity* entity)
1192{
1193  this->entities->add (entity);
1194  entity->postSpawn ();
1195}
1196
1197
1198/**
1199   \brief add and spawn a new entity to this world
1200   \param entity to be added
1201   \param absCoor At what coordinates to add this entity.
1202   \param absDir In which direction should it look.
1203*/
1204void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1205{
1206  this->entities->add (entity);
1207
1208  entity->setAbsCoor (*absCoor);
1209  entity->setAbsDir (*absDir);
1210
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 entity to be added to (PNode)
1219   \param At what relative  coordinates to add this entity.
1220   \param In which relative direction should it look.
1221*/
1222void World::spawn(WorldEntity* entity, PNode* parentNode, 
1223                  Vector* relCoor, Quaternion* relDir, 
1224                  int parentingMode)
1225{
1226  this->nullParent = NullParent::getInstance();
1227  if( parentNode != NULL)
1228    {
1229      parentNode->addChild (entity);
1230     
1231      entity->setRelCoor (*relCoor);
1232      entity->setRelDir (*relDir);
1233      entity->setMode(parentingMode);
1234     
1235      this->entities->add (entity);
1236     
1237      entity->postSpawn ();
1238    }
1239}
1240
1241
1242
1243/**
1244  \brief commands that the world must catch
1245  \returns false if not used by the world
1246*/
1247bool World::command(Command* cmd)
1248{
1249  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1250  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1251  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1252  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1253  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1254  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1255
1256  return false;
1257}
1258
1259void World::setPath( const char* name)
1260{
1261  if (this->path)
1262    delete this->path;
1263  if (ResourceManager::isFile(name))
1264  {
1265    this->path = new char[strlen(name)+1];
1266    strcpy(this->path, name);
1267  }
1268  else
1269    {
1270      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1271      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1272    }
1273}
1274
1275const char* World::getPath( void)
1276{
1277  return path;
1278}
Note: See TracBrowser for help on using the repository browser.