Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/story_entities/world.cc @ 5968

Last change on this file since 5968 was 5968, checked in by patrick, 18 years ago

network: merged the trunk into the network with the command svn merge -r5824:HEAD ../trunk network, changes changed… bla bla..

File size: 21.6 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
[5829]72#include "network_manager.h"
[5968]73#include "playable.h"
[5829]74
[5968]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
[5968]125
[4978]126  // here everything that is alocated by the World is deleted
[4837]127  delete this->entities;
[4830]128  State::setWorldEntityList(NULL);
129
[5968]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.
[4870]145  delete NullParent::getInstance();
[5968]146
[5318]147  Shader::suspendShader();
[4872]148
[4978]149  // unload the resources !!
[4136]150  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
[5218]151
152  delete[] this->path;
[1872]153}
[1858]154
[3526]155/**
[4978]156 * initializes the world.
157 * @param name the name of the world
158 * @param worldID the ID of this world
159 *
160 * set all stuff here that is world generic and does not use to much memory
161 * because the real init() function StoryEntity::init() will be called
162 * shortly before start of the game.
163 * since all worlds are initiated/referenced before they will be started.
164 * NO LEVEL LOADING HERE - NEVER!
[3526]165*/
[4978]166void World::constuctorInit(const char* name, int worldID)
[3526]167{
[4320]168  this->setClassID(CL_WORLD, "World");
[2636]169
[4978]170  this->setName(name);
[3526]171  this->debugWorldNr = worldID;
[5211]172  this->gameTime = 0.0f;
[5205]173  this->setSpeed(1.0);
[4961]174  this->music = NULL;
[5211]175  this->shell = NULL;
176  this->entities = NULL;
[5968]177  this->localPlayer = NULL;
178  this->localCamera = NULL;
[5389]179
180  this->showPNodes = false;
[5429]181  this->showBV = false;
[3629]182}
[3526]183
[4978]184/**
185 * loads the parameters of a World from an XML-element
186 * @param root the XML-element to load from
187 */
[4261]188void World::loadParams(const TiXmlElement* root)
189{
[4600]190  PRINTF(4)("Creating a World\n");
[4261]191
[5671]192  LoadParam(root, "identifier", this, World, setStoryID)
[4261]193    .describe("Sets the StoryID of this world");
[4834]194
[5671]195  LoadParam(root, "nextid", this, World, setNextStoryID)
[4261]196    .describe("Sets the ID of the next world");
[4834]197
[5671]198  LoadParam(root, "path", this, World, setPath)
[4261]199    .describe("The Filename of this World (relative from the data-dir)");
200}
201
[3629]202/**
[4978]203 * this is executed just before load
204 *
205 * since the load function sometimes needs data, that has been initialized
206 * before the load and after the proceeding storyentity has finished
[3629]207*/
208ErrorMessage World::preLoad()
209{
[4829]210  State::setWorldEntityList(this->entities = new tList<WorldEntity>());
211  this->cycle = 0;
212
[3620]213  /* init the world interface */
[5206]214  this->shell = new Shell();
[4010]215
[4735]216  LightManager::getInstance();
[4978]217  NullParent::getInstance ();
[3993]218
[4010]219  AnimationPlayer::getInstance(); // initializes the animationPlayer
[5968]220  ParticleEngine::getInstance();
[4338]221  PhysicsEngine::getInstance();
[4010]222
[4015]223  this->localCamera = new Camera();
[4978]224  this->localCamera->setName ("World-Camera");
[4555]225
[4827]226  State::setCamera(this->localCamera, this->localCamera->getTarget());
[4347]227
[4245]228  GraphicsEngine::getInstance()->displayFPS(true);
[4918]229
230  CDEngine::getInstance()->setEntityList( this->entities);
[3526]231}
232
233
[3449]234/**
[4836]235 *  loads the World by initializing all resources, and set their default values.
[3449]236*/
[3459]237ErrorMessage World::load()
[4555]238{
[4104]239  PRINTF(3)("> Loading world: '%s'\n", getPath());
240  TiXmlElement* element;
[4010]241  GameLoader* loader = GameLoader::getInstance();
[4555]242
[4010]243  if( getPath() == NULL)
[2636]244    {
[4104]245      PRINTF(1)("World has no path specified for loading");
[4324]246      this->loadDebugWorld(this->getStoryID());
[4010]247      return (ErrorMessage){213,"Path not specified","World::load()"};
248    }
[4555]249
[5968]250  TiXmlDocument* XMLDoc = new TiXmlDocument( getPath());
[4010]251  // load the campaign document
[4555]252  if( !XMLDoc->LoadFile())
[4010]253  {
254    // report an error
[5968]255    PRINTF(1)("loading XML File: %s @ %s:l%d:c%d\n", XMLDoc->ErrorDesc(), this->getPath(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
[4010]256    delete XMLDoc;
257    return (ErrorMessage){213,"XML File parsing error","World::load()"};
258  }
[4555]259
[4010]260  // check basic validity
261  TiXmlElement* root = XMLDoc->RootElement();
262  assert( root != NULL);
[4555]263
[4010]264  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
265    {
266      // report an error
[4104]267      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
[4010]268      delete XMLDoc;
269      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
270    }
[4555]271
[4010]272  // load the parameters
273  // name
274  const char* string = grabParameter( root, "name");
275  if( string == NULL)
276    {
[4104]277      PRINTF(2)("World is missing a proper 'name'\n");
[5211]278      this->setName("Unknown");
[4010]279    }
280  else
281    {
[5211]282      this->setName(string);
[4010]283    }
[4978]284
[4104]285  ////////////////
286  // LOADSCREEN //
287  ////////////////
288  element = root->FirstChildElement("LoadScreen");
289  if (element == NULL)
290    {
291      PRINTF(2)("no LoadScreen specified, loading default\n");
292
293      glmis->setBackgroundImage("pictures/load_screen.jpg");
294      this->glmis->setMaximum(8);
295      this->glmis->draw();
296    }
297  else
298    {
[4261]299      this->glmis->loadParams(element);
[4104]300      this->glmis->draw();
301    }
302  this->glmis->draw();
[4726]303
304  ////////////////////////
305  // find WorldEntities //
306  ////////////////////////
307
[4104]308  element = root->FirstChildElement("WorldEntities");
[4555]309
[4010]310  if( element == NULL)
311    {
[4104]312      PRINTF(1)("World is missing 'WorldEntities'\n");
[4010]313    }
314  else
315    {
316      element = element->FirstChildElement();
317      // load Players/Objects/Whatever
[4104]318      PRINTF(4)("Loading WorldEntities\n");
[4010]319      while( element != NULL)
[4555]320        {
[5968]321          BaseObject* created = (loader->fabricate(element));
322          if( created != NULL )
[4919]323          {
[5968]324            if(created->isA(CL_WORLD_ENTITY))
325              this->spawn(dynamic_cast<WorldEntity*>(created));
326            printf("Created a %s: %s\n", created->getClassName(), created->getName());
[5829]327            NetworkManager::getInstance()->connectSynchronizeable(*(Synchronizeable*)this->localPlayer);
[4919]328          }
[5968]329
330          // if we load a 'Player' we use it as localPlayer
331
332
333          //todo do this more elegant
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          {
[5968]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
[5968]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
[5968]362  // Create a Player
363  this->localPlayer = new Player();
[4245]364
[5968]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
[5968]373  // bind camera
374  playable->addChild (this->localCamera);
[4555]375
[5968]376//   //localCamera->setParent(TrackNode::getInstance());
377//  tn->addChild(this->localCamera);
[4620]378  localCamera->setClipRegion(1, 10000.0);
[5968]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
[5829]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.