#include #include #include <../CEGUIRenderer/include/OgreCEGUIRenderer.h> #include <../CEGUIRenderer/include/OgreCEGUIResourceProvider.h> #include <../CEGUIRenderer/include/OgreCEGUITexture.h> #include #include "TerrainMouseQueryListener.h" // output file for frame info const char* frames_out_filename = "frame.out"; // output file for object positions / orientations const char* objects_out_filename = "objects.out"; #define KEY_PRESSED(_key, _timeDelay, _macro) \ { \ if (mInputDevice->isKeyDown(_key) && mTimeDelay <= 0) \ { \ mTimeDelay = _timeDelay; \ _macro ; \ } \ } String mCurrentAlgorithmCaptions[GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS] = { "View Frustum Culling", "Stop and Wait Culling", "Coherent Hierarchical Culling" }; //----------------------------------------------------------------------- TerrainMouseQueryListener::TerrainMouseQueryListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer, TerrainContentGenerator *sceneGenerator, Camera *vizCamera, SceneNode *camNode, Light *sunLight): mCamera(cam), mWindow(win), mNumScreenShots(0), mTimeDelay(0), mSceneDetailIndex(0), mMoveScale(0.0f), mRotScale(0.0f), mTranslateVector(Vector3::ZERO), mAniso(1), mFiltering(TFO_BILINEAR), mGUIRenderer(renderer), mSceneMgr(sceneManager), mCurrentObject(NULL), mTerrainContentGenerator(sceneGenerator), mVisibilityThreshold(0), mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING), //mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING), mNodeVizMode(NODEVIZ_NONE), mVizCameraHeight(Real(2500.0)), mCamNode(camNode), mAppState(WALKTHROUGH), mCurrentFrame(0), mTimeElapsed(0), mRotateSpeed(72), mMoveSpeed(50), mVizCamera(vizCamera), mStatsOn(true), mShutdownRequested(false), mLMouseDown(false), mRMouseDown(false), mShowOctree(false), mUseDepthPass(false), mUseOptimization(true), mShowVisualization(false), mCullCamera(false), mRecord(false), mUseShadows(false), mShowHelp(false), mDisplayCameraDetails(false), mVisualizeCulledNodes(false), mSunLight(sunLight) { mInputDevice = PlatformManager::getSingleton().createInputReader(); mInputDevice->initialise(win, true, true); /* mEventProcessor->addMouseListener(this); mEventProcessor->addMouseMotionListener(this); mEventProcessor->addKeyListener(this); */ // create ray query executor, used to place objects in terrain mRayQueryExecutor = new RayQueryExecutor(mSceneMgr); mHelpOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/HelpOverlay"); mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); //-- visibility culling stats overlay mCullStatsOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/DemoOverlay"); mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/AlgorithmInfo"); mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ThresholdInfo"); mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/FrustumCulledNodesInfo"); mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueryCulledNodesInfo"); mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/TraversedNodesInfo"); mHierarchyNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/HierarchyNodesInfo"); mRenderedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/RenderedNodesInfo"); mObjectsInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ObjectsInfo"); mUseOptimizationInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/UseOptimizationInfo"); mUseDepthPassInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/UseDepthPassInfo"); mQueriesIssuedInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueriesIssuedInfo"); mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]); mThresholdInfo->setCaption(": 0"); mFrustumCulledNodesInfo->setCaption(": 0"); mQueryCulledNodesInfo->setCaption(": 0"); mTraversedNodesInfo->setCaption(": 0"); mHierarchyNodesInfo->setCaption(": 0"); mRenderedNodesInfo->setCaption(": 0"); mObjectsInfo->setCaption(": 0"); mUseOptimizationInfo->setCaption(": true"); mUseDepthPassInfo->setCaption(": false"); mQueriesIssuedInfo->setCaption(": 0"); // show stats overlays showStats(true); //mHelpOverlay->show(); // set culling algorithm type setAlgorithm(mCurrentAlgorithm); // set scene manager options mSceneMgr->setOption("UseOptimization", &mUseOptimization); // apply delayed rendering (i.e., transparents after hierarchical culling pass) // only if optimization is not used bool delayRenderTransparents = !mUseOptimization; mSceneMgr->setOption("DelayRenderTransparents", &delayRenderTransparents); mSceneMgr->setOption("UseDepthPass", &mUseDepthPass); mSceneMgr->setOption("ShowOctree", &mShowOctree); mSceneMgr->setOption("CullCamera", &mCullCamera); mSceneMgr->setOption("ShowVisualization", &mShowVisualization); } //----------------------------------------------------------------------- TerrainMouseQueryListener::~TerrainMouseQueryListener() { PlatformManager::getSingleton().destroyInputReader(mInputDevice); delete mRayQueryExecutor; } //----------------------------------------------------------------------- void TerrainMouseQueryListener::mouseMoved(MouseEvent *e) { // Update CEGUI with the mouse motion CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight()); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::mousePressed(MouseEvent* e) { // Left mouse button down if (e->getButtonID() & InputEvent::BUTTON0_MASK) { CEGUI::MouseCursor::getSingleton().hide(); // Setup the ray scene query Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY()); Vector3 queryResult; // Get results, create a node/entity on the position mCurrentObject = mTerrainContentGenerator->GenerateSceneObject( mouseRay.getOrigin(), Vector3(0,0,0), "robot"); mLMouseDown = true; } // Right mouse button down else if (e->getButtonID() & InputEvent::BUTTON1_MASK) { CEGUI::MouseCursor::getSingleton().hide(); mRMouseDown = true; } } // mousePressed //----------------------------------------------------------------------- void TerrainMouseQueryListener::mouseReleased(MouseEvent* e) { // Left mouse button up if (e->getButtonID() & InputEvent::BUTTON0_MASK) { CEGUI::MouseCursor::getSingleton().show(); mLMouseDown = false; } // Right mouse button up else if (e->getButtonID() & InputEvent::BUTTON1_MASK) { CEGUI::MouseCursor::getSingleton().show(); mRMouseDown = false; } } //----------------------------------------------------------------------- void TerrainMouseQueryListener::mouseDragged(MouseEvent *e) { // If we are dragging the left mouse button. if (mLMouseDown) { Vector3 queryResult; Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY()); if (mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay)) { if (mCurrentObject) { mCurrentObject->setPosition(queryResult); } } } // If we are dragging the right mouse button. if (mRMouseDown) { //mCamera->yaw(-e->getRelX() * mRotateSpeed); //mCamera->pitch(-e->getRelY() * mRotateSpeed); mCamNode->yaw(-e->getRelX() * mRotateSpeed); mCamNode->pitch(-e->getRelY() * mRotateSpeed); } } //----------------------------------------------------------------------- bool TerrainMouseQueryListener::frameStarted(const FrameEvent &evt) { if (mWindow->isClosed()) return false; mInputDevice->capture(); //-- setup what is needed for immediate mouse/key movement if (mTimeDelay >= 0) mTimeDelay -= evt.timeSinceLastFrame; // If this is the first frame, pick a speed if (evt.timeSinceLastFrame == 0) { mMoveScale = 1; mRotScale = 0.1; } // Otherwise scale movement units by time passed since last frame else { // Move about 100 units per second, mMoveScale = mMoveSpeed * evt.timeSinceLastFrame; // Take about 10 seconds for full rotation mRotScale = mRotateSpeed * evt.timeSinceLastFrame; } mRotX = 0; mRotY = 0; mTranslateVector = Vector3::ZERO; if (!processUnbufferedKeyInput(evt)) { return false; } if (!processUnbufferedMouseInput(evt)) { return false; } if (mShowVisualization) { // important for visualization => draw octree bounding boxes mSceneMgr->setOption("ShowOctree", &mShowVisualization); // also render nodew content? //mSceneMgr->setOption("RenderNodesForViz", &mRenderNodesForViz); // -- setup visualization camera mVizCamera->setPosition(0, 0, 0); mVizCamera->setOrientation(Quaternion::IDENTITY); Vector3 camPos = mCamNode->getPosition(); mVizCamera->setPosition(camPos.x, mVizCameraHeight, camPos.z); // point down -Z axis mVizCamera->pitch(Radian(Degree(270.0))); // rotation arounnd X axis mVizCamera->yaw(Math::ATan2(-mCamera->getDerivedDirection().x, -mCamera->getDerivedDirection().z)); // move by a constant so view plane is on bottom of viewport mVizCamera->moveRelative(Vector3(0, 800, 0)); } switch (mAppState) { case REPLAY: setCurrentFrameInfo(evt.timeSinceLastFrame); break; case WALKTHROUGH: //-- if we are recording camera status per frame if (mRecord) { addFrameInfo(mCamNode, evt.timeSinceLastFrame); // print recording message mWindow->setDebugText("Recording frame " + StringConverter::toString(mFrameInfo.size() - 1)); } moveCamera(); Clamp2Terrain(); break; default: break; }; return true; } //----------------------------------------------------------------------- void TerrainMouseQueryListener::Clamp2Terrain() { // clamp to terrain Vector3 camPos = mCamNode->getPosition(); Vector3 queryResult; if (mRayQueryExecutor->executeRayQuery(&queryResult, Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y)) { mCamNode->setPosition(camPos.x, queryResult.y + 10, camPos.z); } } //----------------------------------------------------------------------- bool TerrainMouseQueryListener::frameEnded(const FrameEvent& evt) { if (mShutdownRequested) return false; updateStats(); return true; } //----------------------------------------------------------------------- void TerrainMouseQueryListener::moveCamera() { // move node rather than camera so orientation is right in the visualization mCamNode->yaw(mRotX); mCamNode->pitch(mRotY); mCamNode->translate(mCamNode->getLocalAxes(), mTranslateVector); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::writeFrames() { std::ofstream ofstr(frames_out_filename); std::vector::const_iterator it, it_end; it_end = mFrameInfo.end(); for(it = mFrameInfo.begin(); it < it_end; ++it) { ofstr << StringConverter::toString((*it).position) << " " << StringConverter::toString((*it).orientation) << " " << StringConverter::toString((*it).timeElapsed) << "\n"; } ofstr.close(); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::loadFrames() { std::ifstream ifstr(frames_out_filename); char line[256]; frame_info info; // reset current values mFrameInfo.clear(); mCurrentFrame = 0; while (!ifstr.eof()) { ifstr.getline(line, 256); sscanf(line, "%f %f %f %f %f %f %f %f", &info.position.x, &info.position.y, &info.position.z, &info.orientation.w, &info.orientation.x, &info.orientation.y, &info.orientation.z, &info.timeElapsed); mFrameInfo.push_back(info); /* std::stringstream d; d << StringConverter::toString(info.position) << " " << StringConverter::toString(info.orientation); LogManager::getSingleton().logMessage(d.str()); */ } ifstr.close(); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::nextAppState() { mCurrentFrame = 0; // if last state was replay state if (mAppState == REPLAY) { // reset debug text and write frame info to file mWindow->setDebugText(""); writeFrames(); //-- write out stats for recorded walkthrough std::stringstream d; d << "Algorithm: " << mCurrentAlgorithmCaptions[mCurrentAlgorithm] << "\n" << "avg. FPS: " << mWindow->getAverageFPS() << "\n" << "best FPS: " << mWindow->getBestFPS() << "\n" << "worst FPS: " << mWindow->getWorstFPS() << "\n" << "best frame time: " << mWindow->getBestFrameTime() << "\n" << "worst frame time: " << mWindow->getWorstFrameTime(); LogManager::getSingleton().logMessage(d.str()); } //-- set the next státe mAppState = (mAppState + 1) % STATE_NUM; // replay recorded walkthrough if (mAppState == REPLAY) { // no recording during replay mRecord = false; // load recorded walkthrough if (mFrameInfo.size() == 0) { loadFrames(); } // if there are no recorded frames => set next state if (mFrameInfo.size() == 0) { nextAppState(); } else { mWindow->setDebugText("Replay"); // reset, because we measure fps stats during walkthrough mWindow->resetStatistics(); //-- initialise frame data mTimeElapsed = 0; mCamNode->setPosition(mFrameInfo[0].position); mCamNode->setOrientation(mFrameInfo[0].orientation); } } } //----------------------------------------------------------------------- void TerrainMouseQueryListener::toggleRecord() { mRecord = !mRecord; // clear previous camera path if (mRecord) mFrameInfo.clear(); else mWindow->setDebugText(""); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::changeThreshold(int incr) { mVisibilityThreshold += incr; if(mVisibilityThreshold < 0) mVisibilityThreshold = 0; char str[100]; sprintf(str,": %d", mVisibilityThreshold); mSceneMgr->setOption("Threshold", &mVisibilityThreshold); mThresholdInfo->setCaption(str); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::zoomVizCamera(int zoom) { mVizCameraHeight += zoom; if(mVizCameraHeight < 0) mVizCameraHeight = 0; } //----------------------------------------------------------------------- void TerrainMouseQueryListener::nextAlgorithm() { mCurrentAlgorithm = (mCurrentAlgorithm + 1) % GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS, setAlgorithm(mCurrentAlgorithm); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::setAlgorithm(int algorithm) { mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]); mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::updateStats() { unsigned int opt = 0; char str[100]; static String currFps = "Current FPS: "; static String avgFps = "Average FPS: "; static String bestFps = "Best FPS: "; static String worstFps = "Worst FPS: "; static String tris = "Triangle Count: "; // update stats when necessary try { OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps"); OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps"); OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps"); OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps"); const RenderTarget::FrameStats& stats = mWindow->getStatistics(); guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS)); guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS)); guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS) +" "+StringConverter::toString(stats.bestFrameTime)+" ms"); guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS) +" "+StringConverter::toString(stats.worstFrameTime)+" ms"); OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris"); guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount)); OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); guiDbg->setCaption(mWindow->getDebugText()); //-- culling stats mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt); mFrustumCulledNodesInfo->setCaption(str); mSceneMgr->getOption("NumQueriesIssued", &opt); sprintf(str,": %d", opt); mQueriesIssuedInfo->setCaption(str); mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt); mQueryCulledNodesInfo->setCaption(str); mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt); mTraversedNodesInfo->setCaption(str); mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt); mHierarchyNodesInfo->setCaption(str); mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt); mRenderedNodesInfo->setCaption(str); sprintf(str,": %d", mTerrainContentGenerator->GetObjectCount()); mObjectsInfo->setCaption(str); } catch(...) { // ignore } } //----------------------------------------------------------------------- void TerrainMouseQueryListener::toggleUseOptimization() { mUseOptimization = !mUseOptimization; mSceneMgr->setOption("UseOptimization", &mUseOptimization); // delayed rendering (i.e., render transparents afterwards) allows // no optimization which tests geometry instead of aabb bool delayedRendering = !mUseOptimization; mSceneMgr->setOption("DelayRenderTransparents", &delayedRendering); if (mUseOptimization) mUseOptimizationInfo->setCaption(": true"); else mUseOptimizationInfo->setCaption(": false"); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::toggleShowOctree() { mShowOctree = !mShowOctree; mSceneMgr->setOption("ShowOctree", &mShowOctree); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::toggleUseDepthPass() { mUseDepthPass = !mUseDepthPass; mSceneMgr->setOption("UseDepthPass", &mUseDepthPass); if (mUseDepthPass) { mUseDepthPassInfo->setCaption(": true"); } else { mUseDepthPassInfo->setCaption(": false"); } } //----------------------------------------------------------------------- void TerrainMouseQueryListener::toggleShowViz() { mShowVisualization = !mShowVisualization; mVisualizeCulledNodes = !mVisualizeCulledNodes; // create viewport with priority VIZ_VIEWPORT_Z_ORDER: // will be rendered over standard viewport if (mShowVisualization) { Viewport *vizvp = mWindow->addViewport(mVizCamera, VIZ_VIEWPORT_Z_ORDER, 0.6, 0.6, 0.4, 0.4); vizvp->setBackgroundColour(ColourValue(0.0, 0.3, 0.2, 1)); vizvp->setOverlaysEnabled(false); // Alter the camera aspect ratio to match the viewport mVizCamera->setAspectRatio(Real(vizvp->getActualWidth()) / Real(vizvp->getActualHeight())); mSceneMgr->setOption("VisualizeCulledNodes", &mVisualizeCulledNodes); //vizvp->setClearEveryFrame(false); // Create a skyplane (for visualization background) /* Plane plane; plane.d = -1000; plane.normal = Vector3::UNIT_Y; mSceneMgr->setSkyPlane(true, plane, "Examples/TransparentTest", 4000, 75, false); */ } else { mWindow->removeViewport(VIZ_VIEWPORT_Z_ORDER); // if octree was enabled for visualization purpose, reset now mSceneMgr->setOption("ShowOctree", &mShowOctree); } } //----------------------------------------------------------------------- void TerrainMouseQueryListener::toggleUseShadows() { mUseShadows = !mUseShadows; mSunLight->setCastShadows(mUseShadows); if (mUseShadows) { mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); } else { mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); } } //----------------------------------------------------------------------- void TerrainMouseQueryListener::nextNodeVizMode() { mNodeVizMode = (mNodeVizMode + 1) % NODEVIZ_MODES_NUM; bool renderNodesForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES) || (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT); bool renderNodesContentForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT); //bool renderNodesContentForViz = mNodeVizMode == NODEVIZ_RENDER_GEOMETRY; mSceneMgr->setOption("RenderNodesForViz", &renderNodesForViz); mSceneMgr->setOption("RenderNodesContentForViz", &renderNodesContentForViz); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::keyPressed(KeyEvent* e) { if(e->getKey() == KC_ESCAPE) { mShutdownRequested = true; e->consume(); return; } CEGUI::System::getSingleton().injectKeyDown(e->getKey()); CEGUI::System::getSingleton().injectChar(e->getKeyChar()); e->consume(); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::keyReleased(KeyEvent* e) { CEGUI::System::getSingleton().injectKeyUp(e->getKey()); e->consume(); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::keyClicked(KeyEvent* e) { // Do nothing e->consume(); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::addFrameInfo(SceneNode *camNode, Real timeElapsed) { frame_info info; info.orientation = mCamNode->getOrientation(); info.position = mCamNode->getPosition(); info.timeElapsed = timeElapsed; mFrameInfo.push_back(info); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::setCurrentFrameInfo(Real timeElapsed) { //-- find current frame relative to elapsed frame time mTimeElapsed -= timeElapsed; while ((mTimeElapsed <= 0) && (mCurrentFrame < (int)mFrameInfo.size() - 1)) { mTimeElapsed += mFrameInfo[mCurrentFrame ++].timeElapsed; } frame_info new_frame = mFrameInfo[mCurrentFrame]; frame_info old_frame = mFrameInfo[mCurrentFrame - 1]; //-- interpolate frames Real factor = 1; if (old_frame.timeElapsed > 0) factor = mTimeElapsed / old_frame.timeElapsed; Vector3 camPos = old_frame.position + factor * (new_frame.position - old_frame.position); Quaternion camOrienation = Quaternion::Slerp(factor, old_frame.orientation, new_frame.orientation, true); mCamNode->setPosition(camPos); mCamNode->setOrientation(camOrienation); // stop replay after a full walkthrough if (mCurrentFrame == (int)mFrameInfo.size() - 1) { nextAppState(); } } //----------------------------------------------------------------------- bool TerrainMouseQueryListener::processUnbufferedKeyInput(const FrameEvent& evt) { if (mInputDevice->isKeyDown(KC_ESCAPE)) { return false; } /* Move camera forward by keypress. */ if (mInputDevice->isKeyDown(KC_UP)) { mTranslateVector.z = -mMoveScale; } /* Move camera backward by keypress. */ if (mInputDevice->isKeyDown(KC_DOWN)) { mTranslateVector.z = mMoveScale; } if (mInputDevice->isKeyDown(KC_RIGHT)) { mCamNode->yaw(-mRotScale); } if (mInputDevice->isKeyDown(KC_LEFT)) { mCamNode->yaw(mRotScale); } KEY_PRESSED(KC_SPACE, 0.3, nextAlgorithm()); KEY_PRESSED(KC_F, 0.3, nextFilter()); KEY_PRESSED(KC_R, 0.3, nextSceneDetailLevel()); KEY_PRESSED(KC_P, 0.3, toggleDisplayCameraDetails()); KEY_PRESSED(KC_O, 0.3, toggleUseOptimization()); KEY_PRESSED(KC_T, 0.3, toggleShowOctree()); KEY_PRESSED(KC_X, 0.3, toggleUseDepthPass()); KEY_PRESSED(KC_S, 0.3, toggleUseShadows()); KEY_PRESSED(KC_SUBTRACT, 0, changeThreshold(-10)); KEY_PRESSED(KC_ADD, 0, changeThreshold(10)); //-- visualization KEY_PRESSED(KC_1, 0.3, toggleShowViz()); KEY_PRESSED(KC_2, 0.3, nextNodeVizMode()); KEY_PRESSED(KC_3, 0, zoomVizCamera(50)); KEY_PRESSED(KC_4, 0, zoomVizCamera(-50)); KEY_PRESSED(KC_F1, 0.3, toggleShowHelp()); KEY_PRESSED(KC_F2, 0.3, toggleShowStats()); KEY_PRESSED(KC_F3, 0.3, nextAppState()); KEY_PRESSED(KC_F4, 0.3, toggleRecord()); KEY_PRESSED(KC_F11, 0.3, takeScreenShot()); KEY_PRESSED(KC_F12, 0.3, mTerrainContentGenerator->WriteObjects(objects_out_filename)); //KEY_PRESSED(KC_F3, 0.3, writeFrames()); //KEY_PRESSED(KC_F4, 0.3, loadFrames()); if (mDisplayCameraDetails) { // Print camera details mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) + " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation())); } // Return true to continue rendering return true; } //----------------------------------------------------------------------- void TerrainMouseQueryListener::nextFilter() { switch(mFiltering) { case TFO_BILINEAR: mFiltering = TFO_TRILINEAR; mAniso = 1; break; case TFO_TRILINEAR: mFiltering = TFO_ANISOTROPIC; mAniso = 8; break; case TFO_ANISOTROPIC: mFiltering = TFO_BILINEAR; mAniso = 1; break; default: break; } MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering); MaterialManager::getSingleton().setDefaultAnisotropy(mAniso); showStats(mStatsOn); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::nextSceneDetailLevel() { mSceneDetailIndex = (mSceneDetailIndex+1)%3 ; switch(mSceneDetailIndex) { case 0 : mCamera->setDetailLevel(SDL_SOLID) ; break ; case 1 : mCamera->setDetailLevel(SDL_WIREFRAME) ; break ; case 2 : mCamera->setDetailLevel(SDL_POINTS) ; break ; } } //----------------------------------------------------------------------- void TerrainMouseQueryListener::takeScreenShot() { char tmp[20]; sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots); mWindow->writeContentsToFile(tmp); mWindow->setDebugText(String("Wrote ") + tmp); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::toggleDisplayCameraDetails() { mDisplayCameraDetails = !mDisplayCameraDetails; if (!mDisplayCameraDetails) mWindow->setDebugText(""); } //----------------------------------------------------------------------- bool TerrainMouseQueryListener::processUnbufferedMouseInput(const FrameEvent& evt) { /* Rotation factors, may not be used if the second mouse button is pressed. */ /* If the second mouse button is pressed, then the mouse movement results in sliding the camera, otherwise we rotate. */ if(mInputDevice->getMouseButton(1)) { mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13; mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13; } else { mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13); mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13); } return true; } //----------------------------------------------------------------------- void TerrainMouseQueryListener::showStats(bool show) { if (mDebugOverlay && mCullStatsOverlay) { if (show) { mDebugOverlay->show(); mCullStatsOverlay->show(); } else { mDebugOverlay->hide(); mCullStatsOverlay->hide(); } } } //----------------------------------------------------------------------- void TerrainMouseQueryListener::toggleShowStats() { mStatsOn = !mStatsOn; showStats(mStatsOn); } //----------------------------------------------------------------------- void TerrainMouseQueryListener::toggleShowHelp() { mShowHelp = !mShowHelp; if (mShowHelp) { mHelpOverlay->show(); } else { mHelpOverlay->hide(); } }