Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/particleEngine/src/story_entities/world.cc @ 4175

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

orxonox/branches/particles: little differences

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