Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: resized the stoned stones

File size: 33.4 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
[4720]470  //trackManager->drawGraph(.01);
[4245]471  //trackManager->debug(2);
[4010]472  glEndList();
[3993]473
[4504]474  SoundEngine::getInstance()->setListener(this->localCamera);
[4176]475
[4347]476
[4709]477
[4715]478
479  ////////////
480  // STATIC //
481  ////////////
482
483  Field* gravity = new Gravity();
484  gravity->setMagnitude(30.0);
485
[4709]486  // SYSTEM OF THE VULCANO
[4713]487  ParticleSystem* vulcanSysFog = new ParticleSystem(10000, PARTICLE_SPRITE);
[4715]488  vulcanSysFog->setLifeSpan(5, 2);
489  vulcanSysFog->setRadius(0.0, 20.0, 10);
490  vulcanSysFog->setRadius(.2, 50, 30);
491  vulcanSysFog->setRadius(1.0, 200, 100);
[4709]492  vulcanSysFog->setMass (0.0, 1.0);
493  vulcanSysFog->setColor(0, 1, 1, 1, .5);
[4715]494  vulcanSysFog->setColor(.5, .6, .6, .6, .2);
[4713]495  vulcanSysFog->setColor(1, .0, .0, .0, 0);
[4709]496
[4715]497  ParticleEmitter* vulcanEmitFog = new ParticleEmitter(Vector(0,1,0), .5, 200, 150);
498  vulcanEmitFog->setEmissionVelocity(150, 50);
[4709]499  vulcanEmitFog->setType(EMITTER_CUBE);
500  vulcanEmitFog->setSize(40);
501  vulcanEmitFog->setRelCoor(2460,105, 606);
502  ParticleEngine::getInstance()->addConnection(vulcanEmitFog, vulcanSysFog);
503
[4716]504
[4720]505  ParticleSystem* vulcanSysStone = new ParticleSystem(1000, PARTICLE_SPRITE);
506  vulcanSysStone->setModel("models/vulcanic_stone.obj");
507  vulcanSysStone->setLifeSpan(6);
508  vulcanSysStone->setRadius(0.0, 5.0, 3.0);
509  vulcanSysStone->setMass (0.0, .1);
510
511  ParticleEmitter* vulcanEmitStone = new ParticleEmitter(Vector(0,1,0), .5, 10, 200);
512  vulcanEmitStone->setEmissionVelocity(700, 400);
513  vulcanEmitStone->setType(EMITTER_CUBE);
514  vulcanEmitStone->setSize(40);
515  vulcanEmitStone->setRelCoor(2460,105, 606);
516
517  ParticleEngine::getInstance()->addConnection(vulcanEmitStone, vulcanSysStone);
518  new PhysicsConnection(vulcanSysStone, gravity);
519
[4716]520  // SYSTEM OF THE VULCANO
521  ParticleSystem* vulcanSysSpark = new ParticleSystem(10000, PARTICLE_SPARK);
522  vulcanSysSpark->setLifeSpan(5, 2);
523  vulcanSysSpark->setRadius(0.0, .2, .1);
524  vulcanSysSpark->setRadius(.2, .1, .1);
525  vulcanSysSpark->setRadius(1.0, 0, 0);
526  vulcanSysSpark->setMass (0.0, .1);
527  vulcanSysSpark->setColor(0, 1.0, .0, .0, .3);
528  vulcanSysSpark->setColor(.5, 1.0, 1.0, .0, .2);
529  vulcanSysSpark->setColor(1, .0, .0, .0, 0);
530
531  ParticleEmitter* vulcanEmitSpark = new ParticleEmitter(Vector(0,1,0), .5, 100, 150);
532  vulcanEmitSpark->setEmissionVelocity(500, 500);
533  vulcanEmitSpark->setType(EMITTER_CUBE);
534  vulcanEmitSpark->setSize(40);
535  vulcanEmitSpark->setRelCoor(2460,105, 606);
536  ParticleEngine::getInstance()->addConnection(vulcanEmitSpark, vulcanSysSpark);
537  new PhysicsConnection(vulcanSysSpark, gravity);
538
539
540
[4709]541  // SYSTEM TRAILING THE PLAYER
[4347]542  // Creating a Test Particle System
[4709]543  ParticleSystem* system = new ParticleSystem(5000, PARTICLE_SPRITE);
[4431]544  system->setLifeSpan(.5);
[4347]545  system->setConserve(.8);
[4434]546  system->setRadius(0.0, 1.0, .8);
547  system->setRadius(.2, 3, 2.0);
[4430]548  system->setRadius(1.0, 0.0, .0);
[4431]549  system->setMass (0.0, 1.0);
[4664]550  //system->setModel(ResourceManager::getFullName("models/orx-rocket.obj"));
[4430]551
[4654]552  system->setColor(0, .5, 0, 0, 1);
553  system->setColor(.5, 1, 1, 0, .01);
554  system->setColor(1.0, 0, 0, 0, 0);
[4347]555
[4555]556
[4347]557  // Creating a Test Particle Emitter
[4664]558  ParticleEmitter* emitter = new ParticleEmitter(Vector(-1, 0, 0), M_PI_4, 400, .5);
[4347]559  emitter->setType(EMITTER_DOT);
560  emitter->setSize(20);
561  emitter->setParent(this->localPlayer);
562  emitter->setRelCoor(Vector(-3,0,0));
[4396]563
[4555]564
[4347]565  // Add the Flow from the Emitter into the System
566  particleEngine->addConnection(emitter, system);
567
[4396]568  new PhysicsConnection(system, gravity);
[4397]569  //    new PhysicsConnection(this->localPlayer, gravity);
[4347]570
[4397]571  TestEntity* testEntity = new TestEntity();
572  testEntity->setRelCoor(Vector(570, 10, -15));
[4245]573  testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
574  this->spawn(testEntity);
[4397]575
[4488]576  TestEntity* testEntity2 = new TestEntity();
577  testEntity2->setAnim(RUN);
578  testEntity2->setRelCoor(Vector(570, 30, 15));
579  testEntity2->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
580  this->spawn(testEntity2);
581
582
[4397]583  new PhysicsConnection(testEntity, gravity);
[4574]584
[4592]585  // printing out some debug stuff
[4574]586  NullParent::getInstance()->debug(0);
[4592]587  this->localPlayer->whatIs();
588  this->whatIs();
[4596]589  GraphicsEngine::getInstance()->whatIs();
[4010]590}
[3365]591
[4245]592
[4324]593
[4326]594/**
595   \brief loads the debug world: only for experimental stuff
596*/
[4010]597void World::loadDebugWorld(int worldID)
598{
599  /*monitor progress*/
600  this->glmis->step();
[4228]601  // stuff beyond this point remains to be loaded properly
[3194]602
[4228]603  // initializing the TrackManager
604  this->trackManager = TrackManager::getInstance();
[4496]605  //trackManager->addPointV(Vector(0,0,0));
606  trackManager->addPointV(Vector(150, -35, 5));
607  trackManager->addPointV(Vector(200,-35, 5));
608  trackManager->addPointV(Vector(250, -35, 5));
609  trackManager->addPointV(Vector(320,-33,-.55));
[4228]610  trackManager->setDuration(1);
611  trackManager->setSavePoint();
612
[4496]613  trackManager->addPointV(Vector(410, 0, 0));
614  trackManager->addPointV(Vector(510, 20, -10));
615  trackManager->addPointV(Vector(550, 20, -10));
616  trackManager->addPointV(Vector(570, 20, -10));
[4228]617  trackManager->setDuration(2);
[4555]618
[4228]619  trackManager->forkS("testFork1,testFork2");
[4501]620  trackManager->workOnS("testFork1");
[4496]621  trackManager->addPointV(Vector(640, 25, -30));
622  trackManager->addPointV(Vector(700, 40, -120));
623  trackManager->addPointV(Vector(800, 50, -150));
624  trackManager->addPointV(Vector(900, 60, -100));
625  trackManager->addPointV(Vector(900, 60, -70));
626  trackManager->addPointV(Vector(990, 65, -15));
627  trackManager->addPointV(Vector(1050, 65, -10));
628  trackManager->addPointV(Vector(1100, 65, -20));
[4228]629  trackManager->setDuration(4);
630
[4501]631  trackManager->workOnS("testFork2");
[4496]632  trackManager->addPointV(Vector(640, 25, 20));
633  trackManager->addPointV(Vector(670, 50, 120));
634  trackManager->addPointV(Vector(700, 70, 80));
635  trackManager->addPointV(Vector(800, 70, 65));
636  trackManager->addPointV(Vector(850, 65, 65));
637  trackManager->addPointV(Vector(920, 35, 40));
638  trackManager->addPointV(Vector(945, 40, 40));
639  trackManager->addPointV(Vector(970, 24, 40));
640  trackManager->addPointV(Vector(1000, 40, -7));
[4508]641
[4228]642  trackManager->setDuration(4);
[4555]643
644
[4228]645  trackManager->joinS("testFork1,testFork2");
[4555]646
[4496]647  trackManager->addPointV(Vector(1200, 60, -50));
648  trackManager->addPointV(Vector(1300, 50, -50));
649  trackManager->addPointV(Vector(1400, 40, -50));
650  trackManager->addPointV(Vector(1500, 40, -60));
651  trackManager->addPointV(Vector(1600, 35, -55));
652  trackManager->addPointV(Vector(1700, 45, -40));
653  trackManager->addPointV(Vector(1750, 60, -40));
654  trackManager->addPointV(Vector(1770, 80, -40));
655  trackManager->addPointV(Vector(1800, 100, -40));
[4228]656  trackManager->setDuration(10);
[4555]657
[4228]658  trackManager->finalize();
659
[4555]660
[4010]661  // LIGHT initialisation
662  lightMan->setAmbientColor(.1,.1,.1);
663  lightMan->addLight();
664  lightMan->debug();
[3368]665
[4010]666  switch(this->debugWorldNr)
667    {
668      /*
[4555]669        this loads the hard-coded debug world. this only for simplicity and will be
670        removed by a reald world-loader, which interprets a world-file.
671        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
672        make whatever you want...
[4010]673      */
674    case DEBUG_WORLD_0:
675      {
[4555]676        lightMan->setPosition(-5.0, 10.0, -40.0);
[4010]677
678
[4555]679        this->localPlayer = new Player ();
680        this->localPlayer->setName ("player");
681        this->spawn (this->localPlayer);
682        this->localPlayer->setRelCoor(Vector(5,0,0));
683        /*monitor progress*/
684        this->glmis->step();
[4010]685
[4418]686
[4555]687        this->eventHandler->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
688        this->eventHandler->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
689        this->eventHandler->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
[4418]690
[4555]691        /*
692        Field* testField = new Gravity();
693        testField->setMagnitude(10);
694        new PhysicsConnection(this->localPlayer, testField);
695        */
[4397]696
[4555]697        // bind camera
698        this->localCamera = new Camera();
699        this->localCamera->setName ("camera");
700        /*monitor progress*/
701        this->glmis->step();
[2816]702
[3419]703
[4555]704        // Create SkySphere
[4621]705        this->sky = new Skysphere("pictures/sky-replace.jpg");
706        this->sky->setName("SkySphere");
707        this->spawn(this->sky);
[4555]708        this->localCamera->addChild(this->sky);
709        this->sky->setParentMode(PNODE_MOVEMENT);
710        /*monitor progress*/
711        this->glmis->step();
[3368]712
[3521]713
[4555]714        terrain = new Terrain("worlds/newGround.obj");
715        terrain->setRelCoor(Vector(0,-10,0));
716        this->spawn(terrain);
717        /*monitor progress*/
718        this->glmis->step();
[2816]719
[4555]720        this->pilotNode = new PilotNode();
721        this->spawn(this->pilotNode);
722        this->pilotNode->setAbsCoor(Vector(150, -35, 5));
723        this->pilotNode->addChild(this->localPlayer);
724        this->pilotNode->addChild(this->localCamera);
725        this->localCamera->lookAt(this->localPlayer);
[4422]726
[4555]727        this->eventHandler->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_UP);
728        this->eventHandler->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_DOWN);
729        this->eventHandler->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_LEFT);
730        this->eventHandler->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_RIGHT);
731        this->eventHandler->subscribe(this->pilotNode, ES_GAME, EV_MOUSE_MOTION);
[4422]732
[4555]733        // bind input
734        Orxonox *orx = Orxonox::getInstance ();
735        //orx->getLocalInput()->bind (this->pilotNode);
736
737        /*
738        PNode* tn = trackManager->getTrackNode();
739        tn->addChild(this->localPlayer);
740        this->localCamera->lookAt(tn);
741
742        tn->addChild(this->localCamera);
743        this->localPlayer->setParentMode(PNODE_ALL);
744        trackManager->condition(2, LEFTRIGHT, this->localPlayer);
745        */
746        this->glmis->step();
747        break;
[4010]748      }
749    case DEBUG_WORLD_1:
750      {
[3365]751
[4555]752        break;
[4010]753      }
754    case DEBUG_WORLD_2:
755      {
[3727]756
[4555]757        break;
[4010]758      }
759    default:
[4324]760      break;
[2636]761    }
[4010]762}
[2636]763
[2731]764
[3526]765
[3459]766/**
[3629]767   \brief initializes a new World shortly before start
768
[4555]769   this is the function, that will be loaded shortly before the world is
[3629]770   started
[3459]771*/
772ErrorMessage World::init()
773{
774  this->bPause = false;
[4326]775  this->pilotNode = NULL;
[3459]776}
777
778
779/**
780   \brief starts the World
781*/
782ErrorMessage World::start()
783{
[3546]784  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
[3459]785  this->bQuitOrxonox = false;
786  this->bQuitCurrentGame = false;
787  this->mainLoop();
788}
789
790/**
791   \brief stops the world.
792
793   This happens, when the player decides to end the Level.
794*/
795ErrorMessage World::stop()
796{
[3546]797  PRINTF(3)("World::stop() - got stop signal\n");
[3459]798  this->bQuitCurrentGame = true;
799}
800
801/**
802   \brief pauses the Game
803*/
804ErrorMessage World::pause()
805{
806  this->isPaused = true;
807}
808
809/**
810   \brief ends the pause Phase
811*/
812ErrorMessage World::resume()
813{
814  this->isPaused = false;
815}
816
817/**
818   \brief destroys the World
819*/
820ErrorMessage World::destroy()
821{
[3566]822
[3459]823}
824
825/**
826   \brief shows the loading screen
827*/
828void World::displayLoadScreen ()
829{
[4555]830  PRINTF(3)("World::displayLoadScreen - start\n");
831
832  //GLMenuImageScreen*
[4099]833  this->glmis = new GLMenuImageScreen();
[3675]834  this->glmis->setMaximum(8);
[4555]835
836  PRINTF(3)("World::displayLoadScreen - end\n");
[3459]837}
838
839/**
840   \brief removes the loadscreen, and changes over to the game
841
842   \todo take out the delay
843*/
844void World::releaseLoadScreen ()
845{
[4555]846  PRINTF(3)("World::releaseLoadScreen - start\n");
[3459]847  this->glmis->setValue(this->glmis->getMaximum());
[4555]848  PRINTF(3)("World::releaseLoadScreen - end\n");
[4099]849  delete this->glmis;
[3459]850}
851
852
[3620]853/**
854   \brief gets the list of entities from the world
855   \returns entity list
856*/
857tList<WorldEntity>* World::getEntities()
858{
859  return this->entities;
860}
861
862
[3646]863/**
864   \brief this returns the current game time
865   \returns elapsed game time
866*/
867double World::getGameTime()
868{
869  return this->gameTime;
870}
871
872
[4555]873/**
[2551]874    \brief checks for collisions
[4555]875
876    This method runs through all WorldEntities known to the world and checks for collisions
877    between them. In case of collisions the collide() method of the corresponding entities
[2551]878    is called.
[1858]879*/
[2190]880void World::collide ()
[1858]881{
[2816]882  /*
883  List *a, *b;
[2551]884  WorldEntity *aobj, *bobj;
[4555]885
[2816]886  a = entities;
[4555]887
[2551]888  while( a != NULL)
889    {
[2816]890      aobj = a->nextElement();
[2551]891      if( aobj->bCollide && aobj->collisioncluster != NULL)
[4555]892        {
893          b = a->nextElement();
894          while( b != NULL )
895            {
896              bobj = b->nextElement();
897              if( bobj->bCollide && bobj->collisioncluster != NULL )
898                {
899                  unsigned long ahitflg, bhitflg;
900                  if( check_collision ( &aobj->place, aobj->collisioncluster,
901                                        &ahitflg, &bobj->place, bobj->collisioncluster,
902                                        &bhitflg) );
903                  {
904                    aobj->collide (bobj, ahitflg, bhitflg);
905                    bobj->collide (aobj, bhitflg, ahitflg);
906                  }
907                }
908              b = b->nextElement();
909            }
910        }
[2816]911      a = a->enumerate();
[2551]912    }
[2816]913  */
[1858]914}
915
[4555]916/**
[2551]917    \brief runs through all entities calling their draw() methods
[1931]918*/
[2190]919void World::draw ()
[2077]920{
[3462]921  /* draw entities */
[2551]922  WorldEntity* entity;
[3526]923  glLoadIdentity();
[3653]924  //entity = this->entities->enumerate();
925  tIterator<WorldEntity>* iterator = this->entities->getIterator();
926  entity = iterator->nextElement();
[4555]927  while( entity != NULL )
928    {
[2822]929      if( entity->bDraw ) entity->draw();
[3653]930      //entity = this->entities->nextElement();
931      entity = iterator->nextElement();
932    }
933  delete iterator;
[4555]934
[2731]935  glCallList (objectList);
[3419]936
[4349]937  particleEngine->draw(); //!< \todo should be dts like in the Trunk;
[4176]938
[4518]939  TextEngine::getInstance()->draw();
[3602]940  lightMan->draw(); // must be at the end of the drawing procedure, otherwise Light cannot be handled as PNodes //
[1931]941}
942
[2816]943
[2190]944/**
[3225]945   \brief function to put your own debug stuff into it. it can display informations about
946   the current class/procedure
947*/
[2640]948void World::debug()
949{
[3546]950  PRINTF(2)("debug() - starting debug\n");
[3365]951  PNode* p1 = NullParent::getInstance ();
[3809]952  PNode* p2 = new PNode (Vector(2, 2, 2), p1);
953  PNode* p3 = new PNode (Vector(4, 4, 4), p1);
954  PNode* p4 = new PNode (Vector(6, 6, 6), p2);
[3365]955
956  p1->debug ();
957  p2->debug ();
958  p3->debug ();
959  p4->debug ();
960
[3809]961  p1->shiftCoor (Vector(-1, -1, -1));
[3365]962
963  printf("World::debug() - shift\n");
964  p1->debug ();
965  p2->debug ();
966  p3->debug ();
967  p4->debug ();
[4555]968
[3644]969  p1->update (0);
[3365]970
971  printf ("World::debug() - update\n");
972  p1->debug ();
973  p2->debug ();
974  p3->debug ();
975  p4->debug ();
976
[3809]977  p2->shiftCoor (Vector(-1, -1, -1));
[3644]978  p1->update (0);
[3365]979
980  p1->debug ();
981  p2->debug ();
982  p3->debug ();
983  p4->debug ();
984
[3809]985  p2->setAbsCoor (Vector(1,2,3));
[3365]986
987
[3644]988 p1->update (0);
[3365]989
990  p1->debug ();
991  p2->debug ();
992  p3->debug ();
993  p4->debug ();
994
[3544]995  delete p1;
[4555]996
997
[3365]998  /*
[2640]999  WorldEntity* entity;
1000  printf("counting all entities\n");
[2816]1001  printf("World::debug() - enumerate()\n");
[4555]1002  entity = entities->enumerate();
1003  while( entity != NULL )
1004    {
[2640]1005      if( entity->bDraw ) printf("got an entity\n");
[2816]1006      entity = entities->nextElement();
[2640]1007    }
[3365]1008  */
[2640]1009}
[2636]1010
[2640]1011
[3449]1012/**
[3225]1013  \brief main loop of the world: executing all world relevant function
1014
1015  in this loop we synchronize (if networked), handle input events, give the heart-beat to
1016  all other member-entities of the world (tick to player, enemies etc.), checking for
1017  collisions drawing everything to the screen.
1018*/
[2636]1019void World::mainLoop()
1020{
[3365]1021  this->lastFrame = SDL_GetTicks ();
[3546]1022  PRINTF(3)("World::mainLoop() - Entering main loop\n");
[3215]1023  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
[2551]1024    {
[4558]1025      ++this->cycle;
[3546]1026      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
[2636]1027      // Network
[3365]1028      this->synchronize ();
[2636]1029      // Process input
[3365]1030      this->handleInput ();
[3215]1031      if( this->bQuitCurrentGame || this->bQuitOrxonox)
[4555]1032          break;
[2636]1033      // Process time
[3551]1034      this->tick ();
1035      // Update the state
[4555]1036      this->update ();
[2636]1037      // Process collision
[3459]1038      this->collide ();
[2636]1039      // Draw
[3365]1040      this->display ();
[3548]1041
[3565]1042      //      for( int i = 0; i < 5000000; i++) {}
[3365]1043      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
[2551]1044    }
[3546]1045  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
[1899]1046}
1047
[3459]1048
[2190]1049/**
[2636]1050   \brief synchronize local data with remote data
[1855]1051*/
[2636]1052void World::synchronize ()
[1855]1053{
[2636]1054  // Get remote input
1055  // Update synchronizables
[1855]1056}
[2636]1057
[3459]1058
[2636]1059/**
1060   \brief run all input processing
[3225]1061
1062   the command node is the central input event dispatcher. the node uses the even-queue from
1063   sdl and has its own event-passing-queue.
[2636]1064*/
[3225]1065void World::handleInput ()
[2636]1066{
1067  // localinput
[4407]1068  //CommandNode* cn = Orxonox::getInstance()->getLocalInput();
1069  //cn->process();
1070
1071  EventHandler::getInstance()->process();
1072
[2636]1073  // remoteinput
1074}
1075
[3459]1076
[2636]1077/**
1078   \brief advance the timeline
[3225]1079
1080   this calculates the time used to process one frame (with all input handling, drawing, etc)
1081   the time is mesured in ms and passed to all world-entities and other classes that need
1082   a heart-beat.
[2636]1083*/
[3551]1084void World::tick ()
[2636]1085{
1086  Uint32 currentFrame = SDL_GetTicks();
1087  if(!this->bPause)
1088    {
[3644]1089      this->dt = currentFrame - this->lastFrame;
[4555]1090
[4610]1091      if( this->dt > 10)
[4555]1092        {
1093          float fps = 1000/dt;
[3790]1094
[4555]1095          // temporary, only for showing how fast the text-engine is
1096          char tmpChar[20];
1097          sprintf(tmpChar, "fps: %4.0f", fps);
1098        }
[2636]1099      else
[4555]1100        {
1101          /* the frame-rate is limited to 100 frames per second, all other things are for
1102             nothing.
1103          */
1104          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
[4610]1105          SDL_Delay(10-dt);
[4555]1106          this->dt = 10;
1107        }
1108
1109      this->dtS = (float)this->dt / 1000.0;
[4145]1110      this->gameTime += this->dtS;
[4555]1111      //entity = entities->enumerate();
[3654]1112      tIterator<WorldEntity>* iterator = this->entities->getIterator();
1113      WorldEntity* entity = iterator->nextElement();
[4555]1114      while( entity != NULL)
1115        {
1116          entity->tick (this->dtS);
1117          entity = iterator->nextElement();
1118        }
[3654]1119      delete iterator;
[4010]1120
[3459]1121      /* update tick the rest */
[3646]1122      this->trackManager->tick(this->dt);
1123      this->localCamera->tick(this->dt);
[4558]1124      // tick the engines
[4245]1125      AnimationPlayer::getInstance()->tick(this->dtS);
[4558]1126      if (this->cycle > 5)
1127        PhysicsEngine::getInstance()->tick(this->dtS);
[4396]1128
[4558]1129      ParticleEngine::getInstance()->tick(this->dtS);
1130      GarbageCollector::getInstance()->tick(this->dtS);
[4396]1131
[4558]1132      /** actualy the Graphics Engine should tick the world not the other way around...
[4555]1133         but since we like the things not too complicated we got it this way around
1134         until there is need or time to do it the other way around.
1135         \todo: GraphicsEngine ticks world: separation of processes and data...
[4681]1136
1137        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
1138         beceause graphics have nothing(or at least not much) to do with Motion.
[4245]1139      */
1140      GraphicsEngine::getInstance()->tick(this->dtS);
[2636]1141    }
1142  this->lastFrame = currentFrame;
1143}
1144
[3216]1145
[2636]1146/**
[3551]1147   \brief this function gives the world a consistant state
1148
1149   after ticking (updating the world state) this will give a constistant
1150   state to the whole system.
1151*/
1152void World::update()
1153{
[3646]1154  this->garbageCollector->update();
[4145]1155  this->nullParent->update (this->dtS);
[4504]1156
1157  SoundEngine::getInstance()->update();
[3551]1158}
1159
1160
1161/**
[3225]1162   \brief render the current frame
[4555]1163
[3225]1164   clear all buffers and draw the world
[2636]1165*/
1166void World::display ()
1167{
1168  // clear buffer
1169  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1170  // set camera
1171  this->localCamera->apply ();
1172  // draw world
1173  this->draw();
1174  // draw HUD
[3365]1175  /* \todo draw HUD */
[2636]1176  // flip buffers
[4681]1177  GraphicsEngine::swapBuffers();
[3365]1178  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
1179  //SDL_Flip (screen);
[2636]1180}
1181
[2644]1182
[3225]1183/**
1184   \brief add and spawn a new entity to this world
1185   \param entity to be added
1186*/
[2644]1187void World::spawn(WorldEntity* entity)
1188{
[3365]1189  this->entities->add (entity);
[3233]1190  entity->postSpawn ();
[2816]1191}
1192
1193
[3225]1194/**
1195   \brief add and spawn a new entity to this world
1196   \param entity to be added
[3449]1197   \param absCoor At what coordinates to add this entity.
1198   \param absDir In which direction should it look.
[3225]1199*/
[3365]1200void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
[2816]1201{
[3529]1202  this->entities->add (entity);
1203
[3809]1204  entity->setAbsCoor (*absCoor);
1205  entity->setAbsDir (*absDir);
[3365]1206
[3233]1207  entity->postSpawn ();
[2644]1208}
[2816]1209
1210
[3521]1211/**
1212   \brief add and spawn a new entity to this world
1213   \param entity to be added
1214   \param entity to be added to (PNode)
1215   \param At what relative  coordinates to add this entity.
1216   \param In which relative direction should it look.
1217*/
[4555]1218void World::spawn(WorldEntity* entity, PNode* parentNode,
1219                  Vector* relCoor, Quaternion* relDir,
1220                  int parentingMode)
[3521]1221{
[3551]1222  this->nullParent = NullParent::getInstance();
[3529]1223  if( parentNode != NULL)
[3521]1224    {
1225      parentNode->addChild (entity);
[4555]1226
[3809]1227      entity->setRelCoor (*relCoor);
1228      entity->setRelDir (*relDir);
[4444]1229      entity->setParentMode(parentingMode);
[4555]1230
[3521]1231      this->entities->add (entity);
[4555]1232
[3521]1233      entity->postSpawn ();
1234    }
1235}
1236
1237
1238
[3449]1239/**
[3225]1240  \brief commands that the world must catch
1241  \returns false if not used by the world
1242*/
[3216]1243bool World::command(Command* cmd)
1244{
[4091]1245  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1246  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1247  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1248  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1249  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1250  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
[3216]1251  return false;
1252}
[3365]1253
[4010]1254void World::setPath( const char* name)
1255{
[4094]1256  if (this->path)
1257    delete this->path;
1258  if (ResourceManager::isFile(name))
1259  {
1260    this->path = new char[strlen(name)+1];
1261    strcpy(this->path, name);
1262  }
1263  else
1264    {
1265      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1266      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1267    }
[4010]1268}
1269
1270const char* World::getPath( void)
1271{
1272  return path;
1273}
Note: See TracBrowser for help on using the repository browser.