Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4307 was 4287, checked in by patrick, 20 years ago

orxonox/trunk: implemented the objectmanager debug functon, some small fixed in the ol code

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