Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6017 was 5996, checked in by patrick, 19 years ago

orxonox/trunk: merged network branche into trunk with command svn merge -r 5824:HEAD

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
[5211]417  this->music = NULL;//(OggPlayer*)ResourceManager::getInstance()->load("sound/00-luke_grey_-_hypermode.ogg", OGG, RP_LEVEL);
418  //music->playback();
[4010]419}
[3365]420
[4245]421
[4324]422
[4326]423/**
[4978]424 * creates a debug world: only for experimental stuff
[4326]425*/
[4010]426void World::loadDebugWorld(int worldID)
427{
428  /*monitor progress*/
429  this->glmis->step();
[4228]430  // stuff beyond this point remains to be loaded properly
[3194]431
[4010]432  // LIGHT initialisation
[4735]433  LightManager::getInstance()->setAmbientColor(.1,.1,.1);
[4736]434//  LightManager::getInstance()->addLight();
[4735]435  LightManager::getInstance()->debug();
[3368]436
[4010]437  switch(this->debugWorldNr)
438    {
439      /*
[4555]440        this loads the hard-coded debug world. this only for simplicity and will be
441        removed by a reald world-loader, which interprets a world-file.
442        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
443        make whatever you want...
[4010]444      */
445    case DEBUG_WORLD_0:
446      {
[4735]447        LightManager::getInstance()->getLight()->setAbsCoor(-5.0, 10.0, -40.0);
[4555]448        /*monitor progress*/
449        this->glmis->step();
[4010]450
[4555]451        // bind camera
452        this->localCamera = new Camera();
453        this->localCamera->setName ("camera");
454        /*monitor progress*/
455        this->glmis->step();
[2816]456
[3419]457
[4555]458        // Create SkySphere
[4621]459        this->sky = new Skysphere("pictures/sky-replace.jpg");
460        this->sky->setName("SkySphere");
461        this->spawn(this->sky);
[4555]462        this->localCamera->addChild(this->sky);
463        this->sky->setParentMode(PNODE_MOVEMENT);
464        /*monitor progress*/
465        this->glmis->step();
[3368]466
[3521]467
[4555]468        terrain = new Terrain("worlds/newGround.obj");
469        terrain->setRelCoor(Vector(0,-10,0));
470        this->spawn(terrain);
471        /*monitor progress*/
472        this->glmis->step();
[2816]473
[4555]474        this->glmis->step();
475        break;
[4010]476      }
477    case DEBUG_WORLD_1:
478      {
[3365]479
[4555]480        break;
[4010]481      }
482    case DEBUG_WORLD_2:
483      {
[3727]484
[4555]485        break;
[4010]486      }
487    default:
[4324]488      break;
[2636]489    }
[4010]490}
[2636]491
[3459]492/**
[4836]493 *  initializes a new World shortly before start
[4978]494 *
495 * this is the function, that will be loaded shortly before the world is
496 * started
[3459]497*/
498ErrorMessage World::init()
499{
500  this->bPause = false;
[5051]501
502  /* update the object position before game start - so there are no wrong coordinates used in the first processing */
[5769]503  NullParent::getInstance()->updateNode (0.001f);
504  NullParent::getInstance()->updateNode (0.001f);
[5084]505
[3459]506}
507
508
509/**
[4836]510 *  starts the World
[3459]511*/
512ErrorMessage World::start()
513{
[3546]514  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
[3459]515  this->bQuitOrxonox = false;
516  this->bQuitCurrentGame = false;
517  this->mainLoop();
518}
519
520/**
[4836]521 *  stops the world.
[3459]522
523   This happens, when the player decides to end the Level.
524*/
525ErrorMessage World::stop()
526{
[3546]527  PRINTF(3)("World::stop() - got stop signal\n");
[3459]528  this->bQuitCurrentGame = true;
529}
530
531/**
[4836]532 *  pauses the Game
[3459]533*/
534ErrorMessage World::pause()
535{
536  this->isPaused = true;
537}
538
539/**
[4836]540 *  ends the pause Phase
[3459]541*/
542ErrorMessage World::resume()
543{
544  this->isPaused = false;
545}
546
547/**
[4836]548 *  destroys the World
[3459]549*/
550ErrorMessage World::destroy()
551{
[3566]552
[3459]553}
554
555/**
[4836]556 *  shows the loading screen
[3459]557*/
558void World::displayLoadScreen ()
559{
[4555]560  PRINTF(3)("World::displayLoadScreen - start\n");
561
562  //GLMenuImageScreen*
[4099]563  this->glmis = new GLMenuImageScreen();
[3675]564  this->glmis->setMaximum(8);
[4555]565
566  PRINTF(3)("World::displayLoadScreen - end\n");
[3459]567}
568
569/**
[4836]570 *  removes the loadscreen, and changes over to the game
[3459]571
[4836]572   @todo take out the delay
[3459]573*/
574void World::releaseLoadScreen ()
575{
[4555]576  PRINTF(3)("World::releaseLoadScreen - start\n");
[3459]577  this->glmis->setValue(this->glmis->getMaximum());
[4555]578  PRINTF(3)("World::releaseLoadScreen - end\n");
[4099]579  delete this->glmis;
[3459]580}
581
582
[3620]583/**
[4836]584 *  gets the list of entities from the world
585 * @returns entity list
[3620]586*/
587tList<WorldEntity>* World::getEntities()
588{
589  return this->entities;
590}
591
592
[3646]593/**
[4836]594 *  this returns the current game time
595 * @returns elapsed game time
[3646]596*/
597double World::getGameTime()
598{
599  return this->gameTime;
600}
601
602
[4555]603/**
[4836]604 *  function to put your own debug stuff into it. it can display informations about
[3225]605   the current class/procedure
606*/
[2640]607void World::debug()
608{
[5115]609  PRINTF(0)("Printing out the List of alive WorldEntities:\n");
610  tIterator<WorldEntity>* iterator = this->entities->getIterator();
611  WorldEntity* entity = iterator->firstElement();
612  while( entity != NULL)
613  {
614    PRINTF(0)("%s::%s\n", entity->getClassName(), entity->getName());
615    entity = iterator->nextElement();
616  }
617  delete iterator;
[2640]618}
[2636]619
[2640]620
[3449]621/**
[3225]622  \brief main loop of the world: executing all world relevant function
623
624  in this loop we synchronize (if networked), handle input events, give the heart-beat to
625  all other member-entities of the world (tick to player, enemies etc.), checking for
626  collisions drawing everything to the screen.
627*/
[2636]628void World::mainLoop()
629{
[3365]630  this->lastFrame = SDL_GetTicks ();
[3546]631  PRINTF(3)("World::mainLoop() - Entering main loop\n");
[5045]632
[4836]633  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* @todo implement pause */
[2551]634    {
[4558]635      ++this->cycle;
[5048]636      PRINTF(4)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
[2636]637      // Network
[3365]638      this->synchronize ();
[2636]639      // Process input
[3365]640      this->handleInput ();
[3215]641      if( this->bQuitCurrentGame || this->bQuitOrxonox)
[4555]642          break;
[2636]643      // Process time
[3551]644      this->tick ();
[5045]645      // Process collision
646      this->collide ();
[3551]647      // Update the state
[4555]648      this->update ();
[2636]649      // Draw
[3365]650      this->display ();
[5045]651    }
[3548]652
[3546]653  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
[1899]654}
655
[3459]656
[2190]657/**
[4836]658 *  synchronize local data with remote data
[1855]659*/
[2636]660void World::synchronize ()
[1855]661{
[2636]662  // Get remote input
663  // Update synchronizables
[5996]664/*  NetworkManager::getInstance()->synchronize();*/
[1855]665}
[2636]666
[3459]667
[2636]668/**
[4836]669 *  run all input processing
[3225]670
671   the command node is the central input event dispatcher. the node uses the even-queue from
672   sdl and has its own event-passing-queue.
[2636]673*/
[3225]674void World::handleInput ()
[2636]675{
[4407]676  EventHandler::getInstance()->process();
677
[2636]678  // remoteinput
679}
680
[3459]681
[2636]682/**
[4836]683 *  advance the timeline
[3225]684
685   this calculates the time used to process one frame (with all input handling, drawing, etc)
686   the time is mesured in ms and passed to all world-entities and other classes that need
687   a heart-beat.
[2636]688*/
[3551]689void World::tick ()
[2636]690{
691  Uint32 currentFrame = SDL_GetTicks();
692  if(!this->bPause)
693    {
[3644]694      this->dt = currentFrame - this->lastFrame;
[4555]695
[4610]696      if( this->dt > 10)
[4555]697        {
698          float fps = 1000/dt;
[3790]699
[4555]700          // temporary, only for showing how fast the text-engine is
701          char tmpChar[20];
702          sprintf(tmpChar, "fps: %4.0f", fps);
703        }
[2636]704      else
[4555]705        {
706          /* the frame-rate is limited to 100 frames per second, all other things are for
707             nothing.
708          */
[5048]709          PRINTF(3)("fps = 1000 - frame rate is adjusted\n");
[4610]710          SDL_Delay(10-dt);
[4555]711          this->dt = 10;
712        }
713
[5205]714      this->dtS = (float)this->dt / 1000.0 * this->speed;
[4145]715      this->gameTime += this->dtS;
[4833]716
[3654]717      tIterator<WorldEntity>* iterator = this->entities->getIterator();
[5115]718      WorldEntity* entity = iterator->firstElement();
[4555]719      while( entity != NULL)
720        {
721          entity->tick (this->dtS);
722          entity = iterator->nextElement();
723        }
[3654]724      delete iterator;
[4010]725
[3459]726      /* update tick the rest */
[4832]727      this->localCamera->tick(this->dtS);
[4558]728      // tick the engines
[4245]729      AnimationPlayer::getInstance()->tick(this->dtS);
[4979]730//      if (this->cycle > 5)
[4558]731        PhysicsEngine::getInstance()->tick(this->dtS);
[4396]732
[4558]733      ParticleEngine::getInstance()->tick(this->dtS);
734      GarbageCollector::getInstance()->tick(this->dtS);
[4396]735
[4831]736
[4558]737      /** actualy the Graphics Engine should tick the world not the other way around...
[4555]738         but since we like the things not too complicated we got it this way around
739         until there is need or time to do it the other way around.
[4836]740         @todo: GraphicsEngine ticks world: separation of processes and data...
[4681]741
742        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
743         beceause graphics have nothing(or at least not much) to do with Motion.
[4245]744      */
745      GraphicsEngine::getInstance()->tick(this->dtS);
[2636]746    }
747  this->lastFrame = currentFrame;
748}
749
[3216]750
[2636]751/**
[4836]752 *  this function gives the world a consistant state
[3551]753
754   after ticking (updating the world state) this will give a constistant
755   state to the whole system.
756*/
757void World::update()
758{
[4822]759  GarbageCollector::getInstance()->update();
[5406]760  GraphicsEngine::getInstance()->update(this->dtS);
[5769]761  NullParent::getInstance()->updateNode (this->dtS);
[4504]762
763  SoundEngine::getInstance()->update();
[4978]764  //music->update();
[3551]765}
766
767
[4917]768void World::collide()
769{
[4918]770  CDEngine::getInstance()->checkCollisions();
[4917]771}
772
[3551]773/**
[4836]774 *  render the current frame
[4555]775
[3225]776   clear all buffers and draw the world
[2636]777*/
778void World::display ()
779{
780  // clear buffer
781  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
782  // set camera
783  this->localCamera->apply ();
784  // draw world
785  this->draw();
786  // draw HUD
[4837]787  /** @todo draw HUD */
[2636]788  // flip buffers
[4681]789  GraphicsEngine::swapBuffers();
[3365]790  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
791  //SDL_Flip (screen);
[2636]792}
793
[2644]794
[3225]795/**
[4917]796 *  runs through all entities calling their draw() methods
797 */
798void World::draw ()
799{
800  /* draw entities */
801  WorldEntity* entity;
802  glLoadIdentity();
803  tIterator<WorldEntity>* iterator = this->entities->getIterator();
[5115]804  entity = iterator->firstElement();
[4917]805  while( entity != NULL )
806  {
[5055]807    if( entity->isVisible() ) entity->draw();
[5429]808    if( unlikely( this->showBV)) entity->drawBVTree(3, 226);  // to draw the bounding boxes of the objects at level 2 for debug purp
[4917]809    entity = iterator->nextElement();
810  }
811  delete iterator;
812
813  glCallList (objectList);
814
815  ParticleEngine::getInstance()->draw();
816
[5389]817  if (unlikely(this->showPNodes))
818    NullParent::getInstance()->debugDraw(0);
819
[4917]820  GraphicsEngine::getInstance()->draw();
821  //TextEngine::getInstance()->draw();
822}
823
824/**
[4836]825 *  add and spawn a new entity to this world
826 * @param entity to be added
[3225]827*/
[2644]828void World::spawn(WorldEntity* entity)
829{
[3365]830  this->entities->add (entity);
[3233]831  entity->postSpawn ();
[2816]832}
833
834
[3225]835/**
[4836]836 *  add and spawn a new entity to this world
837 * @param entity to be added
838 * @param absCoor At what coordinates to add this entity.
839 * @param absDir In which direction should it look.
[3225]840*/
[3365]841void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
[2816]842{
[3529]843  this->entities->add (entity);
844
[3809]845  entity->setAbsCoor (*absCoor);
846  entity->setAbsDir (*absDir);
[3365]847
[3233]848  entity->postSpawn ();
[2644]849}
[2816]850
851
[3521]852/**
[4836]853 *  add and spawn a new entity to this world
854 * @param entity to be added
855 * @param entity to be added to (PNode)
856 * @param At what relative  coordinates to add this entity.
857 * @param In which relative direction should it look.
[3521]858*/
[4555]859void World::spawn(WorldEntity* entity, PNode* parentNode,
[4765]860                  Vector* relCoor, Quaternion* relDir)
[3521]861{
[3529]862  if( parentNode != NULL)
[3521]863    {
864      parentNode->addChild (entity);
[4555]865
[3809]866      entity->setRelCoor (*relCoor);
867      entity->setRelDir (*relDir);
[4555]868
[3521]869      this->entities->add (entity);
[4555]870
[3521]871      entity->postSpawn ();
872    }
873}
874
[4010]875void World::setPath( const char* name)
876{
[4094]877  if (this->path)
878    delete this->path;
879  if (ResourceManager::isFile(name))
880  {
881    this->path = new char[strlen(name)+1];
882    strcpy(this->path, name);
883  }
884  else
885    {
886      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
887      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
888    }
[4010]889}
890
891const char* World::getPath( void)
892{
893  return path;
894}
Note: See TracBrowser for help on using the repository browser.