Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the spaceshipcontroll branche back to the trunk
merged with command
svn merge branche/spaceshipcontroll trunk -r5978:HEAD
confilcs:
space_ship.cc: favor of controll, but Draw from trunk
rest: space_ship.h and sound_engine. in favor of the spaceshipcontroll branche

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