Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/physics: particles get rendered with facing toward Camera (in PARTICLE_SPRITE-mode)

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