Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: lights loadable

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