Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/physics: nicer fog trailing our little ship

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