Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 565 was 565, checked in by scheusso, 16 years ago

added class BaseEntity:

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