Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/physics/src/story_entities/world.cc @ 4223

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

orxonox/branches/physics: merged back the Trunk into the Physics-branche
merged with command:
svn merge -r 4178:HEAD ../trunk/ physics
no conflicts in relevant files

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