Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: flush the state

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