Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: ParticleEngine now has a draw-function, that makes sense

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