Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/story_entities/world.cc @ 3644

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

orxonox/trunk: pnode speed function implemented

File size: 20.9 KB
Line 
1
2/*
3   orxonox - the future of 3D-vertical-scrollers
4
5   Copyright (C) 2004 orx
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2, or (at your option)
10   any later version.
11
12   ### File Specific:
13   main-programmer: Patrick Boenzli
14   co-programmer: Christian Meyer
15*/
16
17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
18
19#include "world.h"
20
21#include "orxonox.h"
22
23#include "p_node.h"
24#include "null_parent.h"
25#include "helper_parent.h"
26#include "track_node.h"
27#include "world_entity.h"
28#include "track_manager.h"
29#include "player.h"
30#include "camera.h"
31#include "environment.h"
32#include "primitive.h"
33#include "skysphere.h"
34#include "terrain.h"
35#include "light.h"
36
37#include "command_node.h"
38#include "glmenu_imagescreen.h"
39#include "fontset.h"
40#include "list.h"
41
42
43
44using namespace std;
45
46
47WorldInterface* WorldInterface::singletonRef = 0;
48
49
50/**
51   \brief private constructor because of singleton
52*/
53WorldInterface::WorldInterface()
54{
55  this->worldIsInitialized = false;
56  this->worldReference = NULL;
57}
58
59/**
60   \brief public deconstructor
61*/
62WorldInterface::~WorldInterface()
63{
64  this->singletonRef = NULL;
65  this->worldIsInitialized = false;
66  this->worldReference = NULL;
67}
68
69/**
70   \brief gets the singleton instance
71   \returns singleton instance
72*/
73WorldInterface* WorldInterface::getInstance()
74{
75  if( singletonRef == NULL)
76    singletonRef = new WorldInterface();
77  return singletonRef;
78}
79
80
81/**
82   \brief initializes the interface
83   \param reference to the world
84
85   if the worldinterface is not initilizes, there wont be any
86   useable interface
87*/
88void WorldInterface::init(World* world)
89{
90  this->worldReference = world;
91  if( world != NULL)
92    {
93      this->worldIsInitialized = true;
94      PRINTF(3)("WorldInterface up and running\n");
95    }
96}
97
98
99/**
100   \brief gets the entity list from the world
101   \return entity list
102*/
103tList<WorldEntity>* WorldInterface::getEntityList()
104{
105  if( this->worldIsInitialized)
106    return this->worldReference->getEntities();
107  PRINT(1)("Someone tried to use the WorldInterface before it has been initizlized! this can result in SEGFAULTs!\n");
108  return NULL;
109}
110
111
112
113/**
114    \brief create a new World
115   
116    This creates a new empty world!
117*/
118World::World (char* name)
119{
120  this->init(name, -1);
121  //NullParent* np = NullParent::getInstance();
122}
123
124/**
125   \brief creates a new World...
126   \param worldID with this ID
127*/
128World::World (int worldID)
129{
130  this->init(NULL, worldID);
131}
132
133/**
134    \brief remove the World from memory
135   
136    delete everything explicitly, that isn't contained in the parenting tree!
137    things contained in the tree are deleted automaticaly
138*/
139World::~World ()
140{
141  PRINTF(3)("World::~World() - deleting current world\n");
142  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
143  cn->unbind(this->localPlayer);
144  cn->reset();
145
146  delete WorldInterface::getInstance();
147
148  delete this->nullParent;
149  delete this->entities;
150  delete this->lightMan;
151  delete this->trackManager;
152}
153
154/**
155   \brief initializes the world.
156
157   set all stuff here that is world generic and does not use to much memory
158   because the real init() function StoryEntity::init() will be called
159   shortly before start of the game. 
160   since all worlds are initiated/referenced before they will be started.
161   NO LEVEL LOADING HERE - NEVER!
162*/
163void World::init(char* name, int worldID)
164{
165  this->setClassName ("World");
166
167  this->worldName = name;
168  this->debugWorldNr = worldID;
169  this->entities = new tList<WorldEntity>();
170}
171
172
173/**
174   \brief this is executed before load
175
176   since the load function sometimes needs data, that has been init before
177   the load and after the proceeding storyentity has finished
178*/
179ErrorMessage World::preLoad()
180{
181  /* init the world interface */
182  WorldInterface* wi = WorldInterface::getInstance();
183  wi->init(this);
184}
185
186
187/**
188   \brief loads the World by initializing all resources, and set their default values.
189*/
190ErrorMessage World::load()
191{
192  //  BezierCurve* tmpCurve = new BezierCurve();
193  if(this->debugWorldNr != -1)
194    {
195      // initializing Font
196      testFont = new FontSet();
197      testFont->buildFont("../data/pictures/font.tga");
198
199      // initializing the TrackManager
200      trackManager = TrackManager::getInstance();
201      trackManager->addPoint(Vector(0,0,0));
202      trackManager->addPoint(Vector(100, -40, 5));
203      trackManager->addPoint(Vector(200,-40,-8));
204      trackManager->addPoint(Vector(250, -35, -2));
205      trackManager->addPoint(Vector(320,-33,-.55));
206      trackManager->setDuration(3);
207      trackManager->setSavePoint();
208      trackManager->addPoint(Vector(410, 0, 0));
209      trackManager->addPoint(Vector(510, 20, -10));
210      trackManager->addPoint(Vector(550, 20, -10));
211      trackManager->addPoint(Vector(570, 20, -10));
212      trackManager->setDuration(5);
213     
214      int fork11, fork12;
215      trackManager->fork(2, &fork11, &fork12);
216      trackManager->workOn(fork11);
217      trackManager->addPoint(Vector(640, 25, -30));
218      trackManager->addPoint(Vector(700, 40, -120));
219      trackManager->addPoint(Vector(800, 50, -150));
220      trackManager->addPoint(Vector(900, 60, -100));
221      trackManager->addPoint(Vector(900, 60, -70));
222      trackManager->addPoint(Vector(990, 65, -15));
223      trackManager->addPoint(Vector(1050, 65, -10));
224      trackManager->addPoint(Vector(1100, 65, -20));
225      trackManager->setDuration(10);
226
227      trackManager->workOn(fork12);
228      trackManager->addPoint(Vector(640, 25, 20));
229      trackManager->addPoint(Vector(670, 50, 120));
230      trackManager->addPoint(Vector(700, 70, 80));
231      trackManager->addPoint(Vector(800, 70, 65));
232      trackManager->addPoint(Vector(850, 65, 65));
233      trackManager->addPoint(Vector(920, 35, 40));
234      trackManager->addPoint(Vector(945, 40, 40));
235      trackManager->addPoint(Vector(970, 24, 40));
236      trackManager->addPoint(Vector(1000, 40, -7));
237      trackManager->setDuration(10);
238     
239
240      trackManager->join(2, fork11, fork12);
241
242      trackManager->workOn(5);
243      trackManager->addPoint(Vector(1200, 60, -50));
244      trackManager->addPoint(Vector(1300, 50, -50));
245      trackManager->addPoint(Vector(1400, 40, -50));
246      trackManager->addPoint(Vector(1500, 40, -60));
247      trackManager->addPoint(Vector(1600, 35, -55));
248      trackManager->addPoint(Vector(1700, 45, -40));
249      trackManager->addPoint(Vector(1750, 60, -40));
250      trackManager->addPoint(Vector(1770, 80, -40));
251      trackManager->addPoint(Vector(1800, 100, -40));
252      trackManager->setDuration(10);
253
254      trackManager->finalize();
255
256     
257      /*monitor progress*/
258      this->glmis->step();
259
260      // LIGHT initialisation
261      lightMan = LightManager::getInstance();
262      lightMan->setAmbientColor(.1,.1,.1);
263      lightMan->addLight();
264      //      lightMan->setAttenuation(1.0, .01, 0.0);
265      //      lightMan->setDiffuseColor(1,1,1);
266      //  lightMan->addLight(1);
267      //  lightMan->setPosition(20, 10, -20);
268      //  lightMan->setDiffuseColor(0,0,0);
269      lightMan->debug();
270
271      switch(this->debugWorldNr)
272        {
273          /*
274            this loads the hard-coded debug world. this only for simplicity and will be
275            removed by a reald world-loader, which interprets a world-file.
276            if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
277            make whatever you want...
278           */
279        case DEBUG_WORLD_0:
280          {
281            lightMan->setPosition(-5.0, 10.0, -40.0);
282            this->nullParent = NullParent::getInstance ();
283            this->nullParent->setName ("NullParent");
284
285            // !\todo old track-system has to be removed
286
287            //create helper for player
288            //HelperParent* hp = new HelperParent ();
289            /* the player has to be added to this helper */
290
291            // create a player
292            this->localPlayer = new Player ();
293            this->localPlayer->setName ("player");
294            this->spawn (this->localPlayer);
295            /*monitor progress*/
296            this->glmis->step();           
297
298            // bind input
299            Orxonox *orx = Orxonox::getInstance ();
300            orx->getLocalInput()->bind (this->localPlayer);
301           
302            // bind camera
303            this->localCamera = new Camera();
304            this->localCamera->setName ("camera");
305            this->localCamera->lookAt(this->localPlayer);
306            this->localCamera->setParent(this->localPlayer);
307           
308            /*monitor progress*/
309            this->glmis->step();           
310
311            // Create SkySphere
312            this->skySphere = new Skysphere("../data/pictures/sky-replace.jpg");
313            this->skySphere->setName("SkySphere");
314            this->localCamera->addChild(this->skySphere);
315            this->skySphere->setMode(PNODE_MOVEMENT);
316
317            /*monitor progress*/
318            this->glmis->step();
319
320           
321            WorldEntity* env = new Environment();
322            env->setName ("env");
323            this->spawn(env);
324
325           
326            Vector* es = new Vector (10, 5, 0);
327            Quaternion* qs = new Quaternion ();
328            WorldEntity* pr = new Primitive(P_CYLINDER);
329            pr->setName("primitive");
330            this->spawn(pr, this->localPlayer, es, qs, PNODE_MOVEMENT);
331           
332
333            /*monitor progress*/
334            this->glmis->step();
335
336            //      trackManager->setBindSlave(env);
337            PNode* tn = trackManager->getTrackNode();
338            tn->addChild(this->localPlayer);
339
340            //localCamera->setParent(TrackNode::getInstance());
341            tn->addChild(this->localCamera);
342            //      localCamera->lookAt(tn);
343            this->localPlayer->setMode(PNODE_ALL);
344            //Vector* cameraOffset = new Vector (0, 5, -10);
345            trackManager->condition(2, LEFTRIGHT, this->localPlayer);
346
347            break;
348          }
349        case DEBUG_WORLD_1:
350          {
351            lightMan->setPosition(.0, .0, .0);
352            lightMan->setAttenuation(1.0, .01, 0.0);
353            lightMan->setSpecularColor(1,0,0);
354            this->nullParent = NullParent::getInstance ();
355            this->nullParent->setName ("NullParent");
356
357            // create a player
358            WorldEntity* myPlayer = new Player();
359            myPlayer->setName ("player");
360            this->spawn(myPlayer);
361            this->localPlayer = myPlayer;           
362           
363            // bind input
364            Orxonox *orx = Orxonox::getInstance();
365            orx->getLocalInput()->bind (myPlayer);
366           
367            // bind camera
368            this->localCamera = new Camera ();
369            this->localCamera->setName ("camera");
370            this->localCamera->lookAt(LightManager::getInstance()->getLight(0));
371            this->localCamera->setParent(this->localPlayer);
372
373            // Create SkySphere
374            skySphere = new Skysphere("../data/pictures/sky-replace.jpg");
375            this->localPlayer->addChild(this->skySphere);
376
377            Vector* es = new Vector (20, 0, 0);
378            Quaternion* qs = new Quaternion ();
379            WorldEntity* pr = new Primitive(P_SPHERE);
380            pr->setName("primitive");
381            this->spawn(pr, this->localPlayer, es, qs, PNODE_ROTATE_AND_MOVE);
382
383            lightMan->getLight(0)->setParent(trackManager->getTrackNode());
384            break;
385          }
386        default:
387          printf("World::load() - no world with ID %i found", this->debugWorldNr );
388        }
389    }
390  else if(this->worldName != NULL)
391    {
392
393    }
394
395  // initialize debug coord system
396  objectList = glGenLists(1);
397  glNewList (objectList, GL_COMPILE);
398 
399  trackManager->drawGraph(.01);
400  trackManager->debug(2);
401  glEndList();
402
403  terrain = new Terrain("../data/worlds/newGround.obj");
404  terrain->setRelCoor(new Vector(0,-10,0));
405  this->spawn(terrain);
406
407}
408
409
410/**
411   \brief initializes a new World shortly before start
412
413   this is the function, that will be loaded shortly before the world is
414   started
415*/
416ErrorMessage World::init()
417{
418  this->bPause = false;
419  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
420  cn->addToWorld(this);
421  cn->enable(true);
422}
423
424
425/**
426   \brief starts the World
427*/
428ErrorMessage World::start()
429{
430  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
431  this->bQuitOrxonox = false;
432  this->bQuitCurrentGame = false;
433  this->mainLoop();
434}
435
436/**
437   \brief stops the world.
438
439   This happens, when the player decides to end the Level.
440*/
441ErrorMessage World::stop()
442{
443  PRINTF(3)("World::stop() - got stop signal\n");
444  this->bQuitCurrentGame = true;
445}
446
447/**
448   \brief pauses the Game
449*/
450ErrorMessage World::pause()
451{
452  this->isPaused = true;
453}
454
455/**
456   \brief ends the pause Phase
457*/
458ErrorMessage World::resume()
459{
460  this->isPaused = false;
461}
462
463/**
464   \brief destroys the World
465*/
466ErrorMessage World::destroy()
467{
468
469}
470
471/**
472   \brief shows the loading screen
473*/
474void World::displayLoadScreen ()
475{
476  PRINTF(3)("World::displayLoadScreen - start\n"); 
477 
478  //GLMenuImageScreen*
479  this->glmis = GLMenuImageScreen::getInstance();
480  this->glmis->init();
481  this->glmis->setMaximum(10);
482  this->glmis->draw();
483 
484  PRINTF(3)("World::displayLoadScreen - end\n"); 
485}
486
487/**
488   \brief removes the loadscreen, and changes over to the game
489
490   \todo take out the delay
491*/
492void World::releaseLoadScreen ()
493{
494  PRINTF(3)("World::releaseLoadScreen - start\n"); 
495  this->glmis->setValue(this->glmis->getMaximum());
496  SDL_Delay(500);
497  PRINTF(3)("World::releaseLoadScreen - end\n"); 
498}
499
500
501/**
502   \brief gets the list of entities from the world
503   \returns entity list
504*/
505tList<WorldEntity>* World::getEntities()
506{
507  return this->entities;
508}
509
510
511/**
512    \brief checks for collisions
513   
514    This method runs through all WorldEntities known to the world and checks for collisions
515    between them. In case of collisions the collide() method of the corresponding entities
516    is called.
517*/
518void World::collide ()
519{
520  /*
521  List *a, *b;
522  WorldEntity *aobj, *bobj;
523   
524  a = entities;
525 
526  while( a != NULL)
527    {
528      aobj = a->nextElement();
529      if( aobj->bCollide && aobj->collisioncluster != NULL)
530        {
531          b = a->nextElement();
532          while( b != NULL )
533            {
534              bobj = b->nextElement();
535              if( bobj->bCollide && bobj->collisioncluster != NULL )
536                {
537                  unsigned long ahitflg, bhitflg;
538                  if( check_collision ( &aobj->place, aobj->collisioncluster,
539                                        &ahitflg, &bobj->place, bobj->collisioncluster,
540                                        &bhitflg) );
541                  {
542                    aobj->collide (bobj, ahitflg, bhitflg);
543                    bobj->collide (aobj, bhitflg, ahitflg);
544                  }
545                }
546              b = b->nextElement();
547            }
548        }
549      a = a->enumerate();
550    }
551  */
552}
553
554/**
555    \brief runs through all entities calling their draw() methods
556*/
557void World::draw ()
558{
559  /* draw entities */
560  WorldEntity* entity;
561  glLoadIdentity();
562
563  entity = this->entities->enumerate();
564  while( entity != NULL ) 
565    { 
566      if( entity->bDraw ) entity->draw();
567      entity = this->entities->nextElement();
568    } 
569 
570  glCallList (objectList);
571  //! \todo skysphere is a WorldEntity and should be inside of the world-entity-list.
572  skySphere->draw();
573
574  testFont->printText(0, 0, 1, "orxonox_" PACKAGE_VERSION);
575
576  lightMan->draw(); // must be at the end of the drawing procedure, otherwise Light cannot be handled as PNodes //
577}
578
579
580/**
581   \brief function to put your own debug stuff into it. it can display informations about
582   the current class/procedure
583*/
584void World::debug()
585{
586  PRINTF(2)("debug() - starting debug\n");
587  PNode* p1 = NullParent::getInstance ();
588  PNode* p2 = new PNode (new Vector(2, 2, 2), p1);
589  PNode* p3 = new PNode (new Vector(4, 4, 4), p1);
590  PNode* p4 = new PNode (new Vector(6, 6, 6), p2);
591
592  p1->debug ();
593  p2->debug ();
594  p3->debug ();
595  p4->debug ();
596
597  p1->shiftCoor (new Vector(-1, -1, -1));
598
599  printf("World::debug() - shift\n");
600  p1->debug ();
601  p2->debug ();
602  p3->debug ();
603  p4->debug ();
604 
605  p1->update (0);
606
607  printf ("World::debug() - update\n");
608  p1->debug ();
609  p2->debug ();
610  p3->debug ();
611  p4->debug ();
612
613  p2->shiftCoor (new Vector(-1, -1, -1));
614  p1->update (0);
615
616  p1->debug ();
617  p2->debug ();
618  p3->debug ();
619  p4->debug ();
620
621  p2->setAbsCoor (new Vector(1,2,3));
622
623
624 p1->update (0);
625
626  p1->debug ();
627  p2->debug ();
628  p3->debug ();
629  p4->debug ();
630
631  delete p1;
632 
633 
634  /*
635  WorldEntity* entity;
636  printf("counting all entities\n");
637  printf("World::debug() - enumerate()\n");
638  entity = entities->enumerate(); 
639  while( entity != NULL )
640    {
641      if( entity->bDraw ) printf("got an entity\n");
642      entity = entities->nextElement();
643    }
644  */
645}
646
647
648/**
649  \brief main loop of the world: executing all world relevant function
650
651  in this loop we synchronize (if networked), handle input events, give the heart-beat to
652  all other member-entities of the world (tick to player, enemies etc.), checking for
653  collisions drawing everything to the screen.
654*/
655void World::mainLoop()
656{
657  this->lastFrame = SDL_GetTicks ();
658  PRINTF(3)("World::mainLoop() - Entering main loop\n");
659  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
660    {
661      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
662      // Network
663      this->synchronize ();
664      // Process input
665      this->handleInput ();
666      if( this->bQuitCurrentGame || this->bQuitOrxonox)
667          break;
668      // Process time
669      this->tick ();
670      // Update the state
671      this->update ();     
672      // Process collision
673      this->collide ();
674      // Draw
675      this->display ();
676
677      //      for( int i = 0; i < 5000000; i++) {}
678      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
679    }
680  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
681}
682
683
684/**
685   \brief synchronize local data with remote data
686*/
687void World::synchronize ()
688{
689  // Get remote input
690  // Update synchronizables
691}
692
693
694/**
695   \brief run all input processing
696
697   the command node is the central input event dispatcher. the node uses the even-queue from
698   sdl and has its own event-passing-queue.
699*/
700void World::handleInput ()
701{
702  // localinput
703  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
704  cn->process();
705  // remoteinput
706}
707
708
709/**
710   \brief advance the timeline
711
712   this calculates the time used to process one frame (with all input handling, drawing, etc)
713   the time is mesured in ms and passed to all world-entities and other classes that need
714   a heart-beat.
715*/
716void World::tick ()
717{
718  Uint32 currentFrame = SDL_GetTicks();
719  if(!this->bPause)
720    {
721      this->dt = currentFrame - this->lastFrame;
722     
723      if(dt > 0)
724        {
725          float fps = 1000/dt;
726          PRINTF(3)("fps = %f\n", fps);
727        }
728      else
729        {
730          /* the frame-rate is limited to 100 frames per second, all other things are for
731             nothing.
732          */
733          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
734          SDL_Delay(10);
735          dt = 10;
736        }
737      //this->timeSlice (dt);
738     
739      /* function to let all entities tick (iterate through list) */
740      WorldEntity* entity;
741      float seconds = dt / 1000.0;     
742      entity = entities->enumerate(); 
743      while( entity != NULL) 
744        { 
745          entity->tick (seconds);
746          entity = entities->nextElement();
747        }
748      //skySphere->updatePosition(localCamera->absCoordinate);
749     
750      /* update tick the rest */
751      this->trackManager->tick(dt);
752      this->localCamera->tick(dt);
753    }
754  this->lastFrame = currentFrame;
755}
756
757
758/**
759   \brief this function gives the world a consistant state
760
761   after ticking (updating the world state) this will give a constistant
762   state to the whole system.
763*/
764void World::update()
765{
766  this->nullParent->update (dt);
767}
768
769
770/**
771   \brief render the current frame
772   
773   clear all buffers and draw the world
774*/
775void World::display ()
776{
777  // clear buffer
778  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
779  // set camera
780  this->localCamera->apply ();
781  // draw world
782  this->draw();
783  // draw HUD
784  /* \todo draw HUD */
785  // flip buffers
786  SDL_GL_SwapBuffers();
787  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
788  //SDL_Flip (screen);
789}
790
791
792/**
793   \brief add and spawn a new entity to this world
794   \param entity to be added
795*/
796void World::spawn(WorldEntity* entity)
797{
798  this->entities->add (entity);
799  entity->postSpawn ();
800}
801
802
803/**
804   \brief add and spawn a new entity to this world
805   \param entity to be added
806   \param absCoor At what coordinates to add this entity.
807   \param absDir In which direction should it look.
808*/
809void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
810{
811  this->entities->add (entity);
812
813  entity->setAbsCoor (absCoor);
814  entity->setAbsDir (absDir);
815
816  entity->postSpawn ();
817}
818
819
820/**
821   \brief add and spawn a new entity to this world
822   \param entity to be added
823   \param entity to be added to (PNode)
824   \param At what relative  coordinates to add this entity.
825   \param In which relative direction should it look.
826*/
827void World::spawn(WorldEntity* entity, PNode* parentNode, 
828                  Vector* relCoor, Quaternion* relDir, 
829                  int parentingMode)
830{
831  this->nullParent = NullParent::getInstance();
832  if( parentNode != NULL)
833    {
834      parentNode->addChild (entity);
835     
836      entity->setRelCoor (relCoor);
837      entity->setRelDir (relDir);
838      entity->setMode(parentingMode);
839     
840      this->entities->add (entity);
841     
842      entity->postSpawn ();
843    }
844}
845
846
847
848/**
849  \brief commands that the world must catch
850  \returns false if not used by the world
851*/
852bool World::command(Command* cmd)
853{
854  if( !strcmp( cmd->cmd, "view0")) this->localCamera->setViewMode(VIEW_NORMAL);
855  else if( !strcmp( cmd->cmd, "view1")) this->localCamera->setViewMode(VIEW_BEHIND);
856  else if( !strcmp( cmd->cmd, "view2")) this->localCamera->setViewMode(VIEW_FRONT);
857  else if( !strcmp( cmd->cmd, "view3")) this->localCamera->setViewMode(VIEW_LEFT);
858  else if( !strcmp( cmd->cmd, "view4")) this->localCamera->setViewMode(VIEW_RIGHT);
859  else if( !strcmp( cmd->cmd, "view5")) this->localCamera->setViewMode(VIEW_TOP);
860 
861  return false;
862}
863
Note: See TracBrowser for help on using the repository browser.