Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/md2_loader/src/story_entities/world.cc @ 4152

Last change on this file since 4152 was 4152, checked in by patrick, 19 years ago

orxonox/branches/md2_loader: removed the md2 loader stuff from the world and implemented it in the testentity class, where its more local and makes more sense

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