Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/physics/src/story_entities/world.cc @ 4332

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

orxonox/branches/physics: merged the trunk back to the physics-branche
merged with command:
svn merge -r 4301:HEAD trunk/ branches/physics/
little conflict in particle-system resolved easily

File size: 28.4 KB
RevLine 
[1853]1
[4178]2
[1853]3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
[1855]12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
[2190]15   co-programmer: Christian Meyer
[1853]16*/
17
[3590]18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
19
[2190]20#include "world.h"
[3608]21
22#include "orxonox.h"
[3620]23
[4293]24#include "state.h"
25
[3608]26#include "p_node.h"
27#include "null_parent.h"
28#include "helper_parent.h"
[4332]29#include "pilot_node.h"
[3608]30#include "track_node.h"
[2190]31#include "world_entity.h"
[2036]32#include "player.h"
[2190]33#include "camera.h"
[2816]34#include "environment.h"
[3419]35#include "skysphere.h"
[3803]36#include "skybox.h"
[3750]37#include "satellite.h"
[4283]38#include "test_entity.h"
[3608]39#include "terrain.h"
[3436]40#include "light.h"
[3790]41#include "text_engine.h"
[3620]42
[3646]43#include "track_manager.h"
44#include "garbage_collector.h"
[4301]45#include "object_manager.h"
[3812]46#include "animation_player.h"
[4178]47#include "particle_engine.h"
[4283]48#include "graphics_engine.h"
[3646]49
[3608]50#include "command_node.h"
51#include "glmenu_imagescreen.h"
52#include "list.h"
[4178]53#include "game_loader.h"
[2036]54
[4178]55#include "animation3d.h"
[4183]56#include "physics_engine.h"
57#include "gravity.h"
[3608]58
[4178]59#include "substring.h"
[3608]60
[4283]61#include "factory.h"
62
[4301]63#include "projectile.h"
64
[1856]65using namespace std;
[1853]66
[3620]67WorldInterface* WorldInterface::singletonRef = 0;
68
69
70/**
71   \brief private constructor because of singleton
72*/
73WorldInterface::WorldInterface()
74{
75  this->worldIsInitialized = false;
76  this->worldReference = NULL;
77}
78
79/**
80   \brief public deconstructor
81*/
82WorldInterface::~WorldInterface()
83{
84  this->singletonRef = NULL;
85  this->worldIsInitialized = false;
86  this->worldReference = NULL;
87}
88
89/**
90   \brief gets the singleton instance
91   \returns singleton instance
92*/
93WorldInterface* WorldInterface::getInstance()
94{
95  if( singletonRef == NULL)
96    singletonRef = new WorldInterface();
97  return singletonRef;
98}
99
100
101/**
102   \brief initializes the interface
103   \param reference to the world
104
105   if the worldinterface is not initilizes, there wont be any
106   useable interface
107*/
108void WorldInterface::init(World* world)
109{
110  this->worldReference = world;
[3629]111  if( world != NULL)
[3620]112    {
113      this->worldIsInitialized = true;
114      PRINTF(3)("WorldInterface up and running\n");
115    }
116}
117
118
119/**
120   \brief gets the entity list from the world
121   \return entity list
122*/
123tList<WorldEntity>* WorldInterface::getEntityList()
124{
125  if( this->worldIsInitialized)
126    return this->worldReference->getEntities();
127  PRINT(1)("Someone tried to use the WorldInterface before it has been initizlized! this can result in SEGFAULTs!\n");
128  return NULL;
129}
130
[4178]131CREATE_FACTORY(World);
[3620]132
[4283]133World::World(const TiXmlElement* root)
[4178]134{
135  this->constuctorInit("", -1);
136  this->path = NULL;
137 
[4283]138  this->loadParams(root);
[4178]139}
140
[1858]141/**
[2551]142    \brief create a new World
143   
144    This creates a new empty world!
[1858]145*/
[2636]146World::World (char* name)
[1855]147{
[4178]148  this->path = NULL;
149  this->constuctorInit(name, -1);
[3573]150  //NullParent* np = NullParent::getInstance();
[1855]151}
152
[3449]153/**
154   \brief creates a new World...
155   \param worldID with this ID
156*/
[2636]157World::World (int worldID)
158{
[4178]159  this->path = NULL;
160  this->constuctorInit(NULL, worldID);
[2636]161}
162
[1858]163/**
[2551]164    \brief remove the World from memory
[3365]165   
166    delete everything explicitly, that isn't contained in the parenting tree!
167    things contained in the tree are deleted automaticaly
[1858]168*/
[2190]169World::~World ()
[1872]170{
[3546]171  PRINTF(3)("World::~World() - deleting current world\n");
[3226]172  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
[3220]173  cn->unbind(this->localPlayer);
174  cn->reset();
[3677]175
[3620]176  delete WorldInterface::getInstance();
[3529]177  delete this->nullParent;
[3553]178  delete this->entities;
[3597]179  delete this->lightMan;
[3566]180  delete this->trackManager;
[4178]181  delete this->particleEngine;
[3790]182  TextEngine::getInstance()->flush();
[4183]183  delete PhysicsEngine::getInstance();
[3812]184  delete AnimationPlayer::getInstance(); // this should be at the end of the unloading sequence.
[3729]185  //delete garbagecollecor
186  //delete animator
[3790]187
[4283]188  LoadClassDescription::printAll();
189
[4178]190  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
[1872]191}
[1858]192
[3526]193/**
[3629]194   \brief initializes the world.
195
196   set all stuff here that is world generic and does not use to much memory
197   because the real init() function StoryEntity::init() will be called
198   shortly before start of the game. 
199   since all worlds are initiated/referenced before they will be started.
200   NO LEVEL LOADING HERE - NEVER!
[3526]201*/
[4178]202void World::constuctorInit(char* name, int worldID)
[3526]203{
[4332]204  this->setClassID(CL_WORLD, "World");
[2636]205
[4178]206  //this->worldName = name;
207  //this->worldName = new char[strlen(name)+1];
208  //strcpy(this->worldName, name);
[3526]209  this->debugWorldNr = worldID;
210  this->entities = new tList<WorldEntity>();
[4293]211 
212  State::getInstance();
[3629]213}
[3526]214
[4283]215void World::loadParams(const TiXmlElement* root)
216{
217  const char *string;
218  char *name;
219  int id;
[3629]220
[4283]221  PRINTF0("Creating a World\n");
222
223  LoadParam<World>(root, "identifier", this, &World::setStoryID)
224    .describe("Sets the StoryID of this world");
225  LoadParam<World>(root, "nextid", this, &World::setNextStoryID)
226    .describe("Sets the ID of the next world");
227  LoadParam<World>(root, "path", this, &World::setPath)
228    .describe("The Filename of this World (relative from the data-dir)");
229
230
231  /* 
232  // identifier
233  string = grabParameter( root, "identifier");
234  if( string == NULL || sscanf(string, "%d", &id) != 1)
235  {
236  PRINTF0("World is missing a proper 'identifier'\n");
237  this->setStoryID( -1);
238  }
239  else setStoryID( id);
240
241  // next id
242  string = grabParameter( root, "nextid");
243  if( string == NULL || sscanf(string, "%d", &id) != 1)
244  {
245  PRINTF0("World is missing a proper 'nextid'\n");
246  this->setStoryID( -1);
247  }
248  else setNextStoryID( id);
249 
250
251  // path
252  string = grabParameter( root, "path");
253  if( string == NULL)
254  {
255  PRINTF0("World is missing a proper 'path'\n");
256  this->setPath( NULL);
257  }
258  else
259  {
260  name = new char[strlen(string + 2)];
261  strcpy( name, string);
262  this->setPath( name);
263  }
264  */
265}
266
267
[3629]268/**
269   \brief this is executed before load
270
271   since the load function sometimes needs data, that has been init before
272   the load and after the proceeding storyentity has finished
273*/
274ErrorMessage World::preLoad()
275{
[3620]276  /* init the world interface */
277  WorldInterface* wi = WorldInterface::getInstance();
278  wi->init(this);
[3646]279  this->garbageCollector = GarbageCollector::getInstance();
[4178]280
281  this->particleEngine = ParticleEngine::getInstance();
282  this->trackManager = TrackManager::getInstance();
283  this->lightMan = LightManager::getInstance();
284  this->nullParent = NullParent::getInstance ();
285  this->nullParent->setName ("NullParent");
286
287  AnimationPlayer::getInstance(); // initializes the animationPlayer
[4183]288  PhysicsEngine::getInstance();
[4178]289
290  this->localCamera = new Camera();
[4332]291  this->localCamera->setName ("Camera");
[4293]292
293  State::getInstance()->setCamera(this->localCamera, this->localCamera->getTarget());
294
[4283]295  GraphicsEngine::getInstance()->displayFPS(true);
[3526]296}
297
298
[3449]299/**
300   \brief loads the World by initializing all resources, and set their default values.
301*/
[3459]302ErrorMessage World::load()
[4178]303{       
304  PRINTF(3)("> Loading world: '%s'\n", getPath());
305  TiXmlElement* element;
306  GameLoader* loader = GameLoader::getInstance();
307 
308  if( getPath() == NULL)
[2636]309    {
[4178]310      PRINTF(1)("World has no path specified for loading");
[4332]311      this->loadDebugWorld(this->getStoryID());
[4178]312      return (ErrorMessage){213,"Path not specified","World::load()"};
313    }
314 
315  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
316  // load the campaign document
317  if( !XMLDoc->LoadFile()) 
318  {
319    // report an error
320    PRINTF(1)("loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
321    delete XMLDoc;
322    return (ErrorMessage){213,"XML File parsing error","World::load()"};
323  }
324 
325  // check basic validity
326  TiXmlElement* root = XMLDoc->RootElement();
327  assert( root != NULL);
328 
329  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
330    {
331      // report an error
332      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
333      delete XMLDoc;
334      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
335    }
336 
337  // load the parameters
338  // name
339  char* temp;
340  const char* string = grabParameter( root, "name");
341  if( string == NULL)
342    {
343      PRINTF(2)("World is missing a proper 'name'\n");
344      string = "Unknown";
345      temp = new char[strlen(string + 2)];
346      strcpy( temp, string);
347      this->worldName = temp;
348    }
349  else
350    {
351      temp = new char[strlen(string + 2)];
352      strcpy( temp, string);
353      this->worldName = temp;
354    }
355  ////////////////
356  // LOADSCREEN //
357  ////////////////
358  element = root->FirstChildElement("LoadScreen");
359  if (element == NULL)
360    {
361      PRINTF(2)("no LoadScreen specified, loading default\n");
362
363      glmis->setBackgroundImage("pictures/load_screen.jpg");
364      this->glmis->setMaximum(8);
365      this->glmis->draw();
366    }
367  else
368    {
[4283]369      this->glmis->loadParams(element);
[4178]370      this->glmis->draw();
371    }
372  this->glmis->draw();
373  // find WorldEntities
374  element = root->FirstChildElement("WorldEntities");
375 
376  if( element == NULL)
377    {
378      PRINTF(1)("World is missing 'WorldEntities'\n");
379    }
380  else
381    {
382      element = element->FirstChildElement();
383      // load Players/Objects/Whatever
384      PRINTF(4)("Loading WorldEntities\n");
385      while( element != NULL)
386        {
387          WorldEntity* created = (WorldEntity*) loader->fabricate( element);
388          if( created != NULL) this->spawn( created);
389          // if we load a 'Player' we use it as localPlayer
390          //todo do this more elegant
391          if( element->Value() != NULL && !strcmp( element->Value(), "Player")) localPlayer = (Player*) created;
392          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
393          element = element->NextSiblingElement();
394          glmis->step(); //! \todo temporary
395        }
396      PRINTF(4)("Done loading WorldEntities\n");
397    }
398 
399  // find Track
[4223]400  element = root->FirstChildElement( "Track");
[4178]401  if( element == NULL)
402    {
[4283]403      PRINTF(0)("World is missing a 'Track'\n");
[4178]404    }
405  else
406    {   
407      //load track
[4283]408      PRINTF(4)("Loading Track\n");
[4178]409
[4223]410      trackManager->load( element);
[4178]411      trackManager->finalize();
[4223]412    }
[4178]413 
414  // free the XML data
415
416  delete XMLDoc;
417  /* GENERIC LOADING PROCESS FINISHED */
418 
419  // bind input
420  Orxonox *orx = Orxonox::getInstance ();
421  orx->getLocalInput()->bind (localPlayer);
422 
423  // bind camera
424  //this->localCamera->bind (localPlayer);
425  this->localPlayer->addChild (this->localCamera);
[3567]426     
427
[4178]428  lightMan->setAmbientColor(.1,.1,.1);
429  lightMan->addLight();
430  //      lightMan->setAttenuation(1.0, .01, 0.0);
431  //      lightMan->setDiffuseColor(1,1,1);
432  //  lightMan->addLight(1);
433  //  lightMan->setPosition(20, 10, -20);
434  //  lightMan->setDiffuseColor(0,0,0);
[4283]435  //lightMan->debug();
[4178]436  lightMan->setPosition(-5.0, 10.0, -40.0);
437 
438  //        trackManager->setBindSlave(env);
439  PNode* tn = trackManager->getTrackNode();
440  tn->addChild(this->localPlayer);
441 
442  //localCamera->setParent(TrackNode::getInstance());
443  tn->addChild(this->localCamera);
444  localCamera->lookAt(tn);
445  localCamera->setMode(PNODE_MOVEMENT);
446  this->localPlayer->setMode(PNODE_ALL);
447  Vector* cameraOffset = new Vector (0, 5, -10);
448  trackManager->condition(2, LEFTRIGHT, this->localPlayer);
449 
450  this->sky->setParent(this->localCamera);
[3368]451
[4178]452  // initialize debug coord system
453  objectList = glGenLists(1);
454  glNewList (objectList, GL_COMPILE);
455 
[4283]456  //trackManager->drawGraph(.01);
457  //trackManager->debug(2);
[4178]458  glEndList();
[3602]459
[4178]460  terrain = new Terrain("worlds/newGround.obj");
461  terrain->setRelCoor(Vector(0,-10,0));
462  this->spawn(terrain);
[3365]463
[3194]464
[4192]465  // Creating a Test Particle System
[4190]466  ParticleSystem* system = new ParticleSystem(100000, PARTICLE_SPRITE);
[4192]467  system->setLifeSpan(1);
468  system->setConserve(.8);
[4193]469  system->setRadius(4, 3, 1, 2);
470  system->setColor(.5,0,0,.5, 1,1,0,1, 0,0,0,0);
[3365]471
[4192]472  // Creating a Test Particle Emitter
[4190]473  ParticleEmitter* emitter = new ParticleEmitter(Vector(-1, 0, 0), M_PI_4, 400, .5);
[4314]474  emitter->setType(EMITTER_DOT);
[4274]475  emitter->setSize(20);
[4178]476  emitter->setParent(this->localPlayer);
[4192]477  emitter->setRelCoor(Vector(0,-3,0));
[4178]478 
[4192]479  // Add the Flow from the Emitter into the System
480  particleEngine->addConnection(emitter, system);
481
482
483  // Creating Some Fields
[4184]484  Field* twirl = new Twirl();
[4190]485  twirl->setMagnitude(.1);
[4184]486  Field* gravity = new PointGravity();
[4190]487  gravity->setMagnitude(.5);
[4192]488  twirl->setParent(this->localCamera->getTarget());
489  gravity->setParent(this->localCamera->getTarget());
490
491  //  new PhysicsConnection(system, twirl);
492  //    new PhysicsConnection(system, gravity);
493
[4283]494
495  WorldEntity* testEntity = new TestEntity();
496  //testEntity->setRelCoor(Vector(570, 10, -15));
497  testEntity->setRelCoor(Vector(25, -10, -20));
498  testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
499  this->spawn(testEntity);
500  this->localPlayer->addChild(testEntity);
[4178]501}
[3368]502
[4283]503
[4332]504
505/**
506   \brief loads the debug world: only for experimental stuff
507*/
[4178]508void World::loadDebugWorld(int worldID)
509{
[4332]510  printf("ajsdflkajs;dlfaj;slfja;lsjf;lajsf;la;sdfkja;lskdjfashdfklajshdflkjasdfh\n");
[4178]511  /*monitor progress*/
512  this->glmis->step();
[4283]513  // stuff beyond this point remains to be loaded properly
[4178]514
[4283]515  // initializing the TrackManager
516  this->trackManager = TrackManager::getInstance();
517  //trackManager->addPoint(Vector(0,0,0));
518  trackManager->addPoint(Vector(150, -35, 5));
519  trackManager->addPoint(Vector(200,-35, 5));
520  trackManager->addPoint(Vector(250, -35, 5));
521  trackManager->addPoint(Vector(320,-33,-.55));
522  trackManager->setDuration(1);
523  trackManager->setSavePoint();
524
525  trackManager->addPoint(Vector(410, 0, 0));
526  trackManager->addPoint(Vector(510, 20, -10));
527  trackManager->addPoint(Vector(550, 20, -10));
528  trackManager->addPoint(Vector(570, 20, -10));
529  trackManager->setDuration(2);
530     
531  trackManager->forkS("testFork1,testFork2");
532  trackManager->workOn("testFork1");
533  trackManager->addPoint(Vector(640, 25, -30));
534  trackManager->addPoint(Vector(700, 40, -120));
535  trackManager->addPoint(Vector(800, 50, -150));
536  trackManager->addPoint(Vector(900, 60, -100));
537  trackManager->addPoint(Vector(900, 60, -70));
538  trackManager->addPoint(Vector(990, 65, -15));
539  trackManager->addPoint(Vector(1050, 65, -10));
540  trackManager->addPoint(Vector(1100, 65, -20));
541  trackManager->setDuration(4);
542
543  trackManager->workOn("testFork2");
544  trackManager->addPoint(Vector(640, 25, 20));
545  trackManager->addPoint(Vector(670, 50, 120));
546  trackManager->addPoint(Vector(700, 70, 80));
547  trackManager->addPoint(Vector(800, 70, 65));
548  trackManager->addPoint(Vector(850, 65, 65));
549  trackManager->addPoint(Vector(920, 35, 40));
550  trackManager->addPoint(Vector(945, 40, 40));
551  trackManager->addPoint(Vector(970, 24, 40));
552  trackManager->addPoint(Vector(1000, 40, -7));
553  trackManager->setDuration(4);
554     
555     
556  trackManager->joinS("testFork1,testFork2");
557       
558  trackManager->addPoint(Vector(1200, 60, -50));
559  trackManager->addPoint(Vector(1300, 50, -50));
560  trackManager->addPoint(Vector(1400, 40, -50));
561  trackManager->addPoint(Vector(1500, 40, -60));
562  trackManager->addPoint(Vector(1600, 35, -55));
563  trackManager->addPoint(Vector(1700, 45, -40));
564  trackManager->addPoint(Vector(1750, 60, -40));
565  trackManager->addPoint(Vector(1770, 80, -40));
566  trackManager->addPoint(Vector(1800, 100, -40));
567  trackManager->setDuration(10);
568 
569  trackManager->finalize();
570 
571
[4178]572  // LIGHT initialisation
573  lightMan->setAmbientColor(.1,.1,.1);
574  lightMan->addLight();
575  lightMan->debug();
576
577  switch(this->debugWorldNr)
578    {
579      /*
580        this loads the hard-coded debug world. this only for simplicity and will be
581        removed by a reald world-loader, which interprets a world-file.
582        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
583        make whatever you want...
584      */
585    case DEBUG_WORLD_0:
586      {
587        lightMan->setPosition(-5.0, 10.0, -40.0);
588
589
590        this->localPlayer = new Player ();
591        this->localPlayer->setName ("player");
592        this->spawn (this->localPlayer);
593        /*monitor progress*/
594        this->glmis->step();
595
596        // bind camera
597        this->localCamera = new Camera();
598        this->localCamera->setName ("camera");
599        /*monitor progress*/
600        this->glmis->step();
[2816]601
[3419]602
[4332]603        // Create SkySphere
604        this->sky = new Skysphere("pictures/sky-replace.jpg");
605        this->sky->setName("SkySphere");
606        this->spawn(this->sky);
607        this->localCamera->addChild(this->sky);
608        this->sky->setMode(PNODE_MOVEMENT);
[4178]609        /*monitor progress*/
610        this->glmis->step();
[3368]611
[3521]612
[4332]613        terrain = new Terrain("worlds/newGround.obj");
614        terrain->setRelCoor(Vector(0,-10,0));
615        this->spawn(terrain);
[4178]616        /*monitor progress*/
617        this->glmis->step();
[2816]618
[4332]619        this->pilotNode = new PilotNode();
620        this->pilotNode->addChild(this->localPlayer);
621        this->pilotNode->addChild(this->localCamera);
622        // bind input
623        Orxonox *orx = Orxonox::getInstance ();
624        //orx->getLocalInput()->bind (this->pilotNode);     
625       
626        /*
[4178]627        PNode* tn = trackManager->getTrackNode();
628        tn->addChild(this->localPlayer);
629        this->localCamera->lookAt(tn);
[4332]630       
[4178]631        tn->addChild(this->localCamera);
632        this->localPlayer->setMode(PNODE_ALL);
633        trackManager->condition(2, LEFTRIGHT, this->localPlayer);
[4332]634        */
[4178]635        this->glmis->step();
636        break;
637      }
638    case DEBUG_WORLD_1:
639      {
[3365]640
[4178]641        break;
642      }
643    case DEBUG_WORLD_2:
644      {
[3727]645
[4178]646        break;
647      }
648    default:
[4332]649      break;
[2636]650    }
[4178]651}
[2636]652
[2731]653
[3526]654
[3459]655/**
[3629]656   \brief initializes a new World shortly before start
657
658   this is the function, that will be loaded shortly before the world is
659   started
[3459]660*/
661ErrorMessage World::init()
662{
663  this->bPause = false;
[4332]664  this->pilotNode = NULL;
[3459]665  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
666  cn->addToWorld(this);
667  cn->enable(true);
668}
669
670
671/**
672   \brief starts the World
673*/
674ErrorMessage World::start()
675{
[3546]676  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
[3459]677  this->bQuitOrxonox = false;
678  this->bQuitCurrentGame = false;
679  this->mainLoop();
680}
681
682/**
683   \brief stops the world.
684
685   This happens, when the player decides to end the Level.
686*/
687ErrorMessage World::stop()
688{
[3546]689  PRINTF(3)("World::stop() - got stop signal\n");
[3459]690  this->bQuitCurrentGame = true;
691}
692
693/**
694   \brief pauses the Game
695*/
696ErrorMessage World::pause()
697{
698  this->isPaused = true;
699}
700
701/**
702   \brief ends the pause Phase
703*/
704ErrorMessage World::resume()
705{
706  this->isPaused = false;
707}
708
709/**
710   \brief destroys the World
711*/
712ErrorMessage World::destroy()
713{
[3566]714
[3459]715}
716
717/**
718   \brief shows the loading screen
719*/
720void World::displayLoadScreen ()
721{
[3546]722  PRINTF(3)("World::displayLoadScreen - start\n"); 
[3459]723 
724  //GLMenuImageScreen*
[4178]725  this->glmis = new GLMenuImageScreen();
[3459]726  this->glmis->init();
[3675]727  this->glmis->setMaximum(8);
[4178]728  //  this->glmis->draw();
[3459]729 
[3546]730  PRINTF(3)("World::displayLoadScreen - end\n"); 
[3459]731}
732
733/**
734   \brief removes the loadscreen, and changes over to the game
735
736   \todo take out the delay
737*/
738void World::releaseLoadScreen ()
739{
[3546]740  PRINTF(3)("World::releaseLoadScreen - start\n"); 
[3459]741  this->glmis->setValue(this->glmis->getMaximum());
[3546]742  PRINTF(3)("World::releaseLoadScreen - end\n"); 
[4178]743  delete this->glmis;
[3459]744}
745
746
[3620]747/**
748   \brief gets the list of entities from the world
749   \returns entity list
750*/
751tList<WorldEntity>* World::getEntities()
752{
753  return this->entities;
754}
755
756
[3646]757/**
758   \brief this returns the current game time
759   \returns elapsed game time
760*/
761double World::getGameTime()
762{
763  return this->gameTime;
764}
765
766
[2636]767/**
[2551]768    \brief checks for collisions
769   
770    This method runs through all WorldEntities known to the world and checks for collisions
771    between them. In case of collisions the collide() method of the corresponding entities
772    is called.
[1858]773*/
[2190]774void World::collide ()
[1858]775{
[2816]776  /*
777  List *a, *b;
[2551]778  WorldEntity *aobj, *bobj;
[2816]779   
780  a = entities;
[2551]781 
782  while( a != NULL)
783    {
[2816]784      aobj = a->nextElement();
[2551]785      if( aobj->bCollide && aobj->collisioncluster != NULL)
[2190]786        {
[2816]787          b = a->nextElement();
[2551]788          while( b != NULL )
789            {
[2816]790              bobj = b->nextElement();
[2551]791              if( bobj->bCollide && bobj->collisioncluster != NULL )
[2190]792                {
[2551]793                  unsigned long ahitflg, bhitflg;
794                  if( check_collision ( &aobj->place, aobj->collisioncluster,
795                                        &ahitflg, &bobj->place, bobj->collisioncluster,
796                                        &bhitflg) );
797                  {
798                    aobj->collide (bobj, ahitflg, bhitflg);
799                    bobj->collide (aobj, bhitflg, ahitflg);
800                  }
[2190]801                }
[2816]802              b = b->nextElement();
[2551]803            }
[2190]804        }
[2816]805      a = a->enumerate();
[2551]806    }
[2816]807  */
[1858]808}
809
810/**
[2551]811    \brief runs through all entities calling their draw() methods
[1931]812*/
[2190]813void World::draw ()
[2077]814{
[3462]815  /* draw entities */
[2551]816  WorldEntity* entity;
[3526]817  glLoadIdentity();
818
[3653]819  //entity = this->entities->enumerate();
820  tIterator<WorldEntity>* iterator = this->entities->getIterator();
821  entity = iterator->nextElement();
[2816]822  while( entity != NULL ) 
[2551]823    { 
[2822]824      if( entity->bDraw ) entity->draw();
[3653]825      //entity = this->entities->nextElement();
826      entity = iterator->nextElement();
827    }
828  delete iterator;
[2551]829 
[2731]830  glCallList (objectList);
[3419]831
[3790]832  TextEngine::getInstance()->draw();
[4178]833  particleEngine->draw(this->dtS); //!< \todo should be dts like in the Trunk;
834
[3602]835  lightMan->draw(); // must be at the end of the drawing procedure, otherwise Light cannot be handled as PNodes //
[1931]836}
837
[2816]838
[2190]839/**
[3225]840   \brief function to put your own debug stuff into it. it can display informations about
841   the current class/procedure
842*/
[2640]843void World::debug()
844{
[3546]845  PRINTF(2)("debug() - starting debug\n");
[3365]846  PNode* p1 = NullParent::getInstance ();
[3809]847  PNode* p2 = new PNode (Vector(2, 2, 2), p1);
848  PNode* p3 = new PNode (Vector(4, 4, 4), p1);
849  PNode* p4 = new PNode (Vector(6, 6, 6), p2);
[3365]850
851  p1->debug ();
852  p2->debug ();
853  p3->debug ();
854  p4->debug ();
855
[3809]856  p1->shiftCoor (Vector(-1, -1, -1));
[3365]857
858  printf("World::debug() - shift\n");
859  p1->debug ();
860  p2->debug ();
861  p3->debug ();
862  p4->debug ();
863 
[3644]864  p1->update (0);
[3365]865
866  printf ("World::debug() - update\n");
867  p1->debug ();
868  p2->debug ();
869  p3->debug ();
870  p4->debug ();
871
[3809]872  p2->shiftCoor (Vector(-1, -1, -1));
[3644]873  p1->update (0);
[3365]874
875  p1->debug ();
876  p2->debug ();
877  p3->debug ();
878  p4->debug ();
879
[3809]880  p2->setAbsCoor (Vector(1,2,3));
[3365]881
882
[3644]883 p1->update (0);
[3365]884
885  p1->debug ();
886  p2->debug ();
887  p3->debug ();
888  p4->debug ();
889
[3544]890  delete p1;
[3365]891 
892 
893  /*
[2640]894  WorldEntity* entity;
895  printf("counting all entities\n");
[2816]896  printf("World::debug() - enumerate()\n");
897  entity = entities->enumerate(); 
898  while( entity != NULL )
[2640]899    {
900      if( entity->bDraw ) printf("got an entity\n");
[2816]901      entity = entities->nextElement();
[2640]902    }
[3365]903  */
[2640]904}
[2636]905
[2640]906
[3449]907/**
[3225]908  \brief main loop of the world: executing all world relevant function
909
910  in this loop we synchronize (if networked), handle input events, give the heart-beat to
911  all other member-entities of the world (tick to player, enemies etc.), checking for
912  collisions drawing everything to the screen.
913*/
[2636]914void World::mainLoop()
915{
[3365]916  this->lastFrame = SDL_GetTicks ();
[3546]917  PRINTF(3)("World::mainLoop() - Entering main loop\n");
[3215]918  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
[2551]919    {
[3546]920      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
[2636]921      // Network
[3365]922      this->synchronize ();
[2636]923      // Process input
[3365]924      this->handleInput ();
[3215]925      if( this->bQuitCurrentGame || this->bQuitOrxonox)
926          break;
[2636]927      // Process time
[3551]928      this->tick ();
929      // Update the state
[4178]930      this->update ();     
[2636]931      // Process collision
[3459]932      this->collide ();
[2636]933      // Draw
[3365]934      this->display ();
[3548]935
[3565]936      //      for( int i = 0; i < 5000000; i++) {}
[3365]937      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
[2551]938    }
[3546]939  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
[1899]940}
941
[3459]942
[2190]943/**
[2636]944   \brief synchronize local data with remote data
[1855]945*/
[2636]946void World::synchronize ()
[1855]947{
[2636]948  // Get remote input
949  // Update synchronizables
[1855]950}
[2636]951
[3459]952
[2636]953/**
954   \brief run all input processing
[3225]955
956   the command node is the central input event dispatcher. the node uses the even-queue from
957   sdl and has its own event-passing-queue.
[2636]958*/
[3225]959void World::handleInput ()
[2636]960{
961  // localinput
[3225]962  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
[3216]963  cn->process();
[2636]964  // remoteinput
965}
966
[3459]967
[2636]968/**
969   \brief advance the timeline
[3225]970
971   this calculates the time used to process one frame (with all input handling, drawing, etc)
972   the time is mesured in ms and passed to all world-entities and other classes that need
973   a heart-beat.
[2636]974*/
[3551]975void World::tick ()
[2636]976{
977  Uint32 currentFrame = SDL_GetTicks();
978  if(!this->bPause)
979    {
[3644]980      this->dt = currentFrame - this->lastFrame;
[2816]981     
[3646]982      if( this->dt > 0)
[2636]983        {
984          float fps = 1000/dt;
[3790]985
986          // temporary, only for showing how fast the text-engine is
987          char tmpChar[20];
988          sprintf(tmpChar, "fps: %4.0f", fps);
[2636]989        }
990      else
991        {
[3225]992          /* the frame-rate is limited to 100 frames per second, all other things are for
993             nothing.
994          */
[3546]995          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
[3194]996          SDL_Delay(10);
[3646]997          this->dt = 10;
[2636]998        }
[3459]999      //this->timeSlice (dt);
1000     
1001      /* function to let all entities tick (iterate through list) */
[4178]1002      this->dtS = (float)this->dt / 1000.0;     
1003      this->gameTime += this->dtS;
[3654]1004      //entity = entities->enumerate();
1005      tIterator<WorldEntity>* iterator = this->entities->getIterator();
1006      WorldEntity* entity = iterator->nextElement();
[3459]1007      while( entity != NULL) 
1008        { 
[4178]1009          entity->tick (this->dtS);
[3654]1010          entity = iterator->nextElement();
[3459]1011        }
[3654]1012      delete iterator;
[4178]1013
[3459]1014      /* update tick the rest */
[3646]1015      this->trackManager->tick(this->dt);
1016      this->localCamera->tick(this->dt);
[4283]1017      AnimationPlayer::getInstance()->tick(this->dtS);
[3851]1018
[4183]1019      PhysicsEngine::getInstance()->tick(this->dtS);
1020
[4178]1021      particleEngine->tick(this->dtS);
[4283]1022      this->garbageCollector->tick(this->dtS);
1023         
1024      /* actualy the Graphics Engine should tick the world not the other way around...
1025         but since we like the things not too complicated we got it this way around
1026         until there is need or time to do it the other way around.
1027         \todo: GraphicsEngine ticks world: separation of processes and data...
1028      */
1029      GraphicsEngine::getInstance()->tick(this->dtS);
[2636]1030    }
1031  this->lastFrame = currentFrame;
1032}
1033
[3216]1034
[2636]1035/**
[3551]1036   \brief this function gives the world a consistant state
1037
1038   after ticking (updating the world state) this will give a constistant
1039   state to the whole system.
1040*/
1041void World::update()
1042{
[3646]1043  this->garbageCollector->update();
[4178]1044  this->nullParent->update (this->dtS);
[3551]1045}
1046
1047
1048/**
[3225]1049   \brief render the current frame
1050   
1051   clear all buffers and draw the world
[2636]1052*/
1053void World::display ()
1054{
1055  // clear buffer
1056  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1057  // set camera
1058  this->localCamera->apply ();
1059  // draw world
1060  this->draw();
1061  // draw HUD
[3365]1062  /* \todo draw HUD */
[2636]1063  // flip buffers
1064  SDL_GL_SwapBuffers();
[3365]1065  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
1066  //SDL_Flip (screen);
[2636]1067}
1068
[2644]1069
[3225]1070/**
1071   \brief add and spawn a new entity to this world
1072   \param entity to be added
1073*/
[2644]1074void World::spawn(WorldEntity* entity)
1075{
[3365]1076  this->entities->add (entity);
[3233]1077  entity->postSpawn ();
[2816]1078}
1079
1080
[3225]1081/**
1082   \brief add and spawn a new entity to this world
1083   \param entity to be added
[3449]1084   \param absCoor At what coordinates to add this entity.
1085   \param absDir In which direction should it look.
[3225]1086*/
[3365]1087void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
[2816]1088{
[3529]1089  this->entities->add (entity);
1090
[3809]1091  entity->setAbsCoor (*absCoor);
1092  entity->setAbsDir (*absDir);
[3365]1093
[3233]1094  entity->postSpawn ();
[2644]1095}
[2816]1096
1097
[3521]1098/**
1099   \brief add and spawn a new entity to this world
1100   \param entity to be added
1101   \param entity to be added to (PNode)
1102   \param At what relative  coordinates to add this entity.
1103   \param In which relative direction should it look.
1104*/
1105void World::spawn(WorldEntity* entity, PNode* parentNode, 
1106                  Vector* relCoor, Quaternion* relDir, 
[3565]1107                  int parentingMode)
[3521]1108{
[3551]1109  this->nullParent = NullParent::getInstance();
[3529]1110  if( parentNode != NULL)
[3521]1111    {
1112      parentNode->addChild (entity);
1113     
[3809]1114      entity->setRelCoor (*relCoor);
1115      entity->setRelDir (*relDir);
[3586]1116      entity->setMode(parentingMode);
[3521]1117     
1118      this->entities->add (entity);
1119     
1120      entity->postSpawn ();
1121    }
1122}
1123
1124
1125
[3449]1126/**
[3225]1127  \brief commands that the world must catch
1128  \returns false if not used by the world
1129*/
[3216]1130bool World::command(Command* cmd)
1131{
[4178]1132  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1133  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1134  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1135  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1136  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1137  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
[4332]1138  else if(this->pilotNode != NULL) if( !strcmp( cmd->cmd, "cursor")) this->pilotNode->command(cmd);
[3216]1139  return false;
1140}
[3365]1141
[4178]1142void World::setPath( const char* name)
1143{
1144  if (this->path)
1145    delete this->path;
1146  if (ResourceManager::isFile(name))
1147  {
1148    this->path = new char[strlen(name)+1];
1149    strcpy(this->path, name);
1150  }
1151  else
1152    {
1153      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1154      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1155    }
1156}
1157
1158const char* World::getPath( void)
1159{
1160  return path;
1161}
Note: See TracBrowser for help on using the repository browser.