Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: fight against the mighty segfault

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