source: trunk/VUT/work/TestCullingTerrain/TestCullingTerrainApplication.cpp @ 94

Revision 94, 16.5 KB checked in by mattausch, 19 years ago (diff)
Line 
1/**
2    \file
3        TestCullingTerrainApplication.cpp
4    \brief
5        Tests the visibility culling algorithm
6*/
7
8#include <OgreNoMemoryMacros.h>
9#include <CEGUI/CEGUI.h>
10#include <../CEGUIRenderer/include/OgreCEGUIRenderer.h>
11#include <../CEGUIRenderer/include/OgreCEGUIResourceProvider.h>
12#include <../CEGUIRenderer/include/OgreCEGUITexture.h>
13#include <OgreMemoryMacros.h>
14
15#include "Ogre.h"
16#include "TestCullingTerrainApplication.h"
17
18#define WIN32_LEAN_AND_MEAN
19#include <windows.h>
20
21
22/*******************************************************/
23/*     TestCullingTerrainApplication implementation    */
24/*******************************************************/
25TestCullingTerrainApplication::~TestCullingTerrainApplication()
26{
27        if(mTerrainContentGenerator)
28                delete mTerrainContentGenerator;
29        //if(mVisualizationCamera) delete mVisualizationCamera;
30}
31//-----------------------------------------------------------------------
32void TestCullingTerrainApplication::createCamera()
33{
34        // Create the camera
35        mCamera = mSceneMgr->createCamera("CullCamera");
36       
37        // Set a nice viewpoint
38        mCamera->setPosition(707, 2500, 528);
39        mCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
40       
41        //--create cull camera
42        mVisualizationCamera = mSceneMgr->createCamera("VisualizationCamera");
43        mVisualizationCamera->setPosition(707, 2500, 528);
44        mVisualizationCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
45
46        mVisualizationCamera->setNearClipDistance(1);
47        mCamera->setNearClipDistance(1);
48
49        // Infinite far plane?
50        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
51        {
52                mVisualizationCamera->setFarClipDistance(0);
53                mCamera->setFarClipDistance(0);
54        }
55        else
56        {
57                 mVisualizationCamera->setFarClipDistance(1000);
58                 mCamera->setFarClipDistance(1000);
59        }
60       
61}
62//-----------------------------------------------------------------------
63void TestCullingTerrainApplication::createScene()
64{
65        // Set ambient light
66        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
67       
68        // Create a light
69        Light* l = mSceneMgr->createLight("MainLight");
70        // Accept default settings: point light, white diffuse, just set position
71        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
72        //  other objects, but I don't
73        l->setPosition(20,80,50);
74
75        // --Fog
76        // NB it's VERY important to set this before calling setWorldGeometry
77        // because the vertex program picked will be different
78        ColourValue fadeColour(0.93, 0.86, 0.76);
79        mWindow->getViewport(0)->setBackgroundColour(fadeColour);
80        //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
81       
82        // Create a skybox
83    mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000, false);
84        //mSceneMgr->setSkyDome( true, "Examples/CloudySky", 5, 8, 500, false );
85
86        /*      // Define the required skyplane
87        Plane plane;
88        // 5000 world units from the camera
89        plane.d = 5000;
90        // Above the camera, facing down
91        plane.normal = -Vector3::UNIT_Y;
92        // Create the plane 10000 units wide, tile the texture 3 times
93    mSceneMgr->setSkyPlane(true, plane, "Examples/SpaceSkyPlane",10000,3);*/
94
95        std::string terrain_cfg("terrain.cfg");
96#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
97        terrain_cfg = mResourcePath + terrain_cfg;
98#endif
99        mSceneMgr->setWorldGeometry(terrain_cfg);
100       
101        // CEGUI setup
102        setupGui();
103        // HACK: necessary to call once before the content creation for
104        // terrain initialisation
105        mSceneMgr->_renderScene(mCamera, mWindow->getViewport(0), true);
106
107        mTerrainContentGenerator = new TerrainContentGenerator(mSceneMgr);
108//      mTerrainContentGenerator->GenerateScene(500, "ninja.mesh");
109        mTerrainContentGenerator->GenerateScene(1000, "robot.mesh");
110
111        // no limitations needed anymore: the user can set
112        // objects also on peaks of terrain
113        mTerrainContentGenerator->SetMaxHeight(5000);
114}
115//-----------------------------------------------------------------------
116void TestCullingTerrainApplication::setupGui()
117{
118         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
119                 false, 3000, ST_EXTERIOR_CLOSE);
120     mGUISystem = new CEGUI::System(mGUIRenderer);
121
122         // Mouse
123     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
124     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
125         mGUISystem->setDefaultMouseCursor(
126                (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
127
128         CEGUI::MouseCursor::getSingleton().show();
129}
130//-----------------------------------------------------------------------
131void TestCullingTerrainApplication::createFrameListener()
132{
133        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr,
134                mGUIRenderer, mTerrainContentGenerator, mVisualizationCamera);
135        mFrameListener->showDebugOverlay(true);
136        mRoot->addFrameListener(mFrameListener);
137}
138//-----------------------------------------------------------------------
139void TestCullingTerrainApplication::chooseSceneManager()
140{
141        mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
142}
143/***********************************************/
144/*      MouseQueryListener implementation      */
145/***********************************************/
146//-----------------------------------------------------------------------
147MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam,
148                                                                           SceneManager *sceneManager,
149                                                                           CEGUI::Renderer *renderer,
150                                                                           TerrainContentGenerator *sceneGenerator,
151                                                                           Camera *vizCamera):
152ExampleFrameListener(win, cam, false, true),
153mGUIRenderer(renderer),
154mShutdownRequested(false),
155mLMouseDown(false),
156mRMouseDown(false),
157mSceneMgr(sceneManager),
158mCurrentObject(NULL),
159mTerrainContentGenerator(sceneGenerator),
160mVisibilityThreshold(0),
161mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING),
162mShowOctree(false),
163mUseCulling(true),
164mUseOptimization(true),
165mUseCullCamera(false),
166mVisualizationCamera(vizCamera)
167{
168        // Reduce move speed
169        mMoveSpeed = 50;
170        mRotateSpeed *= 2;
171   
172        // Register this so that we get mouse events.
173        mEventProcessor->addMouseListener(this);
174        mEventProcessor->addMouseMotionListener(this);
175        mEventProcessor->addKeyListener(this);
176
177        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
178       
179        // show overlay
180        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/VisibilityDemoOverlay");
181
182        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/AlgorithmInfo");
183        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ThresholdInfo");
184       
185        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/FrustumCulledNodesInfo");
186        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueryCulledNodesInfo");
187    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/TraversedNodesInfo");
188        mHierarchyNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/HierarchyNodesInfo");
189        mRenderedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/RenderedNodesInfo");
190        mObjectsInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ObjectsInfo");
191        mUseOptimizationInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/UseOptimizationInfo");
192        mQueriesIssuedInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueriesIssuedInfo");
193       
194        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
195        mThresholdInfo->setCaption(": 0");
196        mFrustumCulledNodesInfo->setCaption(": 0");
197        mQueryCulledNodesInfo->setCaption(": 0");
198        mTraversedNodesInfo->setCaption(": 0");
199        mHierarchyNodesInfo->setCaption(": 0");
200        mRenderedNodesInfo->setCaption(": 0");
201        mObjectsInfo->setCaption(": 0");
202        mUseOptimizationInfo->setCaption(": true");
203        mQueriesIssuedInfo->setCaption(": 0");
204
205        setAlgorithm(mCurrentAlgorithm);
206
207        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
208        mSceneMgr->setOption("UseCulling", &mUseCulling);
209        mSceneMgr->setOption("CullCamera", &mUseCullCamera);
210        mSceneMgr->setOption("ShowOctree", &mShowOctree);
211
212    pOver->show();
213}
214//-----------------------------------------------------------------------
215MouseQueryListener::~MouseQueryListener( )
216{
217        delete mRayQueryExecutor;
218}
219//-----------------------------------------------------------------------
220void MouseQueryListener::mouseMoved (MouseEvent *e)
221{
222        // Update CEGUI with the mouse motion
223    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(),
224                e->getRelY() * mGUIRenderer->getHeight());
225}
226//-----------------------------------------------------------------------
227void MouseQueryListener::mousePressed(MouseEvent* e)
228{
229     // Left mouse button down
230     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
231     {
232                 CEGUI::MouseCursor::getSingleton().hide();
233
234                 // Setup the ray scene query
235         Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
236   
237                 Vector3 queryResult;
238                 
239                 // Get results, create a node/entity on the position
240                 mCurrentObject = mTerrainContentGenerator->GenerateSceneObject(
241                         mouseRay.getOrigin(), mouseRay.getDirection(), "robot.mesh");
242               
243         mLMouseDown = true;
244     }
245     // Right mouse button down
246     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
247     {
248         CEGUI::MouseCursor::getSingleton().hide();
249         mRMouseDown = true;
250     } // else if
251} // mousePressed
252
253 //-----------------------------------------------------------------------
254void MouseQueryListener::mouseReleased(MouseEvent* e)
255{
256    // Left mouse button up
257    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
258    {
259                CEGUI::MouseCursor::getSingleton().show();
260        mLMouseDown = false;
261    }
262    // Right mouse button up
263    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
264    {
265        CEGUI::MouseCursor::getSingleton().show();
266        mRMouseDown = false;
267    }
268}
269//-----------------------------------------------------------------------
270void MouseQueryListener::mouseDragged(MouseEvent *e)
271 {
272         // If we are dragging the left mouse button.           
273         if (mLMouseDown)
274     {
275                 Vector3 queryResult;
276                 Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
277
278                 if(mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay))
279                 {
280                         if(mCurrentObject)
281                                 mCurrentObject->setPosition(queryResult);
282                 }
283     }
284         // If we are dragging the right mouse button.
285         if (mRMouseDown)
286         {
287                 mCamera->yaw( -e->getRelX() * mRotateSpeed );
288                 mCamera->pitch( -e->getRelY() * mRotateSpeed );
289         }
290}
291//-----------------------------------------------------------------------
292bool MouseQueryListener::frameStarted(const FrameEvent &evt)
293{
294        clamp2Terrain(mCamera);
295        clamp2Terrain(mVisualizationCamera);
296
297        return ExampleFrameListener::frameStarted(evt);
298}
299void MouseQueryListener::clamp2Terrain(Camera *cam)
300{
301        // clamp to terrain
302        Vector3 camPos = cam->getPosition();
303        Vector3 queryResult;
304
305        if(mRayQueryExecutor->executeRayQuery(&queryResult,
306                        Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y))
307        {
308                cam->setPosition(cam->getPosition().x, queryResult.y + 10,
309                        cam->getPosition().z);
310        }
311}
312//-----------------------------------------------------------------------
313bool MouseQueryListener::frameEnded(const FrameEvent& evt)
314{
315        if (mShutdownRequested)
316                return false;
317
318    if (timeDelay >= 0)
319        timeDelay -= evt.timeSinceLastFrame;
320
321    KEY_PRESSED(KC_SPACE, 0.3, nextAlgorithm());
322
323        KEY_PRESSED(KC_SUBTRACT, 0, changeThreshold(-10));
324        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
325        KEY_PRESSED(KC_O, 0.3, toggleUseOptimization());
326        KEY_PRESSED(KC_S, 0.3, toggleShowOctree());
327        KEY_PRESSED(KC_C, 0.3, toggleUseCulling());
328        KEY_PRESSED(KC_V, 0.3, toggleCullCamera());
329        KEY_PRESSED(KC_X, 0.3, FixVizCamera());
330
331        updateStats();
332        //if(mWindow->getViewport(1))   mWindow->getViewport(1)->update();
333
334    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
335}
336//-----------------------------------------------------------------------
337void MouseQueryListener::changeThreshold(int incr)
338{
339        mVisibilityThreshold += incr;
340        if(mVisibilityThreshold < 0) mVisibilityThreshold = 0;
341       
342        char str[100]; sprintf(str,": %d", mVisibilityThreshold);
343
344        mSceneMgr->setOption("Threshold", &mVisibilityThreshold);
345        mThresholdInfo->setCaption(str);
346}
347//-----------------------------------------------------------------------
348void MouseQueryListener::nextAlgorithm()
349{
350        mCurrentAlgorithm = ++mCurrentAlgorithm %
351                GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS,
352
353        setAlgorithm(mCurrentAlgorithm);
354}
355//-----------------------------------------------------------------------
356void MouseQueryListener::setAlgorithm(int algorithm)
357{
358        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
359        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
360}
361//-----------------------------------------------------------------------
362void MouseQueryListener::updateStats()
363{
364        unsigned int opt = 0;
365        char str[100];
366       
367        mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
368        mFrustumCulledNodesInfo->setCaption(str);
369       
370        mSceneMgr->getOption("NumQueriesIssued", &opt); sprintf(str,": %d", opt);
371        mQueriesIssuedInfo->setCaption(str);
372       
373        mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
374        mQueryCulledNodesInfo->setCaption(str);
375       
376        mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
377        mTraversedNodesInfo->setCaption(str);
378
379        mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt);
380        mHierarchyNodesInfo->setCaption(str);
381
382        mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
383        mRenderedNodesInfo->setCaption(str);
384
385        sprintf(str,": %d", mTerrainContentGenerator->GetObjectCount());
386        mObjectsInfo->setCaption(str);
387}
388//-----------------------------------------------------------------------
389void MouseQueryListener::toggleUseOptimization()
390{
391        mUseOptimization = !mUseOptimization;
392
393        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
394
395        if(mUseOptimization)
396                mUseOptimizationInfo->setCaption(": true");
397        else
398                mUseOptimizationInfo->setCaption(": false");
399}
400//-----------------------------------------------------------------------
401void MouseQueryListener::toggleShowOctree()
402{
403        mShowOctree = !mShowOctree;
404
405        mSceneMgr->setOption("ShowOctree", &mShowOctree);
406}
407//-----------------------------------------------------------------------
408void MouseQueryListener::toggleUseCulling()
409{
410        mUseCulling = !mUseCulling;
411
412        mSceneMgr->setOption("UseCulling", &mUseCulling);
413}
414//-----------------------------------------------------------------------
415void MouseQueryListener::toggleCullCamera()
416{
417        mUseCullCamera = !mUseCullCamera;
418
419        if(mUseCullCamera)
420        {       
421                mWindow->addViewport(mVisualizationCamera, 10, 0.5, 0.5, 1, 1);
422                mWindow->getViewport(1)->setClearEveryFrame(true);
423        }
424        else
425                mWindow->removeViewport(10);
426
427        mSceneMgr->setOption("CullCamera", &mUseCullCamera);
428}
429//-----------------------------------------------------------------------
430void MouseQueryListener::FixVizCamera()
431{
432        mVisualizationCamera->setPosition(mCamera->getPosition());
433        mVisualizationCamera->setOrientation(mCamera->getOrientation());
434        clamp2Terrain(mVisualizationCamera);
435}
436
437//-----------------------------------------------------------------------
438void MouseQueryListener::keyPressed(KeyEvent* e)
439{
440        if(e->getKey() == KC_ESCAPE)
441    {
442                mShutdownRequested = true;
443                e->consume();
444                return;
445        }
446
447        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
448        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
449        e->consume();
450}
451//-----------------------------------------------------------------------
452void MouseQueryListener::keyReleased(KeyEvent* e)
453{
454        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
455        e->consume();
456}
457//-----------------------------------------------------------------------
458void MouseQueryListener::keyClicked(KeyEvent* e)
459{
460        // Do nothing
461        e->consume();
462}
463//-----------------------------------------------------------------------
464INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
465{
466    // Create application object
467    TestCullingTerrainApplication app;
468
469        try
470        {
471        app.go();
472    }
473        catch( Ogre::Exception& e )
474        {
475        MessageBox( NULL, e.getFullDescription().c_str(),
476                        "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
477    }   
478
479    return 0;
480}
Note: See TracBrowser for help on using the repository browser.