Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4722 was 4722, checked in by patrick, 19 years ago

orxonox/trunk: some very small change: model runs now

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