Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4207 was 4176, checked in by bensch, 20 years ago

orxonox/trunk: merged the particleSystem into the Trunk

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