Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: added a ParticleSystem to the vulcano…. one does not see anything yet…. but most probaply in 4 hours :)

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