/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2006 The OGRE Team Also see acknowledgements in Readme.html You may use this sample code for anything you like, it is not covered by the LGPL like the rest of the engine. ----------------------------------------------------------------------------- */ #include "ColladaDemo.h" #include "UIHandler.h" #include "OgreRenderWindow.h" #include "OgreException.h" #include "OgreCamera.h" #include "OgreStringConverter.h" //-------------------------------------------------------------------------- // UIHandler methods that handle all input for this demo. //-------------------------------------------------------------------------- UIHandler::UIHandler(ColladaDemo* main) : mMain(main) , mTranslateVector(Ogre::Vector3::ZERO) , mStatsOn(true) , mNumScreenShots(0) , mMoveScale(0.0f) , mRotScale(0.0f) , mSpeed(MINSPEED) , mAvgFrameTime(0.1) , mSceneDetailIndex(0) , mMoveSpeed(100) , mRotateSpeed(0) , mSkipCount(0) , mUpdateFreq(50) , mLastMousePositionSet(false) , mRotX(0) , mRotY(0) , mFiltering(Ogre::TFO_BILINEAR) , mAniso(1) , mQuit(false) , mLMBDown(false) , mRMBDown(false) , mProcessMovement(false) , mUpdateMovement(false) , mMoveFwd(false) , mMoveBck(false) , mMoveLeft(false) , mMoveRight(false) { // using buffered input OIS::ParamList pl; size_t windowHnd = 0; std::ostringstream windowHndStr; main->getRenderWindow()->getCustomAttribute("WINDOW", &windowHnd); windowHndStr << windowHnd; pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); mInputManager = OIS::InputManager::createInputSystem(windowHnd); mGuiRenderer = CEGUI::System::getSingleton().getRenderer(); mKeyboard = static_cast(mInputManager->createInputObject( OIS::OISKeyboard, true )); mMouse = static_cast(mInputManager->createInputObject( OIS::OISMouse, true )); CEGUI::Rect R=mGuiRenderer->getRect(); //Set Mouse Region.. if window resizes, we should alter this to reflect as well const OIS::MouseState &ms = mMouse->getMouseState(); ms.width = R.getWidth(); ms.height = R.getHeight(); mMouse->setEventCallback(this); mKeyboard->setEventCallback(this); // using buffered input /*mEventProcessor = new Ogre::EventProcessor(); mEventProcessor->initialise(mMain->getRenderWindow()); mEventProcessor->startProcessingEvents(); mEventProcessor->addKeyListener(this); mEventProcessor->addMouseMotionListener(this); mEventProcessor->addMouseListener(this); mInputDevice = mEventProcessor->getInputReader();*/ mGuiAvg = CEGUI::WindowManager::getSingleton().getWindow("OPAverageFPS"); mGuiCurr = CEGUI::WindowManager::getSingleton().getWindow("OPCurrentFPS"); mGuiBest = CEGUI::WindowManager::getSingleton().getWindow("OPBestFPS"); mGuiWorst = CEGUI::WindowManager::getSingleton().getWindow("OPWorstFPS"); mGuiTris = CEGUI::WindowManager::getSingleton().getWindow("OPTriCount"); mGuiDbg = CEGUI::WindowManager::getSingleton().getWindow("OPDebugMsg"); mRoot = CEGUI::WindowManager::getSingleton().getWindow("root"); } //-------------------------------------------------------------------------- UIHandler::~UIHandler() { if(mInputManager) { mInputManager->destroyInputObject(mMouse); mInputManager->destroyInputObject(mKeyboard); OIS::InputManager::destroyInputSystem(mInputManager); mInputManager = 0; } } //-------------------------------------------------------------------------- bool UIHandler::frameStarted(const Ogre::FrameEvent& evt) { mMouse->capture(); mKeyboard->capture(); if (mQuit) return false; else { mSkipCount++; if (mSkipCount >= mUpdateFreq) { mSkipCount = 0; updateStats(); // check to see if window got deactivated because user alt-tabbed out, set it back to active so that render updates // updates are visible even though the window does not have focus if (!mMain->getRenderWindow()->isClosed() && !mMain->getRenderWindow()->isActive()) mMain->getRenderWindow()->setActive(true); } // update movement process if(mProcessMovement || mUpdateMovement) { mTranslateVector.x += mMoveLeft ? mAvgFrameTime * -MOVESPEED : 0; mTranslateVector.x += mMoveRight ? mAvgFrameTime * MOVESPEED : 0; mTranslateVector.z += mMoveFwd ? mAvgFrameTime * -MOVESPEED : 0; mTranslateVector.z += mMoveBck ? mAvgFrameTime * MOVESPEED : 0; Ogre::SceneNode* parentSceneNode = mMain->getActiveCamera()->getParentSceneNode(); if (parentSceneNode) { parentSceneNode->yaw(Ogre::Angle(mRotX)); parentSceneNode->pitch(Ogre::Angle(mRotY)); parentSceneNode->translate(mTranslateVector, Ogre::Node::TS_LOCAL); } else { mMain->getActiveCamera()->yaw(Ogre::Angle(mRotX)); mMain->getActiveCamera()->pitch(Ogre::Angle(mRotY)); mMain->getActiveCamera()->moveRelative(mTranslateVector); } mUpdateMovement = false; mRotX = 0; mRotY = 0; mTranslateVector = Ogre::Vector3::ZERO; } mMain->updateAutoReload(mAvgFrameTime); return true; } } //-------------------------------------------------------------------------- bool UIHandler::mouseMoved (const OIS::MouseEvent &e) { CEGUI::System::getSingleton().injectMouseMove( e.state.X.rel, e.state.Y.rel); CEGUI::System::getSingleton().injectMouseWheelChange(e.state.Z.rel); return true; } //-------------------------------------------------------------------------- bool UIHandler::mouseDragged (const OIS::MouseEvent &e) { return mouseMoved(e); } //-------------------------------------------------------------------------- bool UIHandler::keyPressed (const OIS::KeyEvent &e) { // give 'quitting' priority if (e.key == OIS::KC_ESCAPE) { mQuit = true; return true; } if (e.key== OIS::KC_SYSRQ ) { char tmp[20]; sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots); mMain->getRenderWindow()->writeContentsToFile(tmp); // mMain->getRenderWindow()->setDebugText(Ogre::String("Wrote ") + tmp); } // do event injection CEGUI::System& cegui = CEGUI::System::getSingleton(); // key down cegui.injectKeyDown(e.key); // now character cegui.injectChar(e.text); return true; } //-------------------------------------------------------------------------- bool UIHandler::keyReleased (const OIS::KeyEvent &e) { CEGUI::System::getSingleton().injectKeyUp(e.key); return true; } //-------------------------------------------------------------------------- bool UIHandler::mousePressed (const OIS::MouseEvent &e,OIS::MouseButtonID b) { CEGUI::System::getSingleton().injectMouseButtonDown(convertOgreButtonToCegui(b)); return true; } //-------------------------------------------------------------------------- bool UIHandler::mouseReleased (const OIS::MouseEvent &e,OIS::MouseButtonID b) { CEGUI::System::getSingleton().injectMouseButtonUp(convertOgreButtonToCegui(b)); return true; } //-------------------------------------------------------------------------- CEGUI::MouseButton UIHandler::convertOgreButtonToCegui(OIS::MouseButtonID b) { if(b==(OIS::MB_Left)) return CEGUI::LeftButton; if(b==(OIS::MB_Right)) return CEGUI::RightButton; if(b==(OIS::MB_Middle)) return CEGUI::MiddleButton; if(b==(OIS::MB_Button3)) return CEGUI::X1Button; return CEGUI::LeftButton; } //-------------------------------------------------------------------------- void UIHandler::updateStats() { static CEGUI::String currFps = "Current FPS: "; static CEGUI::String avgFps = "Average FPS: "; static CEGUI::String bestFps = "Best FPS: "; static CEGUI::String worstFps = "Worst FPS: "; static CEGUI::String tris = "Triangle Count: "; const Ogre::RenderTarget::FrameStats& stats = mMain->getRenderWindow()->getStatistics(); mGuiAvg->setText(avgFps + Ogre::StringConverter::toString(stats.avgFPS)); mGuiCurr->setText(currFps + Ogre::StringConverter::toString(stats.lastFPS)); mGuiBest->setText(bestFps + Ogre::StringConverter::toString(stats.bestFPS) + " " + Ogre::StringConverter::toString(stats.bestFrameTime)+" ms"); mGuiWorst->setText(worstFps + Ogre::StringConverter::toString(stats.worstFPS) + " " + Ogre::StringConverter::toString(stats.worstFrameTime)+" ms"); mGuiTris->setText(tris + Ogre::StringConverter::toString(stats.triangleCount)); // mGuiDbg->setText(mMain->getRenderWindow()->getDebugText()); mAvgFrameTime = 1.0f/(stats.avgFPS + 1.0f); if (mAvgFrameTime > 0.1f) mAvgFrameTime = 0.1f; } //-------------------------------------------------------------------------- bool UIHandler::handleMouseMove(const CEGUI::EventArgs& e) { using namespace CEGUI; if( mLMBDown && !mRMBDown) { // rotate camera mRotX += -((const MouseEventArgs&)e).moveDelta.d_x * mAvgFrameTime * 10.0; mRotY += -((const MouseEventArgs&)e).moveDelta.d_y * mAvgFrameTime * 10.0; MouseCursor::getSingleton().setPosition( mLastMousePosition ); mUpdateMovement = true; } else { if( mRMBDown && !mLMBDown) { // translate camera mTranslateVector.x += ((const MouseEventArgs&)e).moveDelta.d_x * mAvgFrameTime * MOVESPEED; mTranslateVector.y += -((const MouseEventArgs&)e).moveDelta.d_y * mAvgFrameTime * MOVESPEED; //mTranslateVector.z = 0; MouseCursor::getSingleton().setPosition( mLastMousePosition ); mUpdateMovement = true; } else { if( mRMBDown && mLMBDown) { mTranslateVector.z += (((const MouseEventArgs&)e).moveDelta.d_x + ((const MouseEventArgs&)e).moveDelta.d_y) * mAvgFrameTime * MOVESPEED; MouseCursor::getSingleton().setPosition( mLastMousePosition ); mUpdateMovement = true; } } } return true; } //-------------------------------------------------------------------------- bool UIHandler::handleMouseButtonUp(const CEGUI::EventArgs& e) { using namespace CEGUI; //Window* wndw = ((const WindowEventArgs&)e).window; if( ((const MouseEventArgs&)e).button == LeftButton ) { mLMBDown = false; } if( ((const MouseEventArgs&)e).button == RightButton ) { mRMBDown = false; } if( !mLMBDown && !mRMBDown ) { MouseCursor::getSingleton().show(); if(mLastMousePositionSet) { MouseCursor::getSingleton().setPosition( mLastMousePosition ); mLastMousePositionSet = false; } mRoot->releaseInput(); } return true; } //-------------------------------------------------------------------------- bool UIHandler::handleMouseButtonDown(const CEGUI::EventArgs& e) { using namespace CEGUI; //Window* wndw = ((const WindowEventArgs&)e).window; if( ((const MouseEventArgs&)e).button == LeftButton ) { mLMBDown = true; } if( ((const MouseEventArgs&)e).button == RightButton ) { mRMBDown = true; } if( mLMBDown || mRMBDown ) { MouseCursor::getSingleton().hide(); if (!mLastMousePositionSet) { mLastMousePosition = MouseCursor::getSingleton().getPosition(); mLastMousePositionSet = true; } mRoot->captureInput(); } return true; } //-------------------------------------------------------------------------- bool UIHandler::handleMouseWheelEvent(const CEGUI::EventArgs& e) { using namespace CEGUI; mTranslateVector.z += ((const MouseEventArgs&)e).wheelChange * -5.0; mUpdateMovement = true; return true; } //-------------------------------------------------------------------------- bool UIHandler::handleKeyDownEvent(const CEGUI::EventArgs& e) { using namespace CEGUI; CheckMovementKeys( ((const KeyEventArgs&)e).scancode , true); return true; } //-------------------------------------------------------------------------- bool UIHandler::handleKeyUpEvent(const CEGUI::EventArgs& e) { using namespace CEGUI; CheckMovementKeys( ((const KeyEventArgs&)e).scancode, false ); return true; } //-------------------------------------------------------------------------- void UIHandler::CheckMovementKeys( CEGUI::Key::Scan scancode, bool state ) { using namespace CEGUI; switch ( scancode ) { case Key::A: mMoveLeft = state; break; case Key::D: mMoveRight = state; break; case Key::S: mMoveBck = state; break; case Key::W: mMoveFwd = state; break; default: break; } mProcessMovement = mMoveLeft || mMoveRight || mMoveFwd || mMoveBck; }