Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: derivation of superclasses is more clear now. lets see, if this will hold out for some time (about 115 classes long)

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