Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Shaders now work :)

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