Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/orxonox/orxonox.cc @ 576

Last change on this file since 576 was 576, checked in by landauf, 16 years ago

added Mesh and Model (doesn't work yet, but i don't want to have merge conflicts all the time :P)

File size: 13.7 KB
RevLine 
[74]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
[462]7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
[74]11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
[462]18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
[74]20 *
21 *   Author:
22 *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
23 *   Co-authors:
24 *      ...
25 *
26 */
27
[142]28/**
29 @file  orxonox.cc
[462]30 @brief Orxonox Main Class
[142]31 */
32
[462]33#include "orxonox.h"
34#include "graphicsEngine.h"
35
[379]36//#include <Ogre.h>
37// 40% speed up: (instead of Ogre.h)
38#include <OgreSceneNode.h>
39#include <OgreSceneManager.h>
40#include <OgreRoot.h>
41#include <OgreFrameListener.h>
42#include <OgreConfigFile.h>
43#include <OgreTextureManager.h>
44#include <OgreEntity.h>
45#include <OgreRenderWindow.h>
46
[137]47#include <OIS/OIS.h>
[346]48//#include <CEGUI/CEGUI.h>
49//#include <OgreCEGUIRenderer.h>
[74]50
[164]51#include <string>
52#include <iostream>
53
[496]54#include "objects/Tickable.h"
55#include "objects/Timer.h"
[542]56#include "core/ArgReader.h"
[496]57#include "core/Factory.h"
[568]58#include "core/Debug.h"
[496]59
[462]60#include "../loader/LevelLoader.h"
61#include "../audio/AudioManager.h"
[164]62
[337]63#include "spaceship_steering.h"
[164]64
[535]65#include "particle/ParticleInterface.h"
[337]66
[459]67//network stuff
[462]68#include "../network/Server.h"
69#include "../network/Client.h"
[473]70#include "../network/NetworkFrameListener.h"
[576]71
72#ifdef WIN32
73#include <windows.h>
74#define usleep(x) Sleep((x)/1000)
75#else
76#include <unistd.h>
77#endif
[459]78
[337]79namespace orxonox
80{
[462]81  using namespace Ogre;
[74]82
[462]83   // put this in seperate Class or solve the problem in another fashion
84  class OrxListener : public FrameListener, public OIS::MouseListener
85  {
86    public:
[519]87      OrxListener(OIS::Keyboard *keyboard, OIS::Mouse *mouse, audio::AudioManager*  auMan, SpaceshipSteering* steering)
[462]88      : mKeyboard(keyboard), mMouse(mouse)
89      {
[530]90
91
92
[462]93        speed = 250;
94        loop = 100;
95        rotate = 10;
96        mouseX = 0;
97        mouseY = 0;
98        maxMouseX = 0;
99        minMouseX = 0;
[337]100        moved = false;
[530]101
[519]102        steering_ = steering;
103
104        steering_->brakeRotate(rotate*10);
105        steering_->brakeLoop(loop);
106
[530]107
[462]108        mMouse->setEventCallback(this);
109        auMan_ = auMan;
[265]110      }
[462]111      bool frameStarted(const FrameEvent& evt)
112      {
[135]113
[462]114        auMan_->update();
[74]115
[462]116        mKeyboard->capture();
117        mMouse->capture();
118        if (mKeyboard->isKeyDown(OIS::KC_UP) || mKeyboard->isKeyDown(OIS::KC_W))
[519]119          steering_->moveForward(speed);
[462]120        else
[519]121          steering_->moveForward(0);
[462]122        if(mKeyboard->isKeyDown(OIS::KC_DOWN) || mKeyboard->isKeyDown(OIS::KC_S))
[519]123          steering_->brakeForward(speed);
[462]124        else
[519]125          steering_->brakeForward(speed/10);
[462]126        if (mKeyboard->isKeyDown(OIS::KC_RIGHT) || mKeyboard->isKeyDown(OIS::KC_D))
[519]127          steering_->loopRight(loop);
[462]128        else
[519]129          steering_->loopRight(0);
[462]130        if (mKeyboard->isKeyDown(OIS::KC_LEFT) || mKeyboard->isKeyDown(OIS::KC_A))
[519]131          steering_->loopLeft(loop);
[462]132        else
[519]133          steering_->loopLeft(0);
[337]134
[462]135        if(moved) {
[512]136          if (mouseY<=0)
[519]137            steering_->rotateUp(-mouseY*rotate);
[462]138          if (mouseY>0)
[519]139            steering_->rotateDown(mouseY*rotate);
[462]140          if (mouseX>0)
[519]141            steering_->rotateRight(mouseX*rotate);
[512]142          if (mouseX<=0)
[519]143            steering_->rotateLeft(-mouseX*rotate);
[512]144          mouseY = 0;
145          mouseX = 0;
[462]146          moved = false;
147        }
148        else {
[519]149          steering_->rotateUp(0);
150          steering_->rotateDown(0);
151          steering_->rotateRight(0);
152          steering_->rotateLeft(0);
[462]153        }
[337]154
[519]155                steering_->tick(evt.timeSinceLastFrame);
[530]156
157
158
[462]159//      scenemanager->spacehip->tick(evt.timesincelastframe);
[542]160        //if(mKeyboard->isKeyDown(OIS::KC_ESCAPE))
161          //cout << "maximal MouseX: " << maxMouseX << "\tminMouseX: " << minMouseX << endl;
[565]162        usleep(10);
[462]163        return !mKeyboard->isKeyDown(OIS::KC_ESCAPE);
164      }
[337]165
[462]166      bool mouseMoved(const OIS::MouseEvent &e)
[265]167      {
[511]168        mouseX += e.state.X.rel;
169        mouseY += e.state.Y.rel;
[462]170        if(mouseX>maxMouseX) maxMouseX = mouseX;
171        if(mouseX<minMouseX) minMouseX = mouseX;
[542]172        //cout << "mouseX: " << mouseX << "\tmouseY: " << mouseY << endl;
[462]173        moved = true;
174        return true;
[265]175      }
[74]176
[462]177      bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; }
178      bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; }
[137]179
[265]180    private:
[462]181      float speed;
182      float rotate;
183      float loop;
184      float mouseY;
185      float mouseX;
186      float maxMouseX;
187      float minMouseX;
188      bool moved;
[265]189      OIS::Keyboard *mKeyboard;
190      OIS::Mouse *mMouse;
[462]191      audio::AudioManager*  auMan_;
[519]192      SpaceshipSteering* steering_;
[462]193  };
194  // init static singleton reference of Orxonox
195  Orxonox* Orxonox::singletonRef_ = NULL;
[137]196
[462]197  /**
198   * create a new instance of Orxonox
199   */
200  Orxonox::Orxonox()
201  {
202    ogre_ = new GraphicsEngine();
[546]203    dataPath_ = "";
[462]204  }
[74]205
[462]206  /**
207   * destruct Orxonox
208   */
209  Orxonox::~Orxonox()
210  {
211    // nothing to delete as for now
212  }
[265]213
[462]214  /**
215   * initialization of Orxonox object
216   * @param argc argument counter
217   * @param argv list of arguments
218   * @param path path to config (in home dir or something)
219   */
220  void Orxonox::init(int argc, char **argv, std::string path)
221  {
222    //TODO: find config file (assuming executable directory)
223    //TODO: read config file
224    //TODO: give config file to Ogre
[568]225    std::string mode;
226    if(argc>=2)
227      mode = std::string(argv[1]);
228    else
229      mode = "";
[542]230    ArgReader ar = ArgReader(argc, argv);
231    ar.checkArgument("mode", mode, false);
[546]232    ar.checkArgument("data", this->dataPath_, false);
[542]233    if(ar.errorHandling()) die();
[534]234
[542]235    if(mode == std::string("server"))
[462]236    {
237      serverInit(path);
[568]238      mode = SERVER;
[462]239    }
[542]240    else if(mode == std::string("client"))
[462]241    {
242      clientInit(path);
[568]243      mode = CLIENT;
[534]244    }
[542]245    else if(mode == std::string("presentation"))
[531]246    {
[568]247      serverInit(path);
248      mode = PRESENTATION;
[534]249    }
[568]250    else{
251      standaloneInit(path);
252      mode = STANDALONE;
253    }
[462]254  }
[263]255
[462]256  /**
257   * start modules
258   */
259  void Orxonox::start()
260  {
261    //TODO: start modules
[534]262    ogre_->startRender();
[462]263    //TODO: run engine
[534]264    createScene();
265    setupScene();
266    setupInputSystem();
267    createFrameListener();
268    Factory::createClassHierarchy();
[568]269    switch(mode_){
270    case PRESENTATION:
271      server_g->open();
272      break;
273    case SERVER:
274    case CLIENT:
275    case STANDALONE:
276    default:
277      break;
278    }
[534]279    startRenderLoop();
[462]280  }
[74]281
[462]282  /**
283   * @return singleton object
284   */
285  Orxonox* Orxonox::getSingleton()
286  {
287    if (!singletonRef_)
288      singletonRef_ = new Orxonox();
289    return singletonRef_;
290  }
[74]291
[462]292  /**
293   * error kills orxonox
294   */
295  void Orxonox::die(/* some error code */)
296  {
297    //TODO: destroy and destruct everything and print nice error msg
[542]298    delete this;
[462]299  }
[74]300
[568]301  void Orxonox::standaloneInit(std::string path)
[462]302  {
303    ogre_->setConfigPath(path);
304    ogre_->setup();
[473]305    root_ = ogre_->getRoot();
[534]306    if(!ogre_->load()) die(/* unable to load */);
[473]307
[534]308    //defineResources();
309    //setupRenderSystem();
310    //createRenderWindow();
311    //initializeResourceGroups();
312    /*createScene();
[473]313    setupScene();
314    setupInputSystem();
315    createFrameListener();
[496]316    Factory::createClassHierarchy();
[534]317    startRenderLoop();*/
[462]318  }
[534]319
[531]320  void Orxonox::playableServer(std::string path)
321  {
322    ogre_->setConfigPath(path);
323    ogre_->setup();
324    root_ = ogre_->getRoot();
325    defineResources();
326    setupRenderSystem();
327    createRenderWindow();
328    initializeResourceGroups();
329    createScene();
330    setupScene();
331    setupInputSystem();
332    Factory::createClassHierarchy();
333    createFrameListener();
334    try{
[534]335      server_g = new network::Server(); // add port and bindadress
336      server_g->open(); // open server and create listener thread
337      if(ogre_ && ogre_->getRoot())
338        ogre_->getRoot()->addFrameListener(new network::ServerFrameListener()); // adds a framelistener for the server
[560]339      COUT(3) << "Info: network framelistener added" << std::endl;
[534]340    }
[531]341    catch(exception &e)
342    {
[560]343      COUT(1) << "Error: There was a problem initialising the server :(" << std::endl;
[531]344    }
345    startRenderLoop();
346  }
[576]347
[568]348  void Orxonox::standalone(){
[576]349
350
351
[568]352  }
[74]353
[462]354  void Orxonox::serverInit(std::string path)
355  {
356    ogre_->setConfigPath(path);
357    ogre_->setup();
[473]358    server_g = new network::Server(); // add some settings if wanted
[462]359    if(!ogre_->load()) die(/* unable to load */);
[568]360    // add network framelistener
[505]361    ogre_->getRoot()->addFrameListener(new network::ServerFrameListener());
[462]362  }
[164]363
[462]364  void Orxonox::clientInit(std::string path)
365  {
366    ogre_->setConfigPath(path);
367    ogre_->setup();
[473]368    client_g = new network::Client(); // address here
[462]369    if(!ogre_->load()) die(/* unable to load */);
[505]370    ogre_->getRoot()->addFrameListener(new network::ClientFrameListener());
[462]371  }
[258]372
[473]373  void Orxonox::defineResources()
374  {
375    Ogre::String secName, typeName, archName;
376    Ogre::ConfigFile cf;
377#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
378    cf.load(macBundlePath() + "/Contents/Resources/resources.cfg");
379#else
[546]380    cf.load(dataPath_ + "resources.cfg");
[473]381#endif
382
383    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
384    while (seci.hasMoreElements())
385    {
386      secName = seci.peekNextKey();
387      Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
388      Ogre::ConfigFile::SettingsMultiMap::iterator i;
389      for (i = settings->begin(); i != settings->end(); ++i)
390      {
391        typeName = i->first;
392        archName = i->second;
393#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
394        Ogre::ResourceGroupManager::getSingleton().addResourceLocation( String(macBundlePath() + "/" + archName), typeName, secName);
395#else
396        Ogre::ResourceGroupManager::getSingleton().addResourceLocation( archName, typeName, secName);
397#endif
398      }
399    }
400  }
401
402  void Orxonox::setupRenderSystem()
403  {
[546]404    if (/*!root_->restoreConfig() &&*/ !root_->showConfigDialog())
[473]405      throw Exception(52, "User canceled the config dialog!", "OrxApplication::setupRenderSystem()");
406  }
407
408  void Orxonox::createRenderWindow()
409  {
410    root_->initialise(true, "OrxonoxV2");
411  }
412
413  void Orxonox::initializeResourceGroups()
414  {
415    TextureManager::getSingleton().setDefaultNumMipmaps(5);
416    ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
417  }
418
[537]419  /**
420   *
421   * @param
422   */
[462]423  void Orxonox::createScene(void)
424  {
[480]425        // Init audio
[462]426    auMan_ = new audio::AudioManager();
[487]427
[480]428    // load this file from config
429    loader_ = new loader::LevelLoader("sample.oxw");
430    loader_->loadLevel();
[337]431
[480]432        /*
[462]433    auMan_->ambientAdd("a1");
434    auMan_->ambientAdd("a2");
435    auMan_->ambientAdd("a3");
436                                //auMan->ambientAdd("ambient1");
437    auMan_->ambientStart();
[480]438        */
[462]439  }
[337]440
441
[537]442  /**
443   *
444   */
[462]445  void Orxonox::setupScene()
446  {
447    SceneManager *mgr = ogre_->getSceneManager();
[512]448
[515]449
[525]450    SceneNode* node = (SceneNode*)mgr->getRootSceneNode()->getChild("OgreHeadNode");
[541]451//     SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("OgreHeadNode", Vector3(0,0,0));
[515]452
[337]453
[525]454    steering_ = new SpaceshipSteering(500, 200, 200, 200);
455    steering_->addNode(node);
[74]456
[537]457
458    particle::ParticleInterface *e = new particle::ParticleInterface(mgr,"engine","Orxonox/strahl");
[535]459    e->particleSystem_->setParameter("local_space","true");
[537]460    e->setPositionOfEmitter(0, Vector3(0,-10,200));
461    e->setDirection(Vector3(0,0,-1));
462    e->addToSceneNode(node);
[535]463
[537]464    particle::ParticleInterface *w = new particle::ParticleInterface(mgr,"schuss","Orxonox/schuss");
465    w->particleSystem_->setParameter("local_space","true");
466    w->newEmitter();
467    w->setDirection(Vector3(0,0,1));
468    w->setPositionOfEmitter(0, Vector3(10,10,0));
469    w->setPositionOfEmitter(1, Vector3(-10,10,0));
470    w->addToSceneNode(node);
[462]471  }
[137]472
473
[462]474  void Orxonox::setupInputSystem()
475  {
476    size_t windowHnd = 0;
477    std::ostringstream windowHndStr;
478    OIS::ParamList pl;
479    Ogre::RenderWindow *win = ogre_->getRoot()->getAutoCreatedWindow();
[137]480
[462]481    win->getCustomAttribute("WINDOW", &windowHnd);
482    windowHndStr << windowHnd;
483    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
484    inputManager_ = OIS::InputManager::createInputSystem(pl);
[265]485
[462]486    try
[337]487    {
[462]488      keyboard_ = static_cast<OIS::Keyboard*>(inputManager_->createInputObject(OIS::OISKeyboard, false));
489      mouse_ = static_cast<OIS::Mouse*>(inputManager_->createInputObject(OIS::OISMouse, true));
[337]490    }
[462]491    catch (const OIS::Exception &e)
[459]492    {
[462]493      throw new Ogre::Exception(42, e.eText, "OrxApplication::setupInputSystem");
[459]494    }
[462]495  }
[137]496
[462]497  // we actually want to do this differently...
498  void Orxonox::createFrameListener()
[137]499  {
[496]500    TickFrameListener* TickFL = new TickFrameListener();
501    ogre_->getRoot()->addFrameListener(TickFL);
502
503    TimerFrameListener* TimerFL = new TimerFrameListener();
504    ogre_->getRoot()->addFrameListener(TimerFL);
505
[519]506    frameListener_ = new OrxListener(keyboard_, mouse_, auMan_, steering_);
[462]507    ogre_->getRoot()->addFrameListener(frameListener_);
[137]508  }
[462]509
510  void Orxonox::startRenderLoop()
[137]511  {
[511]512    // this is a hack!!!
513    // the call to reset the mouse clipping size should probably be somewhere
514    // else, however this works for the moment.
[523]515    unsigned int width, height, depth;
516    int left, top;
517    ogre_->getRoot()->getAutoCreatedWindow()->getMetrics(width, height, depth, left, top);
[511]518
[523]519    const OIS::MouseState &ms = mouse_->getMouseState();
520    ms.width = width;
521    ms.height = height;
[511]522
[462]523    ogre_->getRoot()->startRendering();
[74]524  }
525}
Note: See TracBrowser for help on using the repository browser.