Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the levelloader from lltrunktemp to the trunk. Big thanks to fuzzy to make this so easy for us, and for implementing it in the first place.

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