Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/physics: intoducing state: stors the Camera position globally somewhere we have to store this data

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