Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: better check for SDL (on linux)

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