Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: resized the stoned stones

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