Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/physics: reimplemented the lifeTime function of particles (a little bit slower, but much more efficient)
Color also implemented with the new TimeCode

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->loadTrack( 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(2);
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(5);
413     
414      int fork11, fork12;
415      trackManager->fork(2, &fork11, &fork12);
416      trackManager->workOn(fork11);
417      trackManager->addPoint(Vector(640, 25, -30));
418      trackManager->addPoint(Vector(700, 40, -120));
419      trackManager->addPoint(Vector(800, 50, -150));
420      trackManager->addPoint(Vector(900, 60, -100));
421      trackManager->addPoint(Vector(900, 60, -70));
422      trackManager->addPoint(Vector(990, 65, -15));
423      trackManager->addPoint(Vector(1050, 65, -10));
424      trackManager->addPoint(Vector(1100, 65, -20));
425      trackManager->setDuration(10);
426
427      trackManager->workOn(fork12);
428      trackManager->addPoint(Vector(640, 25, 20));
429      trackManager->addPoint(Vector(670, 50, 120));
430      trackManager->addPoint(Vector(700, 70, 80));
431      trackManager->addPoint(Vector(800, 70, 65));
432      trackManager->addPoint(Vector(850, 65, 65));
433      trackManager->addPoint(Vector(920, 35, 40));
434      trackManager->addPoint(Vector(945, 40, 40));
435      trackManager->addPoint(Vector(970, 24, 40));
436      trackManager->addPoint(Vector(1000, 40, -7));
437      trackManager->setDuration(10);
438     
439
440      trackManager->join(2, fork11, fork12);
441
442      trackManager->workOn(5);
443      trackManager->addPoint(Vector(1200, 60, -50));
444      trackManager->addPoint(Vector(1300, 50, -50));
445      trackManager->addPoint(Vector(1400, 40, -50));
446      trackManager->addPoint(Vector(1500, 40, -60));
447      trackManager->addPoint(Vector(1600, 35, -55));
448      trackManager->addPoint(Vector(1700, 45, -40));
449      trackManager->addPoint(Vector(1750, 60, -40));
450      trackManager->addPoint(Vector(1770, 80, -40));
451      trackManager->addPoint(Vector(1800, 100, -40));
452      trackManager->setDuration(10);
453
454      trackManager->finalize();
455
456     
457  lightMan->setAmbientColor(.1,.1,.1);
458  lightMan->addLight();
459  //      lightMan->setAttenuation(1.0, .01, 0.0);
460  //      lightMan->setDiffuseColor(1,1,1);
461  //  lightMan->addLight(1);
462  //  lightMan->setPosition(20, 10, -20);
463  //  lightMan->setDiffuseColor(0,0,0);
464  lightMan->debug();
465  lightMan->setPosition(-5.0, 10.0, -40.0);
466 
467  //        trackManager->setBindSlave(env);
468  PNode* tn = trackManager->getTrackNode();
469  tn->addChild(this->localPlayer);
470 
471  //localCamera->setParent(TrackNode::getInstance());
472  tn->addChild(this->localCamera);
473  localCamera->lookAt(tn);
474  localCamera->setMode(PNODE_MOVEMENT);
475  this->localPlayer->setMode(PNODE_ALL);
476  Vector* cameraOffset = new Vector (0, 5, -10);
477  trackManager->condition(2, LEFTRIGHT, this->localPlayer);
478 
479  this->sky->setParent(this->localCamera);
480
481  // initialize debug coord system
482  objectList = glGenLists(1);
483  glNewList (objectList, GL_COMPILE);
484 
485  //  trackManager->drawGraph(.01);
486  trackManager->debug(2);
487  glEndList();
488
489  terrain = new Terrain("worlds/newGround.obj");
490  terrain->setRelCoor(Vector(0,-10,0));
491  this->spawn(terrain);
492
493
494  // Creating a Test Particle System
495  ParticleSystem* system = new ParticleSystem(100000, PARTICLE_SPRITE);
496  system->setLifeSpan(1);
497  system->setConserve(.8);
498  system->setRadius(4, 0, 1, 0);
499  system->setColor(1,0,0,1, 1,1,0,1, 0,0,0,0);
500
501  // Creating a Test Particle Emitter
502  ParticleEmitter* emitter = new ParticleEmitter(Vector(-1, 0, 0), M_PI_4, 400, .5);
503  emitter->setParent(this->localPlayer);
504  emitter->setRelCoor(Vector(0,-3,0));
505 
506  // Add the Flow from the Emitter into the System
507  particleEngine->addConnection(emitter, system);
508
509
510  // Creating Some Fields
511  Field* twirl = new Twirl();
512  twirl->setMagnitude(.1);
513  Field* gravity = new PointGravity();
514  gravity->setMagnitude(.5);
515  twirl->setParent(this->localCamera->getTarget());
516  gravity->setParent(this->localCamera->getTarget());
517
518  //  new PhysicsConnection(system, twirl);
519  //    new PhysicsConnection(system, gravity);
520
521}
522
523void World::loadDebugWorld(int worldID)
524{
525  /*monitor progress*/
526  this->glmis->step();
527
528  // LIGHT initialisation
529
530  lightMan->setAmbientColor(.1,.1,.1);
531  lightMan->addLight();
532  //      lightMan->setAttenuation(1.0, .01, 0.0);
533  //      lightMan->setDiffuseColor(1,1,1);
534  //  lightMan->addLight(1);
535  //  lightMan->setPosition(20, 10, -20);
536  //  lightMan->setDiffuseColor(0,0,0);
537  lightMan->debug();
538
539  switch(this->debugWorldNr)
540    {
541      /*
542        this loads the hard-coded debug world. this only for simplicity and will be
543        removed by a reald world-loader, which interprets a world-file.
544        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
545        make whatever you want...
546      */
547    case DEBUG_WORLD_0:
548      {
549        lightMan->setPosition(-5.0, 10.0, -40.0);
550
551        // !\todo old track-system has to be removed
552
553        //create helper for player
554        //HelperParent* hp = new HelperParent ();
555        /* the player has to be added to this helper */
556
557        // create a player
558        this->localPlayer = new Player ();
559        this->localPlayer->setName ("player");
560        this->spawn (this->localPlayer);
561        /*monitor progress*/
562        //this->glmis->step();
563        this->glmis->step();
564
565        // bind input
566        Orxonox *orx = Orxonox::getInstance ();
567        orx->getLocalInput()->bind (this->localPlayer);
568           
569        // bind camera
570        this->localCamera = new Camera();
571        this->localCamera->setName ("camera");
572           
573        /*monitor progress*/
574        this->glmis->step();
575
576        sky = new SkyBox();
577        //      (SkyBox*)(sky)->setTexture("pictures/sky/skybox", "jpg");
578        sky->setParent(localCamera);
579        this->spawn(sky);
580
581        /*monitor progress*/
582        this->glmis->step();
583
584           
585        WorldEntity* env = new Environment();
586        env->setName ("env");
587        this->spawn(env);
588
589           
590        /*
591          Vector* es = new Vector (10, 5, 0);
592          Quaternion* qs = new Quaternion ();
593          WorldEntity* pr = new Primitive(P_CYLINDER);
594          pr->setName("primitive");
595          this->spawn(pr, this->localPlayer, es, qs, PNODE_MOVEMENT);
596        */
597
598        /*monitor progress*/
599        this->glmis->step();
600
601        //          trackManager->setBindSlave(env);
602        PNode* tn = trackManager->getTrackNode();
603        tn->addChild(this->localPlayer);
604        this->localCamera->lookAt(tn);
605
606        //localCamera->setParent(TrackNode::getInstance());
607        tn->addChild(this->localCamera);
608        //          localCamera->lookAt(tn);
609        this->localPlayer->setMode(PNODE_ALL);
610        //Vector* cameraOffset = new Vector (0, 5, -10);
611        trackManager->condition(2, LEFTRIGHT, this->localPlayer);
612        this->glmis->step();
613        break;
614      }
615    case DEBUG_WORLD_1:
616      {
617        lightMan->setPosition(.0, .0, .0);
618        lightMan->setAttenuation(1.0, .01, 0.0);
619        lightMan->setSpecularColor(1,0,0);
620        this->nullParent = NullParent::getInstance ();
621        this->nullParent->setName ("NullParent");
622
623        // create a player
624        WorldEntity* myPlayer = new Player();
625        myPlayer->setName ("player");
626        this->spawn(myPlayer);
627        this->localPlayer = myPlayer;       
628           
629        // bind input
630        Orxonox *orx = Orxonox::getInstance();
631        orx->getLocalInput()->bind (myPlayer);
632           
633        // bind camera
634        this->localCamera = new Camera ();
635        this->localCamera->setName ("camera");
636        this->localCamera->lookAt(LightManager::getInstance()->getLight(0));
637        this->localCamera->setParent(this->localPlayer);
638
639        // Create SkySphere
640        sky = new Skysphere("pictures/sky-replace.jpg");
641        this->localPlayer->addChild(this->sky);
642        this->spawn(this->sky);
643        Vector* es = new Vector (20, 0, 0);
644        Quaternion* qs = new Quaternion ();
645
646        lightMan->getLight(0)->setParent(trackManager->getTrackNode());
647        break;
648      }
649    case DEBUG_WORLD_2:
650      {
651        lightMan->setAmbientColor(.1,.1,.1);
652        lightMan->addLight();
653        lightMan->setPosition(-5.0, 10.0, -40.0);
654        this->nullParent = NullParent::getInstance ();
655        this->nullParent->setName ("NullParent");
656
657        // !\todo old track-system has to be removed
658
659        //create helper for player
660        //HelperParent* hp = new HelperParent ();
661        /* the player has to be added to this helper */
662
663        // create a player
664        this->localPlayer = new Player ();
665        this->localPlayer->setName ("player");
666        this->spawn (this->localPlayer);
667        /*monitor progress*/
668        //this->glmis->step();     
669        this->glmis->step();
670
671        // bind input
672        Orxonox *orx = Orxonox::getInstance ();
673        orx->getLocalInput()->bind (this->localPlayer);
674           
675        // bind camera
676        this->localCamera = new Camera();
677        this->localCamera->setName ("camera");
678        this->localCamera->lookAt(this->localPlayer);
679        this->localCamera->setParent(this->localPlayer);
680           
681        /*monitor progress*/
682        this->glmis->step();
683
684        // Create SkySphere
685        this->sky = new Skysphere("pictures/sky-replace.jpg");
686        this->sky->setName("SkySphere");
687        this->spawn(this->sky);
688        this->localCamera->addChild(this->sky);
689        this->sky->setMode(PNODE_MOVEMENT);
690        /*monitor progress*/
691        this->glmis->step();
692
693
694        WorldEntity* baseNode = new Satellite(Vector(1,0,1), 1.2);
695        this->localPlayer->addChild(baseNode);
696        baseNode->setRelCoor(Vector(10.0, 2.0, 1.0));
697        this->spawn(baseNode);
698
699        WorldEntity* secondNode = new Satellite(Vector(0,0,1), 2.0);
700        baseNode->addChild(secondNode);
701        secondNode->setRelCoor(Vector(0.0, 0.0, 3.0));
702        this->spawn(secondNode);
703
704
705        WorldEntity* thirdNode = new Satellite(Vector(0,0,1), 1.0);
706        secondNode->addChild(thirdNode);
707        thirdNode->setRelCoor(Vector(2.0, 0.0, 0.0));
708        this->spawn(thirdNode);
709
710           
711   
712        WorldEntity* c = new Environment();
713        this->localPlayer->addChild(c);
714        c->setRelCoor(Vector(10.0, 2.0, -1.0));
715        this->spawn(c);
716
717
718           
719        Animation3D* animation = new Animation3D(c);
720        animation->setInfinity(ANIM_INF_REPLAY);
721
722
723        animation->addKeyFrame(Vector(0, 0, 0), Quaternion(0, Vector(0,1,0)), 1.0, ANIM_NEG_EXP, ANIM_LINEAR); 
724        animation->addKeyFrame(Vector(0, 2, 0), Quaternion(M_PI, Vector(0,1,0)), 1.0, ANIM_NEG_EXP, ANIM_LINEAR); 
725        animation->addKeyFrame(Vector(0, 0, 0), Quaternion(0, Vector(0,1,0)), 1.0, ANIM_NEG_EXP, ANIM_LINEAR); 
726
727
728
729
730
731
732        /*         
733          KeyFrame* f1 = new KeyFrame;
734          f1->position = new Vector(-1.1, 0.0, 2.6);
735          f1->direction = new Quaternion();
736          f1->time = 1.0;
737          f1->mode = NEG_EXP;
738                 
739                 
740          KeyFrame* f2 = new KeyFrame;
741          f2->position = new Vector(-2.1, 0.0, 2.6);
742          f2->direction = new Quaternion();
743          f2->time = 0.1;
744          f2->mode = NEG_EXP;
745                 
746          KeyFrame* f3 = new KeyFrame;
747          f3->position = new Vector(10.0, 2.0, -1.0);
748          f3->direction = new Quaternion();
749          f3->time = 0.2;
750          f3->mode = NEG_EXP;
751                 
752          KeyFrame* f4 = new KeyFrame;
753          f4->position = new Vector(10.0, 5.0, -1.0);
754          f4->direction = new Quaternion();
755          f4->time = 1.0;
756          f4->mode = NEG_EXP;
757                 
758                 
759                 
760          this->simpleAnimation->animatorBegin();
761          this->simpleAnimation->selectObject(b);
762          this->simpleAnimation->setAnimationMode(SINGLE);
763          this->simpleAnimation->addKeyFrame(f1);
764          this->simpleAnimation->addKeyFrame(f2);
765          this->simpleAnimation->start();
766          this->simpleAnimation->selectObject(c);
767          this->simpleAnimation->addKeyFrame(f3);
768          this->simpleAnimation->addKeyFrame(f4);
769          this->simpleAnimation->start();
770          this->simpleAnimation->animatorEnd();
771        */
772
773        /*
774          Vector* es = new Vector (10, 5, 0);
775          Quaternion* qs = new Quaternion ();
776          WorldEntity* pr = new Primitive(P_CYLINDER);
777          pr->setName("primitive");
778          this->spawn(pr, this->localPlayer, es, qs, PNODE_MOVEMENT);
779        */
780
781        /*monitor progress*/
782        this->glmis->step();
783
784        //          trackManager->setBindSlave(env);
785        PNode* tn = trackManager->getTrackNode();
786        tn->addChild(this->localPlayer);
787
788        //localCamera->setParent(TrackNode::getInstance());
789        tn->addChild(this->localCamera);
790        //          localCamera->lookAt(tn);
791        this->localPlayer->setMode(PNODE_ALL);
792        //Vector* cameraOffset = new Vector (0, 5, -10);
793        trackManager->condition(2, LEFTRIGHT, this->localPlayer);
794        this->glmis->step();
795
796        break;
797      }
798    default:
799      printf("World::load() - no world with ID %i found", this->debugWorldNr );
800    }
801}
802
803
804
805/**
806   \brief initializes a new World shortly before start
807
808   this is the function, that will be loaded shortly before the world is
809   started
810*/
811ErrorMessage World::init()
812{
813  this->bPause = false;
814  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
815  cn->addToWorld(this);
816  cn->enable(true);
817}
818
819
820/**
821   \brief starts the World
822*/
823ErrorMessage World::start()
824{
825  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
826  this->bQuitOrxonox = false;
827  this->bQuitCurrentGame = false;
828  this->mainLoop();
829}
830
831/**
832   \brief stops the world.
833
834   This happens, when the player decides to end the Level.
835*/
836ErrorMessage World::stop()
837{
838  PRINTF(3)("World::stop() - got stop signal\n");
839  this->bQuitCurrentGame = true;
840}
841
842/**
843   \brief pauses the Game
844*/
845ErrorMessage World::pause()
846{
847  this->isPaused = true;
848}
849
850/**
851   \brief ends the pause Phase
852*/
853ErrorMessage World::resume()
854{
855  this->isPaused = false;
856}
857
858/**
859   \brief destroys the World
860*/
861ErrorMessage World::destroy()
862{
863
864}
865
866/**
867   \brief shows the loading screen
868*/
869void World::displayLoadScreen ()
870{
871  PRINTF(3)("World::displayLoadScreen - start\n"); 
872 
873  //GLMenuImageScreen*
874  this->glmis = new GLMenuImageScreen();
875  this->glmis->init();
876  this->glmis->setMaximum(8);
877  //  this->glmis->draw();
878 
879  PRINTF(3)("World::displayLoadScreen - end\n"); 
880}
881
882/**
883   \brief removes the loadscreen, and changes over to the game
884
885   \todo take out the delay
886*/
887void World::releaseLoadScreen ()
888{
889  PRINTF(3)("World::releaseLoadScreen - start\n"); 
890  this->glmis->setValue(this->glmis->getMaximum());
891  PRINTF(3)("World::releaseLoadScreen - end\n"); 
892  delete this->glmis;
893}
894
895
896/**
897   \brief gets the list of entities from the world
898   \returns entity list
899*/
900tList<WorldEntity>* World::getEntities()
901{
902  return this->entities;
903}
904
905
906/**
907   \brief this returns the current game time
908   \returns elapsed game time
909*/
910double World::getGameTime()
911{
912  return this->gameTime;
913}
914
915
916/**
917    \brief checks for collisions
918   
919    This method runs through all WorldEntities known to the world and checks for collisions
920    between them. In case of collisions the collide() method of the corresponding entities
921    is called.
922*/
923void World::collide ()
924{
925  /*
926  List *a, *b;
927  WorldEntity *aobj, *bobj;
928   
929  a = entities;
930 
931  while( a != NULL)
932    {
933      aobj = a->nextElement();
934      if( aobj->bCollide && aobj->collisioncluster != NULL)
935        {
936          b = a->nextElement();
937          while( b != NULL )
938            {
939              bobj = b->nextElement();
940              if( bobj->bCollide && bobj->collisioncluster != NULL )
941                {
942                  unsigned long ahitflg, bhitflg;
943                  if( check_collision ( &aobj->place, aobj->collisioncluster,
944                                        &ahitflg, &bobj->place, bobj->collisioncluster,
945                                        &bhitflg) );
946                  {
947                    aobj->collide (bobj, ahitflg, bhitflg);
948                    bobj->collide (aobj, bhitflg, ahitflg);
949                  }
950                }
951              b = b->nextElement();
952            }
953        }
954      a = a->enumerate();
955    }
956  */
957}
958
959/**
960    \brief runs through all entities calling their draw() methods
961*/
962void World::draw ()
963{
964  /* draw entities */
965  WorldEntity* entity;
966  glLoadIdentity();
967
968  //entity = this->entities->enumerate();
969  tIterator<WorldEntity>* iterator = this->entities->getIterator();
970  entity = iterator->nextElement();
971  while( entity != NULL ) 
972    { 
973      if( entity->bDraw ) entity->draw();
974      //entity = this->entities->nextElement();
975      entity = iterator->nextElement();
976    }
977  delete iterator;
978 
979  glCallList (objectList);
980
981  TextEngine::getInstance()->draw();
982  particleEngine->draw(this->dtS); //!< \todo should be dts like in the Trunk;
983
984  lightMan->draw(); // must be at the end of the drawing procedure, otherwise Light cannot be handled as PNodes //
985}
986
987
988/**
989   \brief function to put your own debug stuff into it. it can display informations about
990   the current class/procedure
991*/
992void World::debug()
993{
994  PRINTF(2)("debug() - starting debug\n");
995  PNode* p1 = NullParent::getInstance ();
996  PNode* p2 = new PNode (Vector(2, 2, 2), p1);
997  PNode* p3 = new PNode (Vector(4, 4, 4), p1);
998  PNode* p4 = new PNode (Vector(6, 6, 6), p2);
999
1000  p1->debug ();
1001  p2->debug ();
1002  p3->debug ();
1003  p4->debug ();
1004
1005  p1->shiftCoor (Vector(-1, -1, -1));
1006
1007  printf("World::debug() - shift\n");
1008  p1->debug ();
1009  p2->debug ();
1010  p3->debug ();
1011  p4->debug ();
1012 
1013  p1->update (0);
1014
1015  printf ("World::debug() - update\n");
1016  p1->debug ();
1017  p2->debug ();
1018  p3->debug ();
1019  p4->debug ();
1020
1021  p2->shiftCoor (Vector(-1, -1, -1));
1022  p1->update (0);
1023
1024  p1->debug ();
1025  p2->debug ();
1026  p3->debug ();
1027  p4->debug ();
1028
1029  p2->setAbsCoor (Vector(1,2,3));
1030
1031
1032 p1->update (0);
1033
1034  p1->debug ();
1035  p2->debug ();
1036  p3->debug ();
1037  p4->debug ();
1038
1039  delete p1;
1040 
1041 
1042  /*
1043  WorldEntity* entity;
1044  printf("counting all entities\n");
1045  printf("World::debug() - enumerate()\n");
1046  entity = entities->enumerate(); 
1047  while( entity != NULL )
1048    {
1049      if( entity->bDraw ) printf("got an entity\n");
1050      entity = entities->nextElement();
1051    }
1052  */
1053}
1054
1055
1056/**
1057  \brief main loop of the world: executing all world relevant function
1058
1059  in this loop we synchronize (if networked), handle input events, give the heart-beat to
1060  all other member-entities of the world (tick to player, enemies etc.), checking for
1061  collisions drawing everything to the screen.
1062*/
1063void World::mainLoop()
1064{
1065  this->lastFrame = SDL_GetTicks ();
1066  PRINTF(3)("World::mainLoop() - Entering main loop\n");
1067  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
1068    {
1069      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
1070      // Network
1071      this->synchronize ();
1072      // Process input
1073      this->handleInput ();
1074      if( this->bQuitCurrentGame || this->bQuitOrxonox)
1075          break;
1076      // Process time
1077      this->tick ();
1078      // Update the state
1079      this->update ();     
1080      // Process collision
1081      this->collide ();
1082      // Draw
1083      this->display ();
1084
1085      //      for( int i = 0; i < 5000000; i++) {}
1086      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
1087    }
1088  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
1089}
1090
1091
1092/**
1093   \brief synchronize local data with remote data
1094*/
1095void World::synchronize ()
1096{
1097  // Get remote input
1098  // Update synchronizables
1099}
1100
1101
1102/**
1103   \brief run all input processing
1104
1105   the command node is the central input event dispatcher. the node uses the even-queue from
1106   sdl and has its own event-passing-queue.
1107*/
1108void World::handleInput ()
1109{
1110  // localinput
1111  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
1112  cn->process();
1113  // remoteinput
1114}
1115
1116
1117/**
1118   \brief advance the timeline
1119
1120   this calculates the time used to process one frame (with all input handling, drawing, etc)
1121   the time is mesured in ms and passed to all world-entities and other classes that need
1122   a heart-beat.
1123*/
1124void World::tick ()
1125{
1126  Uint32 currentFrame = SDL_GetTicks();
1127  if(!this->bPause)
1128    {
1129      this->dt = currentFrame - this->lastFrame;
1130     
1131      if( this->dt > 0)
1132        {
1133          float fps = 1000/dt;
1134
1135          // temporary, only for showing how fast the text-engine is
1136          char tmpChar[20];
1137          sprintf(tmpChar, "fps: %4.0f", fps);
1138        }
1139      else
1140        {
1141          /* the frame-rate is limited to 100 frames per second, all other things are for
1142             nothing.
1143          */
1144          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
1145          SDL_Delay(10);
1146          this->dt = 10;
1147        }
1148      //this->timeSlice (dt);
1149     
1150      /* function to let all entities tick (iterate through list) */
1151      this->dtS = (float)this->dt / 1000.0;     
1152      this->gameTime += this->dtS;
1153      //entity = entities->enumerate();
1154      tIterator<WorldEntity>* iterator = this->entities->getIterator();
1155      WorldEntity* entity = iterator->nextElement();
1156      while( entity != NULL) 
1157        { 
1158          entity->tick (this->dtS);
1159          entity = iterator->nextElement();
1160        }
1161      delete iterator;
1162
1163      /* update tick the rest */
1164      this->trackManager->tick(this->dt);
1165      this->localCamera->tick(this->dt);
1166      this->garbageCollector->tick(this->dtS);
1167
1168      AnimationPlayer::getInstance()->tick(this->dtS);
1169      PhysicsEngine::getInstance()->tick(this->dtS);
1170
1171      particleEngine->tick(this->dtS);
1172    }
1173  this->lastFrame = currentFrame;
1174}
1175
1176
1177/**
1178   \brief this function gives the world a consistant state
1179
1180   after ticking (updating the world state) this will give a constistant
1181   state to the whole system.
1182*/
1183void World::update()
1184{
1185  this->garbageCollector->update();
1186  this->nullParent->update (this->dtS);
1187}
1188
1189
1190/**
1191   \brief render the current frame
1192   
1193   clear all buffers and draw the world
1194*/
1195void World::display ()
1196{
1197  // clear buffer
1198  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1199  // set camera
1200  this->localCamera->apply ();
1201  // draw world
1202  this->draw();
1203  // draw HUD
1204  /* \todo draw HUD */
1205  // flip buffers
1206  SDL_GL_SwapBuffers();
1207  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
1208  //SDL_Flip (screen);
1209}
1210
1211
1212/**
1213   \brief add and spawn a new entity to this world
1214   \param entity to be added
1215*/
1216void World::spawn(WorldEntity* entity)
1217{
1218  this->entities->add (entity);
1219  entity->postSpawn ();
1220}
1221
1222
1223/**
1224   \brief add and spawn a new entity to this world
1225   \param entity to be added
1226   \param absCoor At what coordinates to add this entity.
1227   \param absDir In which direction should it look.
1228*/
1229void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1230{
1231  this->entities->add (entity);
1232
1233  entity->setAbsCoor (*absCoor);
1234  entity->setAbsDir (*absDir);
1235
1236  entity->postSpawn ();
1237}
1238
1239
1240/**
1241   \brief add and spawn a new entity to this world
1242   \param entity to be added
1243   \param entity to be added to (PNode)
1244   \param At what relative  coordinates to add this entity.
1245   \param In which relative direction should it look.
1246*/
1247void World::spawn(WorldEntity* entity, PNode* parentNode, 
1248                  Vector* relCoor, Quaternion* relDir, 
1249                  int parentingMode)
1250{
1251  this->nullParent = NullParent::getInstance();
1252  if( parentNode != NULL)
1253    {
1254      parentNode->addChild (entity);
1255     
1256      entity->setRelCoor (*relCoor);
1257      entity->setRelDir (*relDir);
1258      entity->setMode(parentingMode);
1259     
1260      this->entities->add (entity);
1261     
1262      entity->postSpawn ();
1263    }
1264}
1265
1266
1267
1268/**
1269  \brief commands that the world must catch
1270  \returns false if not used by the world
1271*/
1272bool World::command(Command* cmd)
1273{
1274  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1275  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1276  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1277  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1278  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1279  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1280
1281  return false;
1282}
1283
1284void World::setPath( const char* name)
1285{
1286  if (this->path)
1287    delete this->path;
1288  if (ResourceManager::isFile(name))
1289  {
1290    this->path = new char[strlen(name)+1];
1291    strcpy(this->path, name);
1292  }
1293  else
1294    {
1295      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1296      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1297    }
1298}
1299
1300const char* World::getPath( void)
1301{
1302  return path;
1303}
Note: See TracBrowser for help on using the repository browser.