Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: multiple new Reparenting modes in PNode.
Testing the stuff in GuidedMissile
Projectile has a PNode as reference not as pointer
some minor weapon changes

File size: 21.7 KB
RevLine 
[4555]1/*
[1853]2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
[1855]10
11   ### File Specific:
12   main-programmer: Patrick Boenzli
[2190]13   co-programmer: Christian Meyer
[5390]14   co-programmer: Benjamin Grauer
[1853]15*/
16
[3590]17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
18
[2190]19#include "world.h"
[3608]20
[5205]21#include "shell_command.h"
[3620]22
[4347]23#include "state.h"
24
[3608]25#include "p_node.h"
26#include "null_parent.h"
[4326]27#include "pilot_node.h"
[2190]28#include "world_entity.h"
[2036]29#include "player.h"
[2190]30#include "camera.h"
[2816]31#include "environment.h"
[3419]32#include "skysphere.h"
[3803]33#include "skybox.h"
[3750]34#include "satellite.h"
[4245]35#include "test_entity.h"
[3608]36#include "terrain.h"
[3436]37#include "light.h"
[4726]38#include "load_param.h"
[5174]39#include "shell.h"
[3620]40
[3646]41#include "garbage_collector.h"
[4940]42#include "fast_factory.h"
[3812]43#include "animation_player.h"
[4176]44#include "particle_engine.h"
[4245]45#include "graphics_engine.h"
[4338]46#include "physics_engine.h"
[4396]47#include "fields.h"
[3646]48
[4488]49#include "md2Model.h"
50
[3608]51#include "glmenu_imagescreen.h"
52#include "list.h"
[4010]53#include "game_loader.h"
[2036]54
[3964]55#include "animation3d.h"
[3608]56
[4010]57#include "substring.h"
[3608]58
[4261]59#include "factory.h"
[4245]60
[5556]61#include "weapons/projectile.h"
[4405]62#include "event_handler.h"
[4504]63#include "sound_engine.h"
[4961]64#include "ogg_player.h"
[4504]65
[4747]66#include "class_list.h"
67
[4917]68#include "cd_engine.h"
[5750]69#include "npcs/npc_test1.h"
[5318]70#include "shader.h"
[4820]71
[5915]72#include "playable.h"
[5996]73#include "network_manager.h"
74#include "playable.h"
[5915]75
[5996]76
[5205]77SHELL_COMMAND(speed, World, setSpeed);
[5389]78SHELL_COMMAND(togglePNodeVisibility, World, togglePNodeVisibility);
[5429]79SHELL_COMMAND(toggleBVVisibility, World, toggleBVVisibility);
[5205]80
[1856]81using namespace std;
[1853]82
[4978]83//! This creates a Factory to fabricate a World
[5750]84CREATE_FACTORY(World, CL_WORLD);
[3620]85
[4261]86World::World(const TiXmlElement* root)
[4010]87{
88  this->constuctorInit("", -1);
[4094]89  this->path = NULL;
[4555]90
[4261]91  this->loadParams(root);
[4010]92}
93
[4555]94/**
[4836]95  *  create a new World
[4555]96
[2551]97    This creates a new empty world!
[1858]98*/
[4978]99World::World (const char* name)
[1855]100{
[4094]101  this->path = NULL;
[4010]102  this->constuctorInit(name, -1);
[1855]103}
104
[3449]105/**
[4836]106 *  creates a new World...
107 * @param worldID with this ID
[3449]108*/
[2636]109World::World (int worldID)
110{
[4094]111  this->path = NULL;
[4010]112  this->constuctorInit(NULL, worldID);
[2636]113}
114
[4555]115/**
[4838]116 *  remove the World from memory
[4555]117
[3365]118    delete everything explicitly, that isn't contained in the parenting tree!
119    things contained in the tree are deleted automaticaly
[4838]120 */
[2190]121World::~World ()
[1872]122{
[5206]123  delete this->shell;
[3546]124  PRINTF(3)("World::~World() - deleting current world\n");
[3677]125
[5915]126
[4978]127  // here everything that is alocated by the World is deleted
[4837]128  delete this->entities;
[4830]129  State::setWorldEntityList(NULL);
130
[5915]131  delete this->localPlayer;
[5115]132
[5296]133  // delete all the initialized Engines.
[5447]134  FastFactory::flushAll(true);
[4735]135  delete LightManager::getInstance();
[4822]136  delete ParticleEngine::getInstance();
[5296]137  delete AnimationPlayer::getInstance();
[4978]138  delete PhysicsEngine::getInstance();
[4822]139
[4978]140  // external engines initialized by the orxonox-class get deleted
[4504]141  SoundEngine::getInstance()->flushAllBuffers();
[4830]142  SoundEngine::getInstance()->flushAllSources();
[4504]143
[5115]144
[4978]145  // erease everything that is left.
[4870]146  delete NullParent::getInstance();
[5915]147
[6054]148  //secondary cleanup of PNodes;
149  const std::list<BaseObject*>* nodeList = ClassList::getList(CL_PARENT_NODE);
150  if (nodeList != NULL)
151    while (!nodeList->empty())
152      delete nodeList->front();
153
[5318]154  Shader::suspendShader();
[4872]155
[4978]156  // unload the resources !!
[4136]157  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
[5218]158
159  delete[] this->path;
[1872]160}
[1858]161
[3526]162/**
[4978]163 * initializes the world.
164 * @param name the name of the world
165 * @param worldID the ID of this world
166 *
167 * set all stuff here that is world generic and does not use to much memory
168 * because the real init() function StoryEntity::init() will be called
169 * shortly before start of the game.
170 * since all worlds are initiated/referenced before they will be started.
171 * NO LEVEL LOADING HERE - NEVER!
[3526]172*/
[4978]173void World::constuctorInit(const char* name, int worldID)
[3526]174{
[4320]175  this->setClassID(CL_WORLD, "World");
[2636]176
[4978]177  this->setName(name);
[3526]178  this->debugWorldNr = worldID;
[5211]179  this->gameTime = 0.0f;
[5205]180  this->setSpeed(1.0);
[4961]181  this->music = NULL;
[5211]182  this->shell = NULL;
183  this->entities = NULL;
[5915]184  this->localPlayer = NULL;
185  this->localCamera = NULL;
[5389]186
187  this->showPNodes = false;
[5429]188  this->showBV = false;
[3629]189}
[3526]190
[4978]191/**
192 * loads the parameters of a World from an XML-element
193 * @param root the XML-element to load from
194 */
[4261]195void World::loadParams(const TiXmlElement* root)
196{
[4600]197  PRINTF(4)("Creating a World\n");
[4261]198
[5671]199  LoadParam(root, "identifier", this, World, setStoryID)
[4261]200    .describe("Sets the StoryID of this world");
[4834]201
[5671]202  LoadParam(root, "nextid", this, World, setNextStoryID)
[4261]203    .describe("Sets the ID of the next world");
[4834]204
[5671]205  LoadParam(root, "path", this, World, setPath)
[4261]206    .describe("The Filename of this World (relative from the data-dir)");
207}
208
[3629]209/**
[4978]210 * this is executed just before load
211 *
212 * since the load function sometimes needs data, that has been initialized
213 * before the load and after the proceeding storyentity has finished
[3629]214*/
215ErrorMessage World::preLoad()
216{
[4829]217  State::setWorldEntityList(this->entities = new tList<WorldEntity>());
218  this->cycle = 0;
219
[3620]220  /* init the world interface */
[5206]221  this->shell = new Shell();
[4010]222
[4735]223  LightManager::getInstance();
[4978]224  NullParent::getInstance ();
[3993]225
[4010]226  AnimationPlayer::getInstance(); // initializes the animationPlayer
[5915]227  ParticleEngine::getInstance();
[4338]228  PhysicsEngine::getInstance();
[4010]229
[4015]230  this->localCamera = new Camera();
[4978]231  this->localCamera->setName ("World-Camera");
[4555]232
[4827]233  State::setCamera(this->localCamera, this->localCamera->getTarget());
[4347]234
[4245]235  GraphicsEngine::getInstance()->displayFPS(true);
[4918]236
237  CDEngine::getInstance()->setEntityList( this->entities);
[3526]238}
239
240
[3449]241/**
[4836]242 *  loads the World by initializing all resources, and set their default values.
[3449]243*/
[3459]244ErrorMessage World::load()
[4555]245{
[4104]246  PRINTF(3)("> Loading world: '%s'\n", getPath());
247  TiXmlElement* element;
[4010]248  GameLoader* loader = GameLoader::getInstance();
[4555]249
[4010]250  if( getPath() == NULL)
[2636]251    {
[4104]252      PRINTF(1)("World has no path specified for loading");
[4324]253      this->loadDebugWorld(this->getStoryID());
[4010]254      return (ErrorMessage){213,"Path not specified","World::load()"};
255    }
[4555]256
[5915]257  TiXmlDocument* XMLDoc = new TiXmlDocument( getPath());
[4010]258  // load the campaign document
[4555]259  if( !XMLDoc->LoadFile())
[4010]260  {
261    // report an error
[5915]262    PRINTF(1)("loading XML File: %s @ %s:l%d:c%d\n", XMLDoc->ErrorDesc(), this->getPath(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
[4010]263    delete XMLDoc;
264    return (ErrorMessage){213,"XML File parsing error","World::load()"};
265  }
[4555]266
[4010]267  // check basic validity
268  TiXmlElement* root = XMLDoc->RootElement();
269  assert( root != NULL);
[4555]270
[4010]271  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
272    {
273      // report an error
[4104]274      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
[4010]275      delete XMLDoc;
276      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
277    }
[4555]278
[4010]279  // load the parameters
280  // name
281  const char* string = grabParameter( root, "name");
282  if( string == NULL)
283    {
[4104]284      PRINTF(2)("World is missing a proper 'name'\n");
[5211]285      this->setName("Unknown");
[4010]286    }
287  else
288    {
[5211]289      this->setName(string);
[4010]290    }
[4978]291
[4104]292  ////////////////
293  // LOADSCREEN //
294  ////////////////
295  element = root->FirstChildElement("LoadScreen");
296  if (element == NULL)
297    {
298      PRINTF(2)("no LoadScreen specified, loading default\n");
299
300      glmis->setBackgroundImage("pictures/load_screen.jpg");
301      this->glmis->setMaximum(8);
302      this->glmis->draw();
303    }
304  else
305    {
[4261]306      this->glmis->loadParams(element);
[4104]307      this->glmis->draw();
308    }
309  this->glmis->draw();
[4726]310
311  ////////////////////////
312  // find WorldEntities //
313  ////////////////////////
314
[4104]315  element = root->FirstChildElement("WorldEntities");
[4555]316
[4010]317  if( element == NULL)
318    {
[4104]319      PRINTF(1)("World is missing 'WorldEntities'\n");
[4010]320    }
321  else
322    {
323      element = element->FirstChildElement();
324      // load Players/Objects/Whatever
[4104]325      PRINTF(4)("Loading WorldEntities\n");
[4010]326      while( element != NULL)
[4555]327        {
[5996]328          BaseObject* created = Factory::fabricate(element);
[5915]329          if( created != NULL )
330          {
331            if(created->isA(CL_WORLD_ENTITY))
332              this->spawn(dynamic_cast<WorldEntity*>(created));
[5996]333            printf("Created a %s: %s\n", created->getClassName(), created->getName());
[5915]334          }
335
[4555]336          // if we load a 'Player' we use it as localPlayer
[5915]337
338
[4555]339          //todo do this more elegant
[5915]340          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox"))
341            sky = dynamic_cast<SkyBox*>(created);
[4918]342          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
343          {
[5915]344            terrain = dynamic_cast<Terrain*>(created);
[4918]345            CDEngine::getInstance()->setTerrain(terrain);
346          }
[4555]347          element = element->NextSiblingElement();
[4836]348          glmis->step(); //! @todo temporary
[4555]349        }
[4104]350      PRINTF(4)("Done loading WorldEntities\n");
[4010]351    }
[4555]352
[4726]353    //////////////////////////////
354    // LOADING ADDITIONAL STUFF //
355    //////////////////////////////
356
[5652]357    LoadParamXML(root, "LightManager", LightManager::getInstance(), LightManager, loadParams);
[4735]358
[5915]359   LoadParamXML(root, "ParticleEngine", ParticleEngine::getInstance(), ParticleEngine, loadParams);
360//   LoadParamXML(root, "PhysicsEngine", PhysicsEngine::getInstance(), PhysicsEngine, loadParams);
[4726]361
[4010]362  // free the XML data
[4015]363
[4010]364  delete XMLDoc;
[4015]365  /* GENERIC LOADING PROCESS FINISHED */
[4555]366
367
[5915]368  // Create a Player
369  this->localPlayer = new Player();
[4245]370
[5915]371  Playable* playable;
372  const list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE);
373  if (playableList != NULL)
374  {
375    playable = dynamic_cast<Playable*>(playableList->front());
376    this->localPlayer->setControllable(playable);
377  }
[4555]378
[5915]379  // bind camera
380  playable->addChild (this->localCamera);
[4555]381
[5915]382//   //localCamera->setParent(TrackNode::getInstance());
383//  tn->addChild(this->localCamera);
[4620]384  localCamera->setClipRegion(1, 10000.0);
[5915]385  localCamera->lookAt(playable);
386//  this->localPlayer->setParentMode(PNODE_ALL);
[5355]387  if (sky != NULL)
388  {
389    this->sky->setParent(this->localCamera);
390    this->sky->setParentMode(PNODE_MOVEMENT);
391  }
[3368]392
[4010]393  // initialize debug coord system
394  objectList = glGenLists(1);
395  glNewList (objectList, GL_COMPILE);
[4555]396
[4010]397  glEndList();
[3993]398
[4504]399  SoundEngine::getInstance()->setListener(this->localCamera);
[4176]400
[4347]401
[4709]402
[4715]403  ////////////
404  // STATIC //
405  ////////////
406
407
[4721]408//   TestEntity* testEntity = new TestEntity();
409//   testEntity->setRelCoor(Vector(570, 10, -15));
410//   testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
411//   this->spawn(testEntity);
[4397]412
[4976]413  for(int i = 0; i < 100; i++)
414  {
[5750]415    WorldEntity* tmp = new NPCTest1();
[5049]416    char npcChar[10];
417    sprintf (npcChar, "NPC_%d", i);
[5256]418        tmp->setName(npcChar);
[5336]419    tmp->setAbsCoor(((float)rand()/RAND_MAX) * 5000, 50/*+ (float)rand()/RAND_MAX*20*/, ((float)rand()/RAND_MAX -.5) *30);
[4976]420    this->spawn(tmp);
421  }
422
[6034]423  this->music = NULL;
424  //(OggPlayer*)ResourceManager::getInstance()->load("sound/00-luke_grey_-_hypermode.ogg", OGG, RP_LEVEL);
[5211]425  //music->playback();
[4010]426}
[3365]427
[4245]428
[4324]429
[4326]430/**
[4978]431 * creates a debug world: only for experimental stuff
[4326]432*/
[4010]433void World::loadDebugWorld(int worldID)
434{
435  /*monitor progress*/
436  this->glmis->step();
[4228]437  // stuff beyond this point remains to be loaded properly
[3194]438
[4010]439  // LIGHT initialisation
[4735]440  LightManager::getInstance()->setAmbientColor(.1,.1,.1);
[4736]441//  LightManager::getInstance()->addLight();
[4735]442  LightManager::getInstance()->debug();
[3368]443
[4010]444  switch(this->debugWorldNr)
445    {
446      /*
[4555]447        this loads the hard-coded debug world. this only for simplicity and will be
448        removed by a reald world-loader, which interprets a world-file.
449        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
450        make whatever you want...
[4010]451      */
452    case DEBUG_WORLD_0:
453      {
[4735]454        LightManager::getInstance()->getLight()->setAbsCoor(-5.0, 10.0, -40.0);
[4555]455        /*monitor progress*/
456        this->glmis->step();
[4010]457
[4555]458        // bind camera
459        this->localCamera = new Camera();
460        this->localCamera->setName ("camera");
461        /*monitor progress*/
462        this->glmis->step();
[2816]463
[3419]464
[4555]465        // Create SkySphere
[4621]466        this->sky = new Skysphere("pictures/sky-replace.jpg");
467        this->sky->setName("SkySphere");
468        this->spawn(this->sky);
[4555]469        this->localCamera->addChild(this->sky);
470        this->sky->setParentMode(PNODE_MOVEMENT);
471        /*monitor progress*/
472        this->glmis->step();
[3368]473
[3521]474
[4555]475        terrain = new Terrain("worlds/newGround.obj");
476        terrain->setRelCoor(Vector(0,-10,0));
477        this->spawn(terrain);
478        /*monitor progress*/
479        this->glmis->step();
[2816]480
[4555]481        this->glmis->step();
482        break;
[4010]483      }
484    case DEBUG_WORLD_1:
485      {
[3365]486
[4555]487        break;
[4010]488      }
489    case DEBUG_WORLD_2:
490      {
[3727]491
[4555]492        break;
[4010]493      }
494    default:
[4324]495      break;
[2636]496    }
[4010]497}
[2636]498
[3459]499/**
[4836]500 *  initializes a new World shortly before start
[4978]501 *
502 * this is the function, that will be loaded shortly before the world is
503 * started
[3459]504*/
505ErrorMessage World::init()
506{
507  this->bPause = false;
[5051]508
509  /* update the object position before game start - so there are no wrong coordinates used in the first processing */
[5769]510  NullParent::getInstance()->updateNode (0.001f);
511  NullParent::getInstance()->updateNode (0.001f);
[5084]512
[3459]513}
514
515
516/**
[4836]517 *  starts the World
[3459]518*/
519ErrorMessage World::start()
520{
[3546]521  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
[3459]522  this->bQuitOrxonox = false;
523  this->bQuitCurrentGame = false;
524  this->mainLoop();
525}
526
527/**
[4836]528 *  stops the world.
[3459]529
530   This happens, when the player decides to end the Level.
531*/
532ErrorMessage World::stop()
533{
[3546]534  PRINTF(3)("World::stop() - got stop signal\n");
[3459]535  this->bQuitCurrentGame = true;
536}
537
538/**
[4836]539 *  pauses the Game
[3459]540*/
541ErrorMessage World::pause()
542{
543  this->isPaused = true;
544}
545
546/**
[4836]547 *  ends the pause Phase
[3459]548*/
549ErrorMessage World::resume()
550{
551  this->isPaused = false;
552}
553
554/**
[4836]555 *  destroys the World
[3459]556*/
557ErrorMessage World::destroy()
558{
[3566]559
[3459]560}
561
562/**
[4836]563 *  shows the loading screen
[3459]564*/
565void World::displayLoadScreen ()
566{
[4555]567  PRINTF(3)("World::displayLoadScreen - start\n");
568
569  //GLMenuImageScreen*
[4099]570  this->glmis = new GLMenuImageScreen();
[3675]571  this->glmis->setMaximum(8);
[4555]572
573  PRINTF(3)("World::displayLoadScreen - end\n");
[3459]574}
575
576/**
[4836]577 *  removes the loadscreen, and changes over to the game
[3459]578
[4836]579   @todo take out the delay
[3459]580*/
581void World::releaseLoadScreen ()
582{
[4555]583  PRINTF(3)("World::releaseLoadScreen - start\n");
[3459]584  this->glmis->setValue(this->glmis->getMaximum());
[4555]585  PRINTF(3)("World::releaseLoadScreen - end\n");
[4099]586  delete this->glmis;
[3459]587}
588
589
[3620]590/**
[4836]591 *  gets the list of entities from the world
592 * @returns entity list
[3620]593*/
594tList<WorldEntity>* World::getEntities()
595{
596  return this->entities;
597}
598
599
[3646]600/**
[4836]601 *  this returns the current game time
602 * @returns elapsed game time
[3646]603*/
604double World::getGameTime()
605{
606  return this->gameTime;
607}
608
609
[4555]610/**
[4836]611 *  function to put your own debug stuff into it. it can display informations about
[3225]612   the current class/procedure
613*/
[2640]614void World::debug()
615{
[5115]616  PRINTF(0)("Printing out the List of alive WorldEntities:\n");
617  tIterator<WorldEntity>* iterator = this->entities->getIterator();
618  WorldEntity* entity = iterator->firstElement();
619  while( entity != NULL)
620  {
621    PRINTF(0)("%s::%s\n", entity->getClassName(), entity->getName());
622    entity = iterator->nextElement();
623  }
624  delete iterator;
[2640]625}
[2636]626
[2640]627
[3449]628/**
[3225]629  \brief main loop of the world: executing all world relevant function
630
631  in this loop we synchronize (if networked), handle input events, give the heart-beat to
632  all other member-entities of the world (tick to player, enemies etc.), checking for
633  collisions drawing everything to the screen.
634*/
[2636]635void World::mainLoop()
636{
[3365]637  this->lastFrame = SDL_GetTicks ();
[3546]638  PRINTF(3)("World::mainLoop() - Entering main loop\n");
[5045]639
[4836]640  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* @todo implement pause */
[2551]641    {
[4558]642      ++this->cycle;
[5048]643      PRINTF(4)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
[2636]644      // Network
[3365]645      this->synchronize ();
[2636]646      // Process input
[3365]647      this->handleInput ();
[3215]648      if( this->bQuitCurrentGame || this->bQuitOrxonox)
[4555]649          break;
[2636]650      // Process time
[3551]651      this->tick ();
[5045]652      // Process collision
653      this->collide ();
[3551]654      // Update the state
[4555]655      this->update ();
[2636]656      // Draw
[3365]657      this->display ();
[5045]658    }
[3548]659
[3546]660  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
[1899]661}
662
[3459]663
[2190]664/**
[4836]665 *  synchronize local data with remote data
[1855]666*/
[2636]667void World::synchronize ()
[1855]668{
[2636]669  // Get remote input
670  // Update synchronizables
[5996]671/*  NetworkManager::getInstance()->synchronize();*/
[1855]672}
[2636]673
[3459]674
[2636]675/**
[4836]676 *  run all input processing
[3225]677
678   the command node is the central input event dispatcher. the node uses the even-queue from
679   sdl and has its own event-passing-queue.
[2636]680*/
[3225]681void World::handleInput ()
[2636]682{
[4407]683  EventHandler::getInstance()->process();
684
[2636]685  // remoteinput
686}
687
[3459]688
[2636]689/**
[4836]690 *  advance the timeline
[3225]691
692   this calculates the time used to process one frame (with all input handling, drawing, etc)
693   the time is mesured in ms and passed to all world-entities and other classes that need
694   a heart-beat.
[2636]695*/
[3551]696void World::tick ()
[2636]697{
698  Uint32 currentFrame = SDL_GetTicks();
699  if(!this->bPause)
700    {
[3644]701      this->dt = currentFrame - this->lastFrame;
[4555]702
[4610]703      if( this->dt > 10)
[4555]704        {
705          float fps = 1000/dt;
[3790]706
[4555]707          // temporary, only for showing how fast the text-engine is
708          char tmpChar[20];
709          sprintf(tmpChar, "fps: %4.0f", fps);
710        }
[2636]711      else
[4555]712        {
713          /* the frame-rate is limited to 100 frames per second, all other things are for
714             nothing.
715          */
[5048]716          PRINTF(3)("fps = 1000 - frame rate is adjusted\n");
[4610]717          SDL_Delay(10-dt);
[4555]718          this->dt = 10;
719        }
720
[5205]721      this->dtS = (float)this->dt / 1000.0 * this->speed;
[4145]722      this->gameTime += this->dtS;
[4833]723
[3654]724      tIterator<WorldEntity>* iterator = this->entities->getIterator();
[5115]725      WorldEntity* entity = iterator->firstElement();
[4555]726      while( entity != NULL)
727        {
728          entity->tick (this->dtS);
729          entity = iterator->nextElement();
730        }
[3654]731      delete iterator;
[4010]732
[3459]733      /* update tick the rest */
[4832]734      this->localCamera->tick(this->dtS);
[4558]735      // tick the engines
[4245]736      AnimationPlayer::getInstance()->tick(this->dtS);
[4979]737//      if (this->cycle > 5)
[4558]738        PhysicsEngine::getInstance()->tick(this->dtS);
[4396]739
[4558]740      ParticleEngine::getInstance()->tick(this->dtS);
741      GarbageCollector::getInstance()->tick(this->dtS);
[4396]742
[4831]743
[4558]744      /** actualy the Graphics Engine should tick the world not the other way around...
[4555]745         but since we like the things not too complicated we got it this way around
746         until there is need or time to do it the other way around.
[4836]747         @todo: GraphicsEngine ticks world: separation of processes and data...
[4681]748
749        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
750         beceause graphics have nothing(or at least not much) to do with Motion.
[4245]751      */
752      GraphicsEngine::getInstance()->tick(this->dtS);
[2636]753    }
754  this->lastFrame = currentFrame;
755}
756
[3216]757
[2636]758/**
[4836]759 *  this function gives the world a consistant state
[3551]760
761   after ticking (updating the world state) this will give a constistant
762   state to the whole system.
763*/
764void World::update()
765{
[4822]766  GarbageCollector::getInstance()->update();
[5406]767  GraphicsEngine::getInstance()->update(this->dtS);
[5769]768  NullParent::getInstance()->updateNode (this->dtS);
[4504]769
770  SoundEngine::getInstance()->update();
[4978]771  //music->update();
[3551]772}
773
774
[4917]775void World::collide()
776{
[4918]777  CDEngine::getInstance()->checkCollisions();
[4917]778}
779
[3551]780/**
[4836]781 *  render the current frame
[4555]782
[3225]783   clear all buffers and draw the world
[2636]784*/
785void World::display ()
786{
787  // clear buffer
788  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
789  // set camera
790  this->localCamera->apply ();
791  // draw world
792  this->draw();
793  // draw HUD
[4837]794  /** @todo draw HUD */
[2636]795  // flip buffers
[4681]796  GraphicsEngine::swapBuffers();
[3365]797  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
798  //SDL_Flip (screen);
[2636]799}
800
[2644]801
[3225]802/**
[4917]803 *  runs through all entities calling their draw() methods
804 */
805void World::draw ()
806{
807  /* draw entities */
808  WorldEntity* entity;
809  glLoadIdentity();
810  tIterator<WorldEntity>* iterator = this->entities->getIterator();
[5115]811  entity = iterator->firstElement();
[4917]812  while( entity != NULL )
813  {
[5055]814    if( entity->isVisible() ) entity->draw();
[5429]815    if( unlikely( this->showBV)) entity->drawBVTree(3, 226);  // to draw the bounding boxes of the objects at level 2 for debug purp
[4917]816    entity = iterator->nextElement();
817  }
818  delete iterator;
819
820  glCallList (objectList);
821
822  ParticleEngine::getInstance()->draw();
823
[5389]824  if (unlikely(this->showPNodes))
825    NullParent::getInstance()->debugDraw(0);
826
[4917]827  GraphicsEngine::getInstance()->draw();
828  //TextEngine::getInstance()->draw();
829}
830
831/**
[4836]832 *  add and spawn a new entity to this world
833 * @param entity to be added
[3225]834*/
[2644]835void World::spawn(WorldEntity* entity)
836{
[3365]837  this->entities->add (entity);
[3233]838  entity->postSpawn ();
[2816]839}
840
841
[3225]842/**
[4836]843 *  add and spawn a new entity to this world
844 * @param entity to be added
845 * @param absCoor At what coordinates to add this entity.
846 * @param absDir In which direction should it look.
[3225]847*/
[3365]848void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
[2816]849{
[3529]850  this->entities->add (entity);
851
[3809]852  entity->setAbsCoor (*absCoor);
853  entity->setAbsDir (*absDir);
[3365]854
[3233]855  entity->postSpawn ();
[2644]856}
[2816]857
858
[3521]859/**
[4836]860 *  add and spawn a new entity to this world
861 * @param entity to be added
862 * @param entity to be added to (PNode)
863 * @param At what relative  coordinates to add this entity.
864 * @param In which relative direction should it look.
[3521]865*/
[4555]866void World::spawn(WorldEntity* entity, PNode* parentNode,
[4765]867                  Vector* relCoor, Quaternion* relDir)
[3521]868{
[3529]869  if( parentNode != NULL)
[3521]870    {
871      parentNode->addChild (entity);
[4555]872
[3809]873      entity->setRelCoor (*relCoor);
874      entity->setRelDir (*relDir);
[4555]875
[3521]876      this->entities->add (entity);
[4555]877
[3521]878      entity->postSpawn ();
879    }
880}
881
[4010]882void World::setPath( const char* name)
883{
[4094]884  if (this->path)
885    delete this->path;
886  if (ResourceManager::isFile(name))
887  {
888    this->path = new char[strlen(name)+1];
889    strcpy(this->path, name);
890  }
891  else
892    {
893      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
894      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
895    }
[4010]896}
897
898const char* World::getPath( void)
899{
900  return path;
901}
Note: See TracBrowser for help on using the repository browser.