Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/physics: physicsEngine works for particles

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