Changeset 161 for code/branches/main_reto_vs05/src/run_manager.cc
- Timestamp:
- Nov 4, 2007, 5:00:41 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/main_reto_vs05/src/run_manager.cc
r160 r161 39 39 */ 40 40 41 #include "Ogre.h" 42 //#include "OgreRoot.h" 43 //#include "OgreSceneManager.h" 44 //#include "OgreSceneNode.h" 45 //#include "OgreCamera.h" 46 //#include "OgreViewport.h" 47 //#include "OgreRenderWindow.h" 48 //#include "OgreOverlay.h" 49 //#include "OgreOverlayManager.h" 50 //#include "OgreOverlayElement.h" 51 //#include "OgreTextureManager.h" 52 //#include "OgreMaterialManager.h" 53 //#include "OgreLogManager.h" 54 //#include "OgreVector3.h" 55 //#include "OgreStringConverter.h" 56 //#include "OgreWindowEventUtilities.h" 57 58 //Use this define to signify OIS will be used as a DLL 59 //(so that dll import/export macros are in effect) 60 #define OIS_DYNAMIC_LIB 61 #include <OIS/OIS.h> 62 63 #include "ogre_control.h" 64 #include "orxonox_scene.h" 65 #include "orxonox_ship.h" 66 #include "bullet.h" 67 #include "camera_manager.h" 68 41 69 #include "run_manager.h" 42 70 43 44 /** 45 * Contructor only needs the render window and the Root object which are both 46 * the OgreControl object. 47 * Right now the constructor does all the initialisation work. This could also 48 * be done in a new method "initialize()", for whatever purpose. 49 * 50 * 51 * @param ogre_ The OgreControl object holding the render window and the Root 52 */ 53 RunManager::RunManager(OgreControl * ogre) 54 : ogre_(ogre), window_(ogre->getRenderWindow()), leftButtonDown_(false), 55 statsOn_(true), screenShotCounter_(0), timeUntilNextToggle_(0), 56 filtering_(TFO_BILINEAR), aniso_(1), sceneDetailIndex_(0), 57 mouseSensitivity_(0.003), 58 debugOverlay_(0), inputManager_(0), mouse_(0), keyboard_(0), joystick_(0) 59 { 60 61 // SETTING UP THE SCENE 62 63 // create one new SceneManger 64 sceneMgr_ = ogre_->getRoot()->createSceneManager(ST_GENERIC, "backgroundScene_"); 65 66 // background scene (world objects, skybox, lights, etc.) 67 backgroundScene_ = new OrxonoxScene(sceneMgr_); 68 69 // PLAYER SPACESHIP 70 71 // Create a space ship object and its SceneNode. 72 // Some ideas about the steering: The ship should only receive events like 73 // up, down, left, right, roll left, roll right, move down, move up, etc). 74 // Multiple interpretations of these commands would make the game more 75 // but it also makes AI steering more difficult, since for every type of 76 // steering, new methods have to be written. 77 // --> clearly define how a space ship can fly (rolling?, conservation of 78 // impuls?, direct mouse sight steeering?, etc.) 79 // It should also be considered, that the ship should provide another Node 80 // for a camera to be attached (otherwise the spaceship in front of the 81 // would be very static, never moving at all). 82 83 // Construct a new spaceship and give it the node 84 playerShip_ = new OrxonoxShip(sceneMgr_, sceneMgr_->getRootSceneNode() 85 ->createChildSceneNode("ShipNode", Vector3(20, 20, 20))); 86 87 88 // RESOURCE LOADING (using ResourceGroups if implemented) 89 90 // load all resources and create the entities by calling the initialise() 91 // methods for each object (don't initialise in the constructor!). 92 backgroundScene_->initialise(); 93 playerShip_->initialise(); 94 95 96 // CAMERA AND VIEWPORT 97 // TODO: create a camera manager. It should be able to change its position 98 // around the space ship (predefined states would be nice too). And it should 99 // also be able to switch between different locations (like ship, spactator, 100 // certain fixed positions (e.g. finish line, etc.)). These are just ideas. 101 102 // create camera and viewport 103 createCamera(); 104 createViewports(); 105 106 107 // Set default mipmap level (NB some APIs ignore this) 108 TextureManager::getSingleton().setDefaultNumMipmaps(5); 109 110 111 // BULLET LIST FOR THE TEST APPLICATION 112 113 // TODO: Use STL to make life easier. But it works this way too.. 114 bullets_ = new Bullet*[10]; 115 bulletsIndex_ = 0; 116 bulletsSize_ = 10; 117 118 119 // HUMAN INTERFACE 120 121 using namespace OIS; 122 123 debugOverlay_ = OverlayManager::getSingleton() 124 .getByName("Core/DebugOverlay"); 125 126 LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***"); 127 ParamList pl; 128 size_t windowHnd = 0; 129 std::ostringstream windowHndStr; 130 131 window_->getCustomAttribute("WINDOW", &windowHnd); 132 windowHndStr << windowHnd; 133 pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); 134 135 inputManager_ = InputManager::createInputSystem( pl ); 136 137 // Create all devices (We only catch joystick exceptions here, 138 // as, most people have Key/Mouse) 139 keyboard_ = static_cast<Keyboard*>(inputManager_ 140 ->createInputObject( OISKeyboard, false )); 141 mouse_ = static_cast<Mouse*>(inputManager_ 142 ->createInputObject( OISMouse, false )); 143 try { 144 joystick_ = static_cast<JoyStick*>(inputManager_ 145 ->createInputObject( OISJoyStick, false )); 146 } 147 catch(...) { 148 joystick_ = 0; 149 } 150 151 //Set initial mouse clipping size 152 windowResized(window_); 153 154 showDebugOverlay(true); 155 156 // REGISTER THIS OBJECT AS A WINDOW EVENT LISTENER IN OGRE 157 // It will then receive events liek windowClosed, windowResized, etc. 158 WindowEventUtilities::addWindowEventListener(window_, this); 71 namespace Orxonox { 72 using namespace Ogre; 73 74 /** 75 * Contructor only needs the render window and the Root object which are both 76 * the OgreControl object. 77 * Right now the constructor does all the initialisation work. This could also 78 * be done in a new method "initialize()", for whatever purpose. 79 * 80 * 81 * @param ogre_ The OgreControl object holding the render window and the Root 82 */ 83 RunManager::RunManager(OgreControl * ogre) 84 : ogre_(ogre), window_(ogre->getRenderWindow()), leftButtonDown_(false), 85 statsOn_(true), screenShotCounter_(0), timeUntilNextToggle_(0), 86 filtering_(TFO_BILINEAR), aniso_(1), sceneDetailIndex_(0), 87 mouseSensitivity_(0.003), 88 debugOverlay_(0), inputManager_(0), mouse_(0), keyboard_(0), joystick_(0) 89 { 90 91 // SETTING UP THE SCENE 92 93 // create one new SceneManger 94 sceneMgr_ = ogre_->getRoot()->createSceneManager(ST_GENERIC, "backgroundScene_"); 95 96 // background scene (world objects, skybox, lights, etc.) 97 backgroundScene_ = new OrxonoxScene(sceneMgr_); 98 99 // PLAYER SPACESHIP 100 101 // Create a space ship object and its SceneNode. 102 // Some ideas about the steering: The ship should only receive events like 103 // up, down, left, right, roll left, roll right, move down, move up, etc). 104 // Multiple interpretations of these commands would make the game more 105 // but it also makes AI steering more difficult, since for every type of 106 // steering, new methods have to be written. 107 // --> clearly define how a space ship can fly (rolling?, conservation of 108 // impuls?, direct mouse sight steeering?, etc.) 109 // It should also be considered, that the ship should provide another Node 110 // for a camera to be attached (otherwise the spaceship in front of the 111 // would be very static, never moving at all). 112 113 // Construct a new spaceship and give it the node 114 playerShip_ = new OrxonoxShip(sceneMgr_, sceneMgr_->getRootSceneNode() 115 ->createChildSceneNode("ShipNode", Vector3(20, 20, 20))); 116 117 118 // RESOURCE LOADING (using ResourceGroups if implemented) 119 120 // load all resources and create the entities by calling the initialise() 121 // methods for each object (don't initialise in the constructor!). 122 backgroundScene_->initialise(); 123 playerShip_->initialise(); 124 125 126 // CAMERA AND VIEWPORT 127 // TODO: create a camera manager. It should be able to change its position 128 // around the space ship (predefined states would be nice too). And it should 129 // also be able to switch between different locations (like ship, spactator, 130 // certain fixed positions (e.g. finish line, etc.)). These are just ideas. 131 132 // create camera and viewport 133 createCamera(); 134 createViewports(); 135 136 137 // Set default mipmap level (NB some APIs ignore this) 138 TextureManager::getSingleton().setDefaultNumMipmaps(5); 139 140 141 // BULLET LIST FOR THE TEST APPLICATION 142 143 // TODO: Use STL to make life easier. But it works this way too.. 144 bullets_ = new Bullet*[10]; 145 bulletsIndex_ = 0; 146 bulletsSize_ = 10; 147 148 149 // HUMAN INTERFACE 150 151 using namespace OIS; 152 153 debugOverlay_ = OverlayManager::getSingleton() 154 .getByName("Core/DebugOverlay"); 155 156 LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***"); 157 ParamList pl; 158 size_t windowHnd = 0; 159 std::ostringstream windowHndStr; 160 161 window_->getCustomAttribute("WINDOW", &windowHnd); 162 windowHndStr << windowHnd; 163 pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); 164 165 inputManager_ = InputManager::createInputSystem( pl ); 166 167 // Create all devices (We only catch joystick exceptions here, 168 // as, most people have Key/Mouse) 169 keyboard_ = static_cast<Keyboard*>(inputManager_ 170 ->createInputObject( OISKeyboard, false )); 171 mouse_ = static_cast<Mouse*>(inputManager_ 172 ->createInputObject( OISMouse, false )); 173 try { 174 joystick_ = static_cast<JoyStick*>(inputManager_ 175 ->createInputObject( OISJoyStick, false )); 176 } 177 catch(...) { 178 joystick_ = 0; 179 } 180 181 //Set initial mouse clipping size 182 windowResized(window_); 183 184 showDebugOverlay(true); 185 186 // REGISTER THIS OBJECT AS A WINDOW EVENT LISTENER IN OGRE 187 // It will then receive events liek windowClosed, windowResized, etc. 188 WindowEventUtilities::addWindowEventListener(window_, this); 189 } 190 191 /** 192 * Standard destructor. 193 * Removes this object as a window event listener and deletes all created 194 * variables. 195 */ 196 RunManager::~RunManager() 197 { 198 //Remove ourself as a Window listener 199 WindowEventUtilities::removeWindowEventListener(window_, this); 200 windowClosed(window_); 201 202 if (backgroundScene_) 203 delete backgroundScene_; 204 if (playerShip_) 205 delete playerShip_; 206 207 // clean up the bullet list 208 for (int i = 0; i < bulletsIndex_; i++) 209 delete bullets_[i]; 210 delete bullets_; 211 } 212 213 214 /** 215 * Method to compute anyting between 2 frames. 216 * 217 * Everything that needs to be computed during the games happens right here. 218 * The only exception are the listeners (which should only set variables, 219 * not actually do something). 220 * 221 * @param time Absolute play time 222 * @param deltaTime Time passed since last frame 223 * @return Return false to end rendering 224 */ 225 bool RunManager::tick(unsigned long time, float deltaTime) 226 { 227 // synchronize with internal class timer 228 totalTime_ = time; 229 230 // Call tick() for every object 231 // This could be done by registering (needs a factory..) 232 backgroundScene_->tick(time, deltaTime); 233 playerShip_->tick(time, deltaTime); 234 235 236 // Update the 'HUD' 237 updateStats(); 238 239 // update the bullet positions 240 for (int i = 0; i < bulletsIndex_; i++) 241 { 242 bullets_[i]->mNode->translate(bullets_[i]->mSpeed*deltaTime); 243 bullets_[i]->mNode->yaw(Degree(deltaTime*100)); 244 bullets_[i]->mNode->roll(Degree(deltaTime*300)); 245 } 246 247 // HUMAN INTERFACE 248 249 using namespace OIS; 250 251 if(window_->isClosed()) return false; 252 253 //Need to capture/update each device 254 keyboard_->capture(); 255 mouse_->capture(); 256 if( joystick_ ) joystick_->capture(); 257 258 bool buffJ = (joystick_) ? joystick_->buffered() : true; 259 260 //Check if one of the devices is not buffered 261 if( !mouse_->buffered() || !keyboard_->buffered() || !buffJ ) 262 { 263 // one of the input modes is immediate, so setup what 264 // is needed for immediate movement 265 if (timeUntilNextToggle_ >= 0) 266 timeUntilNextToggle_ -= deltaTime; 267 } 268 269 // handle HID devices 270 if( processUnbufferedKeyInput() == false ) 271 return false; 272 if( processUnbufferedMouseInput() == false ) 273 return false; 274 275 // keep rendering 276 return true; 277 } 278 279 280 /** 281 * Adjust mouse clipping area. 282 * This method is called by Ogre without regards of tick()! 283 * Avoid doing too much in this call. 284 * @param rw render window 285 */ 286 void RunManager::windowResized(RenderWindow* rw) 287 { 288 unsigned int width, height, depth; 289 int left, top; 290 rw->getMetrics(width, height, depth, left, top); 291 292 const OIS::MouseState &ms = mouse_->getMouseState(); 293 ms.width = width; 294 ms.height = height; 295 } 296 297 298 /** 299 * Unattach OIS before window shutdown (very important under Linux). 300 * Again, avoid computing a lot in this function. 301 * @param rw Render Window 302 */ 303 void RunManager::windowClosed(RenderWindow* rw) 304 { 305 //Only close for window that created OIS (the main window in these demos) 306 if( rw == window_ ) 307 { 308 if( inputManager_ ) 309 { 310 inputManager_->destroyInputObject( mouse_ ); 311 inputManager_->destroyInputObject( keyboard_ ); 312 inputManager_->destroyInputObject( joystick_ ); 313 314 OIS::InputManager::destroyInputSystem(inputManager_); 315 inputManager_ = 0; 316 } 317 } 318 } 319 320 /** 321 * Processes the Keyboard input. 322 * TODO: Use listeners to improve performance. 323 * A lookup table should be implemented to bind any key to a specific action. 324 * @return Return true to keep rendering 325 */ 326 bool RunManager::processUnbufferedKeyInput() 327 { 328 using namespace OIS; 329 330 if(keyboard_->isKeyDown(KC_A) || keyboard_->isKeyDown(KC_LEFT)) 331 playerShip_->setSideThrust(1); 332 else if(keyboard_->isKeyDown(KC_D) || keyboard_->isKeyDown(KC_RIGHT)) 333 playerShip_->setSideThrust(-1); 334 else 335 playerShip_->setSideThrust(0); 336 337 if(keyboard_->isKeyDown(KC_UP) || keyboard_->isKeyDown(KC_W) ) 338 playerShip_->setMainThrust(1); 339 else if(keyboard_->isKeyDown(KC_DOWN) || keyboard_->isKeyDown(KC_S) ) 340 playerShip_->setMainThrust(-1); 341 else 342 playerShip_->setMainThrust(0); 343 344 if (keyboard_->isKeyDown(KC_C)) 345 playerShip_->setYThrust(1); 346 else if (keyboard_->isKeyDown(KC_SPACE)) 347 playerShip_->setYThrust(-1); 348 else 349 playerShip_->setYThrust(0); 350 351 if( keyboard_->isKeyDown(KC_ESCAPE) || keyboard_->isKeyDown(KC_Q) ) 352 return false; 353 354 if( keyboard_->isKeyDown(KC_F) && timeUntilNextToggle_ <= 0 ) 355 { 356 statsOn_ = !statsOn_; 357 showDebugOverlay(statsOn_); 358 timeUntilNextToggle_ = 1; 359 } 360 361 if( keyboard_->isKeyDown(KC_T) && timeUntilNextToggle_ <= 0 ) 362 { 363 switch(filtering_) 364 { 365 case TFO_BILINEAR: 366 filtering_ = TFO_TRILINEAR; 367 aniso_ = 1; 368 break; 369 case TFO_TRILINEAR: 370 filtering_ = TFO_ANISOTROPIC; 371 aniso_ = 8; 372 break; 373 case TFO_ANISOTROPIC: 374 filtering_ = TFO_BILINEAR; 375 aniso_ = 1; 376 break; 377 default: break; 378 } 379 MaterialManager::getSingleton().setDefaultTextureFiltering(filtering_); 380 MaterialManager::getSingleton().setDefaultAnisotropy(aniso_); 381 382 showDebugOverlay(statsOn_); 383 timeUntilNextToggle_ = 1; 384 } 385 386 if(keyboard_->isKeyDown(KC_SYSRQ) && timeUntilNextToggle_ <= 0) 387 { 388 std::ostringstream ss; 389 ss << "screenshot_" << ++screenShotCounter_ << ".png"; 390 window_->writeContentsToFile(ss.str()); 391 timeUntilNextToggle_ = 0.5; 392 debugText_ = "Saved: " + ss.str(); 393 } 394 395 if(keyboard_->isKeyDown(KC_R) && timeUntilNextToggle_ <=0) 396 { 397 sceneDetailIndex_ = (sceneDetailIndex_+1)%3 ; 398 switch(sceneDetailIndex_) { 399 case 0 : camera_->setPolygonMode(PM_SOLID); break; 400 case 1 : camera_->setPolygonMode(PM_WIREFRAME); break; 401 case 2 : camera_->setPolygonMode(PM_POINTS); break; 402 } 403 timeUntilNextToggle_ = 0.5; 404 } 405 406 static bool displayCameraDetails = false; 407 if(keyboard_->isKeyDown(KC_P) && timeUntilNextToggle_ <= 0) 408 { 409 displayCameraDetails = !displayCameraDetails; 410 timeUntilNextToggle_ = 0.5; 411 if (!displayCameraDetails) 412 debugText_ = ""; 413 } 414 415 // Print camera details 416 if(displayCameraDetails) 417 debugText_ = " | Speed = " 418 + StringConverter::toString(playerShip_->getSpeed()); 419 // debugText_ = "P: " + StringConverter::toString(camera_ 420 // ->getDerivedPosition()) + " " + "O: " 421 // + StringConverter::toString(camera_->getDerivedOrientation()); 422 423 // Return true to continue rendering 424 return true; 425 } 426 427 428 /** 429 * Processes the Mouse input. 430 * TODO: Use listeners to improve performance. 431 * A lookup table should be implemented to bind ANY button or movement 432 * to a specific action. 433 * @return Return true to keep rendering 434 */ 435 bool RunManager::processUnbufferedMouseInput() 436 { 437 using namespace OIS; 438 439 const MouseState &ms = mouse_->getMouseState(); 440 441 // This is a 'hack' to show some flying barrels.. 442 // Usually, the Bullet created by the ship should be managed 443 // by the physics engine.. 444 if (ms.buttonDown(MB_Left) && !leftButtonDown_) 445 { 446 // Prevent continuous fire for the moment. 447 leftButtonDown_ = true; 448 449 // let ship fire one shot with its only weapon (Barrels..) 450 Bullet *tempBullet = playerShip_->fire(); 451 452 // resize array if neccessary (double the size then) 453 if (bulletsIndex_ >= bulletsSize_) 454 { 455 // redimension the array 456 Bullet **tempArray = new Bullet*[2*bulletsSize_]; 457 for (int i = 0; i < bulletsSize_; i++) 458 tempArray[i] = bullets_[i]; 459 bulletsSize_ *= 2; 460 delete bullets_; 461 bullets_ = tempArray; 462 } 463 464 // add the bullet to the list 465 bullets_[bulletsIndex_++] = tempBullet; 466 467 } 468 else if (!ms.buttons) 469 leftButtonDown_ = false; 470 471 // space ship steering. This should definitely be done in the steering object 472 // Simply give it the mouse movements. 473 playerShip_->turnUpAndDown(Radian(ms.Y.rel * mouseSensitivity_)); 474 playerShip_->turnLeftAndRight(Radian(ms.X.rel * mouseSensitivity_)); 475 //playerShip_->mRootNode->pitch(Degree(-ms.Y.rel * 0.13), Ogre::Node::TransformSpace::TS_LOCAL); 476 //playerShip_->mRootNode->yaw(Degree(-ms.X.rel * 0.13), Ogre::Node::TransformSpace::TS_PARENT); 477 478 // keep rendering 479 return true; 480 } 481 482 /** 483 * Show the debug overlay of desired. 484 * @param show Whether or not to show the debug overlay 485 */ 486 void RunManager::showDebugOverlay(bool show) 487 { 488 if (debugOverlay_) 489 { 490 if (show) 491 debugOverlay_->show(); 492 else 493 debugOverlay_->hide(); 494 } 495 } 496 497 498 /** 499 * Show stats (e.g. FPS) in the left lower corner of the screen. 500 * Copied from the ExampleFrameListener.h in the Ogre SDK 501 */ 502 void RunManager::updateStats(void) 503 { 504 static String currFps = "Current FPS: "; 505 static String avgFps = "Average FPS: "; 506 static String bestFps = "Best FPS: "; 507 static String worstFps = "Worst FPS: "; 508 static String tris = "Triangle Count: "; 509 static String batches = "Batch Count: "; 510 511 // update stats when necessary 512 try { 513 OverlayElement* guiAvg = OverlayManager::getSingleton() 514 .getOverlayElement("Core/AverageFps"); 515 OverlayElement* guiCurr = OverlayManager::getSingleton() 516 .getOverlayElement("Core/CurrFps"); 517 OverlayElement* guiBest = OverlayManager::getSingleton() 518 .getOverlayElement("Core/BestFps"); 519 OverlayElement* guiWorst = OverlayManager::getSingleton() 520 .getOverlayElement("Core/WorstFps"); 521 522 const RenderTarget::FrameStats& stats = window_->getStatistics(); 523 guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS)); 524 guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS)); 525 guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS) 526 +" "+StringConverter::toString(stats.bestFrameTime)+" ms"); 527 guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS) 528 +" "+StringConverter::toString(stats.worstFrameTime)+" ms"); 529 530 OverlayElement* guiTris = OverlayManager::getSingleton() 531 .getOverlayElement("Core/NumTris"); 532 guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount)); 533 534 OverlayElement* guiBatches = OverlayManager::getSingleton() 535 .getOverlayElement("Core/NumBatches"); 536 guiBatches->setCaption(batches 537 + StringConverter::toString(stats.batchCount)); 538 539 OverlayElement* guiDbg = OverlayManager::getSingleton() 540 .getOverlayElement("Core/DebugText"); 541 guiDbg->setCaption(debugText_); 542 } 543 catch(...) { /* ignore */ } 544 } 545 546 547 548 /** 549 * Simple camera creator. 550 * playerShip_Node->attachObject(camera_) should no be here! This is what the camera 551 * manager is for. Right now, this method should do just fine, setting the 552 * cam behind the ship. 553 */ 554 void RunManager::createCamera(void) 555 { 556 camera_ = sceneMgr_->createCamera("PlayerCam"); 557 playerShip_->getRootNode()->attachObject(camera_); 558 camera_->setNearClipDistance(5); 559 camera_->setPosition(Vector3(0,10,500)); 560 camera_->lookAt(Vector3(0,0,0)); 561 } 562 563 /** 564 * Simple viewport creator. 565 * TODO: fully understand the concept of viewports concerning orxnox. 566 * E.g. do we need splitscreen mode? 567 * For now the viewport uses the entire render window and is based on the one 568 * camera created so far. 569 */ 570 void RunManager::createViewports(void) 571 { 572 // Create one viewport, entire window 573 Viewport* vp = window_->addViewport(camera_); 574 vp->setBackgroundColour(ColourValue(0,0,0)); 575 576 // Alter the camera aspect ratio to match the viewport 577 camera_->setAspectRatio( 578 Real(vp->getActualWidth()) / Real(vp->getActualHeight())); 579 } 580 159 581 } 160 161 /**162 * Standard destructor.163 * Removes this object as a window event listener and deletes all created164 * variables.165 */166 RunManager::~RunManager()167 {168 //Remove ourself as a Window listener169 WindowEventUtilities::removeWindowEventListener(window_, this);170 windowClosed(window_);171 172 if (backgroundScene_)173 delete backgroundScene_;174 if (playerShip_)175 delete playerShip_;176 177 // clean up the bullet list178 for (int i = 0; i < bulletsIndex_; i++)179 delete bullets_[i];180 delete bullets_;181 }182 183 184 /**185 * Method to compute anyting between 2 frames.186 *187 * Everything that needs to be computed during the games happens right here.188 * The only exception are the listeners (which should only set variables,189 * not actually do something).190 *191 * @param time Absolute play time192 * @param deltaTime Time passed since last frame193 * @return Return false to end rendering194 */195 bool RunManager::tick(unsigned long time, float deltaTime)196 {197 // synchronize with internal class timer198 totalTime_ = time;199 200 // Call tick() for every object201 // This could be done by registering (needs a factory..)202 backgroundScene_->tick(time, deltaTime);203 playerShip_->tick(time, deltaTime);204 205 206 // Update the 'HUD'207 updateStats();208 209 // update the bullet positions210 for (int i = 0; i < bulletsIndex_; i++)211 {212 bullets_[i]->mNode->translate(bullets_[i]->mSpeed*deltaTime);213 bullets_[i]->mNode->yaw(Degree(deltaTime*100));214 bullets_[i]->mNode->roll(Degree(deltaTime*300));215 }216 217 // HUMAN INTERFACE218 219 using namespace OIS;220 221 if(window_->isClosed()) return false;222 223 //Need to capture/update each device224 keyboard_->capture();225 mouse_->capture();226 if( joystick_ ) joystick_->capture();227 228 bool buffJ = (joystick_) ? joystick_->buffered() : true;229 230 //Check if one of the devices is not buffered231 if( !mouse_->buffered() || !keyboard_->buffered() || !buffJ )232 {233 // one of the input modes is immediate, so setup what234 // is needed for immediate movement235 if (timeUntilNextToggle_ >= 0)236 timeUntilNextToggle_ -= deltaTime;237 }238 239 // handle HID devices240 if( processUnbufferedKeyInput() == false )241 return false;242 if( processUnbufferedMouseInput() == false )243 return false;244 245 // keep rendering246 return true;247 }248 249 250 /**251 * Adjust mouse clipping area.252 * This method is called by Ogre without regards of tick()!253 * Avoid doing too much in this call.254 * @param rw render window255 */256 void RunManager::windowResized(RenderWindow* rw)257 {258 unsigned int width, height, depth;259 int left, top;260 rw->getMetrics(width, height, depth, left, top);261 262 const OIS::MouseState &ms = mouse_->getMouseState();263 ms.width = width;264 ms.height = height;265 }266 267 268 /**269 * Unattach OIS before window shutdown (very important under Linux).270 * Again, avoid computing a lot in this function.271 * @param rw Render Window272 */273 void RunManager::windowClosed(RenderWindow* rw)274 {275 //Only close for window that created OIS (the main window in these demos)276 if( rw == window_ )277 {278 if( inputManager_ )279 {280 inputManager_->destroyInputObject( mouse_ );281 inputManager_->destroyInputObject( keyboard_ );282 inputManager_->destroyInputObject( joystick_ );283 284 OIS::InputManager::destroyInputSystem(inputManager_);285 inputManager_ = 0;286 }287 }288 }289 290 /**291 * Processes the Keyboard input.292 * TODO: Use listeners to improve performance.293 * A lookup table should be implemented to bind any key to a specific action.294 * @return Return true to keep rendering295 */296 bool RunManager::processUnbufferedKeyInput()297 {298 using namespace OIS;299 300 if(keyboard_->isKeyDown(KC_A) || keyboard_->isKeyDown(KC_LEFT))301 playerShip_->setSideThrust(1);302 else if(keyboard_->isKeyDown(KC_D) || keyboard_->isKeyDown(KC_RIGHT))303 playerShip_->setSideThrust(-1);304 else305 playerShip_->setSideThrust(0);306 307 if(keyboard_->isKeyDown(KC_UP) || keyboard_->isKeyDown(KC_W) )308 playerShip_->setMainThrust(1);309 else if(keyboard_->isKeyDown(KC_DOWN) || keyboard_->isKeyDown(KC_S) )310 playerShip_->setMainThrust(-1);311 else312 playerShip_->setMainThrust(0);313 314 if (keyboard_->isKeyDown(KC_C))315 playerShip_->setYThrust(1);316 else if (keyboard_->isKeyDown(KC_SPACE))317 playerShip_->setYThrust(-1);318 else319 playerShip_->setYThrust(0);320 321 if( keyboard_->isKeyDown(KC_ESCAPE) || keyboard_->isKeyDown(KC_Q) )322 return false;323 324 if( keyboard_->isKeyDown(KC_F) && timeUntilNextToggle_ <= 0 )325 {326 statsOn_ = !statsOn_;327 showDebugOverlay(statsOn_);328 timeUntilNextToggle_ = 1;329 }330 331 if( keyboard_->isKeyDown(KC_T) && timeUntilNextToggle_ <= 0 )332 {333 switch(filtering_)334 {335 case TFO_BILINEAR:336 filtering_ = TFO_TRILINEAR;337 aniso_ = 1;338 break;339 case TFO_TRILINEAR:340 filtering_ = TFO_ANISOTROPIC;341 aniso_ = 8;342 break;343 case TFO_ANISOTROPIC:344 filtering_ = TFO_BILINEAR;345 aniso_ = 1;346 break;347 default: break;348 }349 MaterialManager::getSingleton().setDefaultTextureFiltering(filtering_);350 MaterialManager::getSingleton().setDefaultAnisotropy(aniso_);351 352 showDebugOverlay(statsOn_);353 timeUntilNextToggle_ = 1;354 }355 356 if(keyboard_->isKeyDown(KC_SYSRQ) && timeUntilNextToggle_ <= 0)357 {358 std::ostringstream ss;359 ss << "screenshot_" << ++screenShotCounter_ << ".png";360 window_->writeContentsToFile(ss.str());361 timeUntilNextToggle_ = 0.5;362 debugText_ = "Saved: " + ss.str();363 }364 365 if(keyboard_->isKeyDown(KC_R) && timeUntilNextToggle_ <=0)366 {367 sceneDetailIndex_ = (sceneDetailIndex_+1)%3 ;368 switch(sceneDetailIndex_) {369 case 0 : camera_->setPolygonMode(PM_SOLID); break;370 case 1 : camera_->setPolygonMode(PM_WIREFRAME); break;371 case 2 : camera_->setPolygonMode(PM_POINTS); break;372 }373 timeUntilNextToggle_ = 0.5;374 }375 376 static bool displayCameraDetails = false;377 if(keyboard_->isKeyDown(KC_P) && timeUntilNextToggle_ <= 0)378 {379 displayCameraDetails = !displayCameraDetails;380 timeUntilNextToggle_ = 0.5;381 if (!displayCameraDetails)382 debugText_ = "";383 }384 385 // Print camera details386 if(displayCameraDetails)387 debugText_ = " | Speed = "388 + StringConverter::toString(playerShip_->getSpeed());389 // debugText_ = "P: " + StringConverter::toString(camera_390 // ->getDerivedPosition()) + " " + "O: "391 // + StringConverter::toString(camera_->getDerivedOrientation());392 393 // Return true to continue rendering394 return true;395 }396 397 398 /**399 * Processes the Mouse input.400 * TODO: Use listeners to improve performance.401 * A lookup table should be implemented to bind ANY button or movement402 * to a specific action.403 * @return Return true to keep rendering404 */405 bool RunManager::processUnbufferedMouseInput()406 {407 using namespace OIS;408 409 const MouseState &ms = mouse_->getMouseState();410 411 // This is a 'hack' to show some flying barrels..412 // Usually, the Bullet created by the ship should be managed413 // by the physics engine..414 if (ms.buttonDown(MB_Left) && !leftButtonDown_)415 {416 // Prevent continuous fire for the moment.417 leftButtonDown_ = true;418 419 // let ship fire one shot with its only weapon (Barrels..)420 Bullet *tempBullet = playerShip_->fire();421 422 // resize array if neccessary (double the size then)423 if (bulletsIndex_ >= bulletsSize_)424 {425 // redimension the array426 Bullet **tempArray = new Bullet*[2*bulletsSize_];427 for (int i = 0; i < bulletsSize_; i++)428 tempArray[i] = bullets_[i];429 bulletsSize_ *= 2;430 delete bullets_;431 bullets_ = tempArray;432 }433 434 // add the bullet to the list435 bullets_[bulletsIndex_++] = tempBullet;436 437 }438 else if (!ms.buttons)439 leftButtonDown_ = false;440 441 // space ship steering. This should definitely be done in the steering object442 // Simply give it the mouse movements.443 playerShip_->turnUpAndDown(Radian(ms.Y.rel * mouseSensitivity_));444 playerShip_->turnLeftAndRight(Radian(ms.X.rel * mouseSensitivity_));445 //playerShip_->mRootNode->pitch(Degree(-ms.Y.rel * 0.13), Ogre::Node::TransformSpace::TS_LOCAL);446 //playerShip_->mRootNode->yaw(Degree(-ms.X.rel * 0.13), Ogre::Node::TransformSpace::TS_PARENT);447 448 // keep rendering449 return true;450 }451 452 /**453 * Show the debug overlay of desired.454 * @param show Whether or not to show the debug overlay455 */456 void RunManager::showDebugOverlay(bool show)457 {458 if (debugOverlay_)459 {460 if (show)461 debugOverlay_->show();462 else463 debugOverlay_->hide();464 }465 }466 467 468 /**469 * Show stats (e.g. FPS) in the left lower corner of the screen.470 * Copied from the ExampleFrameListener.h in the Ogre SDK471 */472 void RunManager::updateStats(void)473 {474 static String currFps = "Current FPS: ";475 static String avgFps = "Average FPS: ";476 static String bestFps = "Best FPS: ";477 static String worstFps = "Worst FPS: ";478 static String tris = "Triangle Count: ";479 static String batches = "Batch Count: ";480 481 // update stats when necessary482 try {483 OverlayElement* guiAvg = OverlayManager::getSingleton()484 .getOverlayElement("Core/AverageFps");485 OverlayElement* guiCurr = OverlayManager::getSingleton()486 .getOverlayElement("Core/CurrFps");487 OverlayElement* guiBest = OverlayManager::getSingleton()488 .getOverlayElement("Core/BestFps");489 OverlayElement* guiWorst = OverlayManager::getSingleton()490 .getOverlayElement("Core/WorstFps");491 492 const RenderTarget::FrameStats& stats = window_->getStatistics();493 guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));494 guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));495 guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)496 +" "+StringConverter::toString(stats.bestFrameTime)+" ms");497 guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)498 +" "+StringConverter::toString(stats.worstFrameTime)+" ms");499 500 OverlayElement* guiTris = OverlayManager::getSingleton()501 .getOverlayElement("Core/NumTris");502 guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));503 504 OverlayElement* guiBatches = OverlayManager::getSingleton()505 .getOverlayElement("Core/NumBatches");506 guiBatches->setCaption(batches507 + StringConverter::toString(stats.batchCount));508 509 OverlayElement* guiDbg = OverlayManager::getSingleton()510 .getOverlayElement("Core/DebugText");511 guiDbg->setCaption(debugText_);512 }513 catch(...) { /* ignore */ }514 }515 516 517 518 /**519 * Simple camera creator.520 * playerShip_Node->attachObject(camera_) should no be here! This is what the camera521 * manager is for. Right now, this method should do just fine, setting the522 * cam behind the ship.523 */524 void RunManager::createCamera(void)525 {526 camera_ = sceneMgr_->createCamera("PlayerCam");527 playerShip_->getRootNode()->attachObject(camera_);528 camera_->setNearClipDistance(5);529 camera_->setPosition(Vector3(0,10,500));530 camera_->lookAt(Vector3(0,0,0));531 }532 533 /**534 * Simple viewport creator.535 * TODO: fully understand the concept of viewports concerning orxnox.536 * E.g. do we need splitscreen mode?537 * For now the viewport uses the entire render window and is based on the one538 * camera created so far.539 */540 void RunManager::createViewports(void)541 {542 // Create one viewport, entire window543 Viewport* vp = window_->addViewport(camera_);544 vp->setBackgroundColour(ColourValue(0,0,0));545 546 // Alter the camera aspect ratio to match the viewport547 camera_->setAspectRatio(548 Real(vp->getActualWidth()) / Real(vp->getActualHeight()));549 }
Note: See TracChangeset
for help on using the changeset viewer.