| 1 | #include "RunManager.h" | 
|---|
| 2 |  | 
|---|
| 3 |  | 
|---|
| 4 | // Constructor takes a RenderWindow because it uses that to determine input context | 
|---|
| 5 | RunManager::RunManager(OgreControl * mOgre, bool bufferedKeys, bool bufferedMouse, | 
|---|
| 6 |                                            bool bufferedJoy ) : | 
|---|
| 7 | mOgre(mOgre), mWindow(mOgre->getRenderWindow()), leftButtonDown(false), | 
|---|
| 8 | mStatsOn(true), mNumScreenShots(0), | 
|---|
| 9 | mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR), | 
|---|
| 10 | mAniso(1), mSceneDetailIndex(0), mDebugOverlay(0), | 
|---|
| 11 | mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0) | 
|---|
| 12 | { | 
|---|
| 13 |         // create new SceneManger | 
|---|
| 14 |         mSceneMgr = mOgre->getRoot()->createSceneManager(ST_GENERIC,"mScene"); | 
|---|
| 15 |  | 
|---|
| 16 |  | 
|---|
| 17 |         // create various objects | 
|---|
| 18 |         // background scene | 
|---|
| 19 |         mScene = new OrxonoxScene(mSceneMgr); | 
|---|
| 20 |  | 
|---|
| 21 |         // create a steerable SceneNode for the spaceship to be attached to | 
|---|
| 22 |         mShipNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("ShipNode", Vector3(20, 20, 20)); | 
|---|
| 23 |  | 
|---|
| 24 |         // spaceship | 
|---|
| 25 |         mShip = new OrxonoxShip(mSceneMgr, mShipNode); | 
|---|
| 26 |  | 
|---|
| 27 |         // load all resources and create the entities | 
|---|
| 28 |         mScene->initialise(); | 
|---|
| 29 |         mShip->initialise(); | 
|---|
| 30 |  | 
|---|
| 31 |         // create camera and viewport | 
|---|
| 32 |         createCamera(); | 
|---|
| 33 |         createViewports(); | 
|---|
| 34 |  | 
|---|
| 35 |         // Set default mipmap level (NB some APIs ignore this) | 
|---|
| 36 |         TextureManager::getSingleton().setDefaultNumMipmaps(5); | 
|---|
| 37 |  | 
|---|
| 38 |         // initialise bullets list | 
|---|
| 39 |         mBullets = new Bullet*[10]; | 
|---|
| 40 |         mBulletsPosition = 0; | 
|---|
| 41 |         mBulletsSize = 10; | 
|---|
| 42 |  | 
|---|
| 43 |         using namespace OIS; | 
|---|
| 44 |  | 
|---|
| 45 |         mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); | 
|---|
| 46 |  | 
|---|
| 47 |         LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***"); | 
|---|
| 48 |         ParamList pl; | 
|---|
| 49 |         size_t windowHnd = 0; | 
|---|
| 50 |         std::ostringstream windowHndStr; | 
|---|
| 51 |  | 
|---|
| 52 |         mWindow->getCustomAttribute("WINDOW", &windowHnd); | 
|---|
| 53 |         windowHndStr << windowHnd; | 
|---|
| 54 |         pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); | 
|---|
| 55 |  | 
|---|
| 56 |         mInputManager = InputManager::createInputSystem( pl ); | 
|---|
| 57 |  | 
|---|
| 58 |         //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse) | 
|---|
| 59 |         mKeyboard = static_cast<Keyboard*>(mInputManager->createInputObject( OISKeyboard, bufferedKeys )); | 
|---|
| 60 |         mMouse = static_cast<Mouse*>(mInputManager->createInputObject( OISMouse, bufferedMouse )); | 
|---|
| 61 |         try { | 
|---|
| 62 |                 mJoy = static_cast<JoyStick*>(mInputManager->createInputObject( OISJoyStick, bufferedJoy )); | 
|---|
| 63 |         } | 
|---|
| 64 |         catch(...) { | 
|---|
| 65 |                 mJoy = 0; | 
|---|
| 66 |         } | 
|---|
| 67 |  | 
|---|
| 68 |         //Set initial mouse clipping size | 
|---|
| 69 |         windowResized(mWindow); | 
|---|
| 70 |  | 
|---|
| 71 |         showDebugOverlay(true); | 
|---|
| 72 |  | 
|---|
| 73 |         //Register as a Window listener | 
|---|
| 74 |         WindowEventUtilities::addWindowEventListener(mWindow, this); | 
|---|
| 75 | } | 
|---|
| 76 |  | 
|---|
| 77 |  | 
|---|
| 78 | RunManager::~RunManager() | 
|---|
| 79 | { | 
|---|
| 80 |         //Remove ourself as a Window listener | 
|---|
| 81 |         WindowEventUtilities::removeWindowEventListener(mWindow, this); | 
|---|
| 82 |         windowClosed(mWindow); | 
|---|
| 83 |  | 
|---|
| 84 |         if (mScene) | 
|---|
| 85 |                 delete mScene; | 
|---|
| 86 |  | 
|---|
| 87 |         for (int i = 0; i < mBulletsPosition; i++) | 
|---|
| 88 |                 delete mBullets[i]; | 
|---|
| 89 |         delete mBullets; | 
|---|
| 90 | } | 
|---|
| 91 |  | 
|---|
| 92 |  | 
|---|
| 93 | // Override frameStarted event to process that (don't care about frameEnded) | 
|---|
| 94 | bool RunManager::tick(unsigned long time, float deltaTime) | 
|---|
| 95 | { | 
|---|
| 96 |         mTime = time; | 
|---|
| 97 |  | 
|---|
| 98 |         updateStats(); | 
|---|
| 99 |          | 
|---|
| 100 |         mScene->tick(time, deltaTime); | 
|---|
| 101 |         mShip->tick(time, deltaTime); | 
|---|
| 102 |  | 
|---|
| 103 |         // update the bullet positions | 
|---|
| 104 |         for (int i = 0; i < mBulletsPosition; i++) | 
|---|
| 105 |         { | 
|---|
| 106 |                 mBullets[i]->mNode->translate(mBullets[i]->mSpeed*deltaTime); | 
|---|
| 107 |                 mBullets[i]->mNode->yaw(Degree(deltaTime*100)); | 
|---|
| 108 |                 mBullets[i]->mNode->roll(Degree(deltaTime*300)); | 
|---|
| 109 |         } | 
|---|
| 110 |  | 
|---|
| 111 |         using namespace OIS; | 
|---|
| 112 |  | 
|---|
| 113 |         if(mWindow->isClosed()) return false; | 
|---|
| 114 |  | 
|---|
| 115 |         //Need to capture/update each device | 
|---|
| 116 |         mKeyboard->capture(); | 
|---|
| 117 |         mMouse->capture(); | 
|---|
| 118 |         if( mJoy ) mJoy->capture(); | 
|---|
| 119 |  | 
|---|
| 120 |         bool buffJ = (mJoy) ? mJoy->buffered() : true; | 
|---|
| 121 |  | 
|---|
| 122 |         //Check if one of the devices is not buffered | 
|---|
| 123 |         if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ ) | 
|---|
| 124 |         { | 
|---|
| 125 |                 // one of the input modes is immediate, so setup what is needed for immediate movement | 
|---|
| 126 |                 if (mTimeUntilNextToggle >= 0) | 
|---|
| 127 |                         mTimeUntilNextToggle -= deltaTime; | 
|---|
| 128 |         } | 
|---|
| 129 |  | 
|---|
| 130 |         //Check to see which device is not buffered, and handle it | 
|---|
| 131 |         if( !mKeyboard->buffered() ) | 
|---|
| 132 |                 if( processUnbufferedKeyInput() == false ) | 
|---|
| 133 |                         return false; | 
|---|
| 134 |         if( !mMouse->buffered() ) | 
|---|
| 135 |                 if( processUnbufferedMouseInput() == false ) | 
|---|
| 136 |                         return false; | 
|---|
| 137 |  | 
|---|
| 138 |         return true; | 
|---|
| 139 | } | 
|---|
| 140 |  | 
|---|
| 141 |  | 
|---|
| 142 | //Adjust mouse clipping area | 
|---|
| 143 | void RunManager::windowResized(RenderWindow* rw) | 
|---|
| 144 | { | 
|---|
| 145 |         unsigned int width, height, depth; | 
|---|
| 146 |         int left, top; | 
|---|
| 147 |         rw->getMetrics(width, height, depth, left, top); | 
|---|
| 148 |  | 
|---|
| 149 |         const OIS::MouseState &ms = mMouse->getMouseState(); | 
|---|
| 150 |         ms.width = width; | 
|---|
| 151 |         ms.height = height; | 
|---|
| 152 | } | 
|---|
| 153 |  | 
|---|
| 154 |  | 
|---|
| 155 | //Unattach OIS before window shutdown (very important under Linux) | 
|---|
| 156 | void RunManager::windowClosed(RenderWindow* rw) | 
|---|
| 157 | { | 
|---|
| 158 |         //Only close for window that created OIS (the main window in these demos) | 
|---|
| 159 |         if( rw == mWindow ) | 
|---|
| 160 |         { | 
|---|
| 161 |                 if( mInputManager ) | 
|---|
| 162 |                 { | 
|---|
| 163 |                         mInputManager->destroyInputObject( mMouse ); | 
|---|
| 164 |                         mInputManager->destroyInputObject( mKeyboard ); | 
|---|
| 165 |                         mInputManager->destroyInputObject( mJoy ); | 
|---|
| 166 |  | 
|---|
| 167 |                         OIS::InputManager::destroyInputSystem(mInputManager); | 
|---|
| 168 |                         mInputManager = 0; | 
|---|
| 169 |                 } | 
|---|
| 170 |         } | 
|---|
| 171 | } | 
|---|
| 172 |  | 
|---|
| 173 |  | 
|---|
| 174 | bool RunManager::processUnbufferedKeyInput() | 
|---|
| 175 | { | 
|---|
| 176 |         using namespace OIS; | 
|---|
| 177 |  | 
|---|
| 178 |         if(mKeyboard->isKeyDown(KC_A) || mKeyboard->isKeyDown(KC_LEFT)) | 
|---|
| 179 |                 mShip->setSideThrust(1); | 
|---|
| 180 |         else if(mKeyboard->isKeyDown(KC_D) || mKeyboard->isKeyDown(KC_RIGHT)) | 
|---|
| 181 |                 mShip->setSideThrust(-1); | 
|---|
| 182 |         else | 
|---|
| 183 |                 mShip->setSideThrust(0); | 
|---|
| 184 |  | 
|---|
| 185 |         if(mKeyboard->isKeyDown(KC_UP) || mKeyboard->isKeyDown(KC_W) ) | 
|---|
| 186 |                 mShip->setThrust(1); | 
|---|
| 187 |         else if(mKeyboard->isKeyDown(KC_DOWN) || mKeyboard->isKeyDown(KC_S) ) | 
|---|
| 188 |                 mShip->setThrust(-1); | 
|---|
| 189 |         else | 
|---|
| 190 |                 mShip->setThrust(0); | 
|---|
| 191 |  | 
|---|
| 192 |         if( mKeyboard->isKeyDown(KC_ESCAPE) || mKeyboard->isKeyDown(KC_Q) ) | 
|---|
| 193 |                 return false; | 
|---|
| 194 |  | 
|---|
| 195 |         if( mKeyboard->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0 ) | 
|---|
| 196 |         { | 
|---|
| 197 |                 mStatsOn = !mStatsOn; | 
|---|
| 198 |                 showDebugOverlay(mStatsOn); | 
|---|
| 199 |                 mTimeUntilNextToggle = 1; | 
|---|
| 200 |         } | 
|---|
| 201 |  | 
|---|
| 202 |         if( mKeyboard->isKeyDown(KC_T) && mTimeUntilNextToggle <= 0 ) | 
|---|
| 203 |         { | 
|---|
| 204 |                 switch(mFiltering) | 
|---|
| 205 |                 { | 
|---|
| 206 |                 case TFO_BILINEAR: | 
|---|
| 207 |                         mFiltering = TFO_TRILINEAR; | 
|---|
| 208 |                         mAniso = 1; | 
|---|
| 209 |                         break; | 
|---|
| 210 |                 case TFO_TRILINEAR: | 
|---|
| 211 |                         mFiltering = TFO_ANISOTROPIC; | 
|---|
| 212 |                         mAniso = 8; | 
|---|
| 213 |                         break; | 
|---|
| 214 |                 case TFO_ANISOTROPIC: | 
|---|
| 215 |                         mFiltering = TFO_BILINEAR; | 
|---|
| 216 |                         mAniso = 1; | 
|---|
| 217 |                         break; | 
|---|
| 218 |                 default: break; | 
|---|
| 219 |                 } | 
|---|
| 220 |                 MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering); | 
|---|
| 221 |                 MaterialManager::getSingleton().setDefaultAnisotropy(mAniso); | 
|---|
| 222 |  | 
|---|
| 223 |                 showDebugOverlay(mStatsOn); | 
|---|
| 224 |                 mTimeUntilNextToggle = 1; | 
|---|
| 225 |         } | 
|---|
| 226 |  | 
|---|
| 227 |         if(mKeyboard->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0) | 
|---|
| 228 |         { | 
|---|
| 229 |                 std::ostringstream ss; | 
|---|
| 230 |                 ss << "screenshot_" << ++mNumScreenShots << ".png"; | 
|---|
| 231 |                 mWindow->writeContentsToFile(ss.str()); | 
|---|
| 232 |                 mTimeUntilNextToggle = 0.5; | 
|---|
| 233 |                 mDebugText = "Saved: " + ss.str(); | 
|---|
| 234 |         } | 
|---|
| 235 |  | 
|---|
| 236 |         if(mKeyboard->isKeyDown(KC_R) && mTimeUntilNextToggle <=0) | 
|---|
| 237 |         { | 
|---|
| 238 |                 mSceneDetailIndex = (mSceneDetailIndex+1)%3 ; | 
|---|
| 239 |                 switch(mSceneDetailIndex) { | 
|---|
| 240 |                                 case 0 : mCamera->setPolygonMode(PM_SOLID); break; | 
|---|
| 241 |                                 case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break; | 
|---|
| 242 |                                 case 2 : mCamera->setPolygonMode(PM_POINTS); break; | 
|---|
| 243 |                 } | 
|---|
| 244 |                 mTimeUntilNextToggle = 0.5; | 
|---|
| 245 |         } | 
|---|
| 246 |  | 
|---|
| 247 |         static bool displayCameraDetails = false; | 
|---|
| 248 |         if(mKeyboard->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0) | 
|---|
| 249 |         { | 
|---|
| 250 |                 displayCameraDetails = !displayCameraDetails; | 
|---|
| 251 |                 mTimeUntilNextToggle = 0.5; | 
|---|
| 252 |                 if (!displayCameraDetails) | 
|---|
| 253 |                         mDebugText = ""; | 
|---|
| 254 |         } | 
|---|
| 255 |  | 
|---|
| 256 |         // Print camera details | 
|---|
| 257 |         if(displayCameraDetails) | 
|---|
| 258 |                 mDebugText = StringConverter::toString(mShip->getThrust()) | 
|---|
| 259 |                 + " | Speed = " + StringConverter::toString(mShip->speed); | 
|---|
| 260 |                 // mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) + | 
|---|
| 261 |                 // " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation()); | 
|---|
| 262 |  | 
|---|
| 263 |         // Return true to continue rendering | 
|---|
| 264 |         return true; | 
|---|
| 265 | } | 
|---|
| 266 |  | 
|---|
| 267 |  | 
|---|
| 268 | bool RunManager::processUnbufferedMouseInput() | 
|---|
| 269 | { | 
|---|
| 270 |         using namespace OIS; | 
|---|
| 271 |  | 
|---|
| 272 |         // Rotation factors, may not be used if the second mouse button is pressed | 
|---|
| 273 |         // 2nd mouse button - slide, otherwise rotate | 
|---|
| 274 |         const MouseState &ms = mMouse->getMouseState(); | 
|---|
| 275 |  | 
|---|
| 276 |         if (ms.buttonDown(MB_Left) && !leftButtonDown) | 
|---|
| 277 |         { | 
|---|
| 278 |                 leftButtonDown = true; | 
|---|
| 279 |                 // fire | 
|---|
| 280 |                 Bullet *mTempBullet = mShip->fire(); | 
|---|
| 281 |                 if (mBulletsPosition >= mBulletsSize) | 
|---|
| 282 |                 { | 
|---|
| 283 |                         // redimension the array | 
|---|
| 284 |                         Bullet **mTempArray = new Bullet*[2*mBulletsSize]; | 
|---|
| 285 |                         for (int i = 0; i < mBulletsSize; i++) | 
|---|
| 286 |                                 mTempArray[i] = mBullets[i]; | 
|---|
| 287 |                         mBulletsSize *= 2; | 
|---|
| 288 |                         delete mBullets; | 
|---|
| 289 |                         mBullets = mTempArray; | 
|---|
| 290 |                 } | 
|---|
| 291 |                 mBullets[mBulletsPosition++] = mTempBullet; | 
|---|
| 292 |  | 
|---|
| 293 |         } | 
|---|
| 294 |         else if (!ms.buttons) | 
|---|
| 295 |                 leftButtonDown = false; | 
|---|
| 296 |  | 
|---|
| 297 |         mShip->setYaw(Degree(-ms.X.rel * 0.13)); | 
|---|
| 298 |         mShip->setPitch(Degree(-ms.Y.rel * 0.13)); | 
|---|
| 299 |  | 
|---|
| 300 |         return true; | 
|---|
| 301 | } | 
|---|
| 302 |  | 
|---|
| 303 |  | 
|---|
| 304 | void RunManager::showDebugOverlay(bool show) | 
|---|
| 305 | { | 
|---|
| 306 |         if (mDebugOverlay) | 
|---|
| 307 |         { | 
|---|
| 308 |                 if (show) | 
|---|
| 309 |                         mDebugOverlay->show(); | 
|---|
| 310 |                 else | 
|---|
| 311 |                         mDebugOverlay->hide(); | 
|---|
| 312 |         } | 
|---|
| 313 | } | 
|---|
| 314 |  | 
|---|
| 315 |  | 
|---|
| 316 |  | 
|---|
| 317 | void RunManager::updateStats(void) | 
|---|
| 318 | { | 
|---|
| 319 |         static String currFps = "Current FPS: "; | 
|---|
| 320 |         static String avgFps = "Average FPS: "; | 
|---|
| 321 |         static String bestFps = "Best FPS: "; | 
|---|
| 322 |         static String worstFps = "Worst FPS: "; | 
|---|
| 323 |         static String tris = "Triangle Count: "; | 
|---|
| 324 |         static String batches = "Batch Count: "; | 
|---|
| 325 |  | 
|---|
| 326 |         // update stats when necessary | 
|---|
| 327 |         try { | 
|---|
| 328 |                 OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps"); | 
|---|
| 329 |                 OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps"); | 
|---|
| 330 |                 OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps"); | 
|---|
| 331 |                 OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps"); | 
|---|
| 332 |                 //OverlayElement* asfd = OverlayManager::getSingleton().getOverlayElement( | 
|---|
| 333 |  | 
|---|
| 334 |                 const RenderTarget::FrameStats& stats = mWindow->getStatistics(); | 
|---|
| 335 |                 guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS)); | 
|---|
| 336 |                 guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS)); | 
|---|
| 337 |                 guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS) | 
|---|
| 338 |                         +" "+StringConverter::toString(stats.bestFrameTime)+" ms"); | 
|---|
| 339 |                 guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS) | 
|---|
| 340 |                         +" "+StringConverter::toString(stats.worstFrameTime)+" ms"); | 
|---|
| 341 |  | 
|---|
| 342 |                 OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris"); | 
|---|
| 343 |                 guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount)); | 
|---|
| 344 |  | 
|---|
| 345 |                 OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches"); | 
|---|
| 346 |                 guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount)); | 
|---|
| 347 |  | 
|---|
| 348 |                 OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); | 
|---|
| 349 |                 guiDbg->setCaption(mDebugText); | 
|---|
| 350 |         } | 
|---|
| 351 |         catch(...) { /* ignore */ } | 
|---|
| 352 | } | 
|---|
| 353 |  | 
|---|
| 354 |  | 
|---|
| 355 |  | 
|---|
| 356 | // create camera | 
|---|
| 357 | void RunManager::createCamera(void) | 
|---|
| 358 | { | 
|---|
| 359 |         mCamera = mSceneMgr->createCamera("PlayerCam"); | 
|---|
| 360 |         mShipNode->attachObject(mCamera); | 
|---|
| 361 |         mCamera->setNearClipDistance(5); | 
|---|
| 362 |         mCamera->setPosition(Vector3(0,10,500)); | 
|---|
| 363 |         mCamera->lookAt(Vector3(0,0,0)); | 
|---|
| 364 | } | 
|---|
| 365 |  | 
|---|
| 366 |  | 
|---|
| 367 | void RunManager::createViewports(void) | 
|---|
| 368 | { | 
|---|
| 369 |         // Create one viewport, entire window | 
|---|
| 370 |         Viewport* vp = mWindow->addViewport(mCamera); | 
|---|
| 371 |         vp->setBackgroundColour(ColourValue(0,0,0)); | 
|---|
| 372 |  | 
|---|
| 373 |         // Alter the camera aspect ratio to match the viewport | 
|---|
| 374 |         mCamera->setAspectRatio( | 
|---|
| 375 |                 Real(vp->getActualWidth()) / Real(vp->getActualHeight())); | 
|---|
| 376 | } | 
|---|
| 377 |  | 
|---|
| 378 |  | 
|---|