Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: flush the state

File size: 31.4 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer: Christian Meyer
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
19
20#include "world.h"
21
22#include "orxonox.h"
23
24#include "p_node.h"
25#include "null_parent.h"
26#include "helper_parent.h"
27#include "track_node.h"
28#include "world_entity.h"
29#include "player.h"
30#include "camera.h"
31#include "environment.h"
32#include "skysphere.h"
33#include "skybox.h"
34#include "satellite.h"
35#include "terrain.h"
36#include "light.h"
37#include "text_engine.h"
38
39#include "track_manager.h"
40#include "garbage_collector.h"
41#include "animation_player.h"
42#include "particle_engine.h"
43
44#include "command_node.h"
45#include "glmenu_imagescreen.h"
46#include "list.h"
47#include "game_loader.h"
48
49#include "animation3d.h"
50
51#include "substring.h"
52
53using namespace std;
54
55WorldInterface* WorldInterface::singletonRef = 0;
56
57
58/**
59   \brief private constructor because of singleton
60*/
61WorldInterface::WorldInterface()
62{
63  this->worldIsInitialized = false;
64  this->worldReference = NULL;
65}
66
67/**
68   \brief public deconstructor
69*/
70WorldInterface::~WorldInterface()
71{
72  this->singletonRef = NULL;
73  this->worldIsInitialized = false;
74  this->worldReference = NULL;
75}
76
77/**
78   \brief gets the singleton instance
79   \returns singleton instance
80*/
81WorldInterface* WorldInterface::getInstance()
82{
83  if( singletonRef == NULL)
84    singletonRef = new WorldInterface();
85  return singletonRef;
86}
87
88
89/**
90   \brief initializes the interface
91   \param reference to the world
92
93   if the worldinterface is not initilizes, there wont be any
94   useable interface
95*/
96void WorldInterface::init(World* world)
97{
98  this->worldReference = world;
99  if( world != NULL)
100    {
101      this->worldIsInitialized = true;
102      PRINTF(3)("WorldInterface up and running\n");
103    }
104}
105
106
107/**
108   \brief gets the entity list from the world
109   \return entity list
110*/
111tList<WorldEntity>* WorldInterface::getEntityList()
112{
113  if( this->worldIsInitialized)
114    return this->worldReference->getEntities();
115  PRINT(1)("Someone tried to use the WorldInterface before it has been initizlized! this can result in SEGFAULTs!\n");
116  return NULL;
117}
118
119CREATE_FACTORY(World);
120
121World::World( TiXmlElement* root)
122{
123  this->constuctorInit("", -1);
124  this->path = NULL;
125  const char *string;
126  char *name;
127  int id;
128 
129  PRINTF0("Creating a World\n");
130 
131  // identifier
132  string = grabParameter( root, "identifier");
133  if( string == NULL || sscanf(string, "%d", &id) != 1)
134    {
135      PRINTF0("World is missing a proper 'identifier'\n");
136      this->setStoryID( -1);
137    }
138  else setStoryID( id);
139
140  // next id
141  string = grabParameter( root, "nextid");
142  if( string == NULL || sscanf(string, "%d", &id) != 1)
143    {
144      PRINTF0("World is missing a proper 'nextid'\n");
145      this->setStoryID( -1);
146    }
147  else setNextStoryID( id);
148 
149
150  // path
151  string = grabParameter( root, "path");
152  if( string == NULL)
153    {
154      PRINTF0("World is missing a proper 'path'\n");
155      this->setPath( NULL);
156    }
157  else
158    {
159      name = new char[strlen(string + 2)];
160      strcpy( name, string);
161      this->setPath( name);
162    }
163}
164
165/**
166    \brief create a new World
167   
168    This creates a new empty world!
169*/
170World::World (char* name)
171{
172  this->path = NULL;
173  this->constuctorInit(name, -1);
174  //NullParent* np = NullParent::getInstance();
175}
176
177/**
178   \brief creates a new World...
179   \param worldID with this ID
180*/
181World::World (int worldID)
182{
183  this->path = NULL;
184  this->constuctorInit(NULL, worldID);
185}
186
187/**
188    \brief remove the World from memory
189   
190    delete everything explicitly, that isn't contained in the parenting tree!
191    things contained in the tree are deleted automaticaly
192*/
193World::~World ()
194{
195  PRINTF(3)("World::~World() - deleting current world\n");
196  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
197  cn->unbind(this->localPlayer);
198  cn->reset();
199
200  delete WorldInterface::getInstance();
201
202  delete this->nullParent;
203  delete this->entities;
204  delete this->lightMan;
205  delete this->trackManager;
206  delete this->particleEngine;
207  TextEngine::getInstance()->flush();
208
209  delete AnimationPlayer::getInstance(); // this should be at the end of the unloading sequence.
210  //delete garbagecollecor
211  //delete animator
212
213  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
214}
215
216/**
217   \brief initializes the world.
218
219   set all stuff here that is world generic and does not use to much memory
220   because the real init() function StoryEntity::init() will be called
221   shortly before start of the game. 
222   since all worlds are initiated/referenced before they will be started.
223   NO LEVEL LOADING HERE - NEVER!
224*/
225void World::constuctorInit(char* name, int worldID)
226{
227  this->setClassName ("World");
228
229  //this->worldName = name;
230  //this->worldName = new char[strlen(name)+1];
231  //strcpy(this->worldName, name);
232  this->debugWorldNr = worldID;
233  this->entities = new tList<WorldEntity>();
234}
235
236
237/**
238   \brief this is executed before load
239
240   since the load function sometimes needs data, that has been init before
241   the load and after the proceeding storyentity has finished
242*/
243ErrorMessage World::preLoad()
244{
245  /* init the world interface */
246  WorldInterface* wi = WorldInterface::getInstance();
247  wi->init(this);
248  this->garbageCollector = GarbageCollector::getInstance();
249
250  this->particleEngine = ParticleEngine::getInstance();
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  this->localCamera = new Camera();
259  this->localCamera->setName ("camera");
260}
261
262
263/**
264   \brief loads the World by initializing all resources, and set their default values.
265*/
266ErrorMessage World::load()
267{       
268  PRINTF(3)("> Loading world: '%s'\n", getPath());
269  TiXmlElement* element;
270  GameLoader* loader = GameLoader::getInstance();
271 
272  if( getPath() == NULL)
273    {
274      PRINTF(1)("World has no path specified for loading");
275      return (ErrorMessage){213,"Path not specified","World::load()"};
276    }
277 
278  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
279  // load the campaign document
280  if( !XMLDoc->LoadFile()) 
281  {
282    // report an error
283    PRINTF(1)("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      PRINTF(1)("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      PRINTF(2)("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  // LOADSCREEN //
320  ////////////////
321  element = root->FirstChildElement("LoadScreen");
322  if (element == NULL)
323    {
324      PRINTF(2)("no LoadScreen specified, loading default\n");
325
326      glmis->setBackgroundImage("pictures/load_screen.jpg");
327      this->glmis->setMaximum(8);
328      this->glmis->draw();
329    }
330  else
331    {
332      this->glmis->load(element);
333      this->glmis->draw();
334    }
335  this->glmis->draw();
336  // find WorldEntities
337  element = root->FirstChildElement("WorldEntities");
338 
339  if( element == NULL)
340    {
341      PRINTF(1)("World is missing 'WorldEntities'\n");
342    }
343  else
344    {
345      element = element->FirstChildElement();
346      // load Players/Objects/Whatever
347      PRINTF(4)("Loading WorldEntities\n");
348      while( element != NULL)
349        {
350          WorldEntity* created = (WorldEntity*) loader->fabricate( element);
351          if( created != NULL) this->spawn( created);
352          // if we load a 'Player' we use it as localPlayer
353          //todo do this more elegant
354          if( element->Value() != NULL && !strcmp( element->Value(), "Player")) localPlayer = (Player*) created;
355          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
356          element = element->NextSiblingElement();
357          glmis->step(); //! \todo temporary
358        }
359      PRINTF(4)("Done loading WorldEntities\n");
360    }
361 
362  // find Track
363  element = root->FirstChildElement( "Track");
364  if( element == NULL)
365    {
366      PRINTF(0)("World is missing a 'Track'\n");
367    }
368  else
369    {   
370      //load track
371      PRINTF(4)("Loading Track\n");
372
373      trackManager->load( element);
374      trackManager->finalize();
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  lightMan->setAmbientColor(.1,.1,.1);
391  lightMan->addLight();
392  //      lightMan->setAttenuation(1.0, .01, 0.0);
393  //      lightMan->setDiffuseColor(1,1,1);
394  //  lightMan->addLight(1);
395  //  lightMan->setPosition(20, 10, -20);
396  //  lightMan->setDiffuseColor(0,0,0);
397  lightMan->debug();
398  lightMan->setPosition(-5.0, 10.0, -40.0);
399 
400  //        trackManager->setBindSlave(env);
401  PNode* tn = trackManager->getTrackNode();
402  tn->addChild(this->localPlayer);
403 
404  //localCamera->setParent(TrackNode::getInstance());
405  tn->addChild(this->localCamera);
406  localCamera->lookAt(tn);
407  localCamera->setMode(PNODE_MOVEMENT);
408  this->localPlayer->setMode(PNODE_ALL);
409  Vector* cameraOffset = new Vector (0, 5, -10);
410  trackManager->condition(2, LEFTRIGHT, this->localPlayer);
411 
412  this->sky->setParent(this->localCamera);
413
414  // initialize debug coord system
415  objectList = glGenLists(1);
416  glNewList (objectList, GL_COMPILE);
417 
418  trackManager->drawGraph(.01);
419  trackManager->debug(2);
420  glEndList();
421
422  terrain = new Terrain("worlds/newGround.obj");
423  terrain->setRelCoor(Vector(0,-10,0));
424  this->spawn(terrain);
425
426
427  ParticleSystem* system = new ParticleSystem(1000, PARTICLE_SPRITE);
428  system->setLifeSpan(.5);
429  system->setConserve(.99);
430  system->setRadius(2, 0, 2, 0);
431
432  ParticleEmitter* emitter = new ParticleEmitter(Vector(-1, 0, 0), M_PI_4, 100, .05);
433  emitter->setParent(this->localPlayer);
434 
435  particleEngine->addConnection(emitter, system);
436}
437
438void World::loadDebugWorld(int worldID)
439{
440  /*monitor progress*/
441  this->glmis->step();
442  // stuff beyond this point remains to be loaded properly
443
444  // initializing the TrackManager
445  this->trackManager = TrackManager::getInstance();
446  //trackManager->addPoint(Vector(0,0,0));
447  trackManager->addPoint(Vector(150, -35, 5));
448  trackManager->addPoint(Vector(200,-35, 5));
449  trackManager->addPoint(Vector(250, -35, 5));
450  trackManager->addPoint(Vector(320,-33,-.55));
451  trackManager->setDuration(1);
452  trackManager->setSavePoint();
453
454  trackManager->addPoint(Vector(410, 0, 0));
455  trackManager->addPoint(Vector(510, 20, -10));
456  trackManager->addPoint(Vector(550, 20, -10));
457  trackManager->addPoint(Vector(570, 20, -10));
458  trackManager->setDuration(2);
459     
460  trackManager->forkS("testFork1,testFork2");
461  trackManager->workOn("testFork1");
462  trackManager->addPoint(Vector(640, 25, -30));
463  trackManager->addPoint(Vector(700, 40, -120));
464  trackManager->addPoint(Vector(800, 50, -150));
465  trackManager->addPoint(Vector(900, 60, -100));
466  trackManager->addPoint(Vector(900, 60, -70));
467  trackManager->addPoint(Vector(990, 65, -15));
468  trackManager->addPoint(Vector(1050, 65, -10));
469  trackManager->addPoint(Vector(1100, 65, -20));
470  trackManager->setDuration(4);
471
472  trackManager->workOn("testFork2");
473  trackManager->addPoint(Vector(640, 25, 20));
474  trackManager->addPoint(Vector(670, 50, 120));
475  trackManager->addPoint(Vector(700, 70, 80));
476  trackManager->addPoint(Vector(800, 70, 65));
477  trackManager->addPoint(Vector(850, 65, 65));
478  trackManager->addPoint(Vector(920, 35, 40));
479  trackManager->addPoint(Vector(945, 40, 40));
480  trackManager->addPoint(Vector(970, 24, 40));
481  trackManager->addPoint(Vector(1000, 40, -7));
482  trackManager->setDuration(4);
483     
484     
485  trackManager->joinS("testFork1,testFork2");
486       
487  trackManager->addPoint(Vector(1200, 60, -50));
488  trackManager->addPoint(Vector(1300, 50, -50));
489  trackManager->addPoint(Vector(1400, 40, -50));
490  trackManager->addPoint(Vector(1500, 40, -60));
491  trackManager->addPoint(Vector(1600, 35, -55));
492  trackManager->addPoint(Vector(1700, 45, -40));
493  trackManager->addPoint(Vector(1750, 60, -40));
494  trackManager->addPoint(Vector(1770, 80, -40));
495  trackManager->addPoint(Vector(1800, 100, -40));
496  trackManager->setDuration(10);
497 
498  trackManager->finalize();
499 
500
501  // LIGHT initialisation
502  lightMan->setAmbientColor(.1,.1,.1);
503  lightMan->addLight();
504  //      lightMan->setAttenuation(1.0, .01, 0.0);
505  //      lightMan->setDiffuseColor(1,1,1);
506  //  lightMan->addLight(1);
507  //  lightMan->setPosition(20, 10, -20);
508  //  lightMan->setDiffuseColor(0,0,0);
509  lightMan->debug();
510
511  switch(this->debugWorldNr)
512    {
513      /*
514        this loads the hard-coded debug world. this only for simplicity and will be
515        removed by a reald world-loader, which interprets a world-file.
516        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
517        make whatever you want...
518      */
519    case DEBUG_WORLD_0:
520      {
521        lightMan->setPosition(-5.0, 10.0, -40.0);
522
523        // !\todo old track-system has to be removed
524
525        //create helper for player
526        //HelperParent* hp = new HelperParent ();
527        /* the player has to be added to this helper */
528
529        // create a player
530        this->localPlayer = new Player ();
531        this->localPlayer->setName ("player");
532        this->spawn (this->localPlayer);
533        /*monitor progress*/
534        //this->glmis->step();
535        this->glmis->step();
536
537        // bind input
538        Orxonox *orx = Orxonox::getInstance ();
539        orx->getLocalInput()->bind (this->localPlayer);
540           
541        // bind camera
542        this->localCamera = new Camera();
543        this->localCamera->setName ("camera");
544           
545        /*monitor progress*/
546        this->glmis->step();
547
548        sky = new SkyBox();
549        //      (SkyBox*)(sky)->setTexture("pictures/sky/skybox", "jpg");
550        sky->setParent(localCamera);
551        this->spawn(sky);
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        sky = new Skysphere("pictures/sky-replace.jpg");
613        this->localPlayer->addChild(this->sky);
614        this->spawn(this->sky);
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->sky = new Skysphere("pictures/sky-replace.jpg");
658        this->sky->setName("SkySphere");
659        this->spawn(this->sky);
660        this->localCamera->addChild(this->sky);
661        this->sky->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 = new GLMenuImageScreen();
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  PRINTF(3)("World::releaseLoadScreen - end\n"); 
864  delete this->glmis;
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  particleEngine->draw(this->dtS); //!< \todo should be dts like in the Trunk;
955
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      this->dtS = (float)this->dt / 1000.0;     
1124      this->gameTime += this->dtS;
1125      //entity = entities->enumerate();
1126      tIterator<WorldEntity>* iterator = this->entities->getIterator();
1127      WorldEntity* entity = iterator->nextElement();
1128      while( entity != NULL) 
1129        { 
1130          entity->tick (this->dtS);
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(this->dtS);
1139
1140      AnimationPlayer::getInstance()->tick(this->dtS);
1141      particleEngine->tick(this->dtS);
1142    }
1143  this->lastFrame = currentFrame;
1144}
1145
1146
1147/**
1148   \brief this function gives the world a consistant state
1149
1150   after ticking (updating the world state) this will give a constistant
1151   state to the whole system.
1152*/
1153void World::update()
1154{
1155  this->garbageCollector->update();
1156  this->nullParent->update (this->dtS);
1157}
1158
1159
1160/**
1161   \brief render the current frame
1162   
1163   clear all buffers and draw the world
1164*/
1165void World::display ()
1166{
1167  // clear buffer
1168  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1169  // set camera
1170  this->localCamera->apply ();
1171  // draw world
1172  this->draw();
1173  // draw HUD
1174  /* \todo draw HUD */
1175  // flip buffers
1176  SDL_GL_SwapBuffers();
1177  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
1178  //SDL_Flip (screen);
1179}
1180
1181
1182/**
1183   \brief add and spawn a new entity to this world
1184   \param entity to be added
1185*/
1186void World::spawn(WorldEntity* entity)
1187{
1188  this->entities->add (entity);
1189  entity->postSpawn ();
1190}
1191
1192
1193/**
1194   \brief add and spawn a new entity to this world
1195   \param entity to be added
1196   \param absCoor At what coordinates to add this entity.
1197   \param absDir In which direction should it look.
1198*/
1199void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1200{
1201  this->entities->add (entity);
1202
1203  entity->setAbsCoor (*absCoor);
1204  entity->setAbsDir (*absDir);
1205
1206  entity->postSpawn ();
1207}
1208
1209
1210/**
1211   \brief add and spawn a new entity to this world
1212   \param entity to be added
1213   \param entity to be added to (PNode)
1214   \param At what relative  coordinates to add this entity.
1215   \param In which relative direction should it look.
1216*/
1217void World::spawn(WorldEntity* entity, PNode* parentNode, 
1218                  Vector* relCoor, Quaternion* relDir, 
1219                  int parentingMode)
1220{
1221  this->nullParent = NullParent::getInstance();
1222  if( parentNode != NULL)
1223    {
1224      parentNode->addChild (entity);
1225     
1226      entity->setRelCoor (*relCoor);
1227      entity->setRelDir (*relDir);
1228      entity->setMode(parentingMode);
1229     
1230      this->entities->add (entity);
1231     
1232      entity->postSpawn ();
1233    }
1234}
1235
1236
1237
1238/**
1239  \brief commands that the world must catch
1240  \returns false if not used by the world
1241*/
1242bool World::command(Command* cmd)
1243{
1244  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1245  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1246  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1247  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1248  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1249  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1250
1251  return false;
1252}
1253
1254void World::setPath( const char* name)
1255{
1256  if (this->path)
1257    delete this->path;
1258  if (ResourceManager::isFile(name))
1259  {
1260    this->path = new char[strlen(name)+1];
1261    strcpy(this->path, name);
1262  }
1263  else
1264    {
1265      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1266      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1267    }
1268}
1269
1270const char* World::getPath( void)
1271{
1272  return path;
1273}
Note: See TracBrowser for help on using the repository browser.