Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: taken out NullParent.
THE TRUNK IS NOT RUNNING FOR THE TIME BEING. DO NOT BE ALARMED, THIS IS TEMPORARY

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