Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the levelLoader-branche back into the trunk, because it seems to be stable.
merged with command:
svn merge -r 4230:HEAD levelLoader ../trunk
no conflicts of any interesst

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