Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/particleEngine/src/story_entities/world.cc @ 4128

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

orxonox/branches/particleEngine: renders some particles again

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