source: trunk/VUT/OcclusionCullingSceneManager/TestCullingDotScene/TestCullingDotSceneApplication.cpp @ 39

Revision 39, 19.4 KB checked in by mattausch, 20 years ago (diff)
Line 
1/**
2    \file
3        TestCullingApplication.cpp
4    \brief
5        Tests the occlusion 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 "OgreLight.h"
17#include "tinyxml.h"
18#include "TestCullingDotSceneApplication.h"
19#include "OgreOcclusionCullingSceneTraverser.h"
20
21#define WIN32_LEAN_AND_MEAN
22#include "windows.h"
23
24/***********************************************/
25/* TestCullingDotSceneApplication implementation       */
26/***********************************************/
27void TestCullingDotSceneApplication::ParseDotScene( const String &SceneName, const String& groupName )
28{
29        TiXmlDocument   *XMLDoc;
30        TiXmlElement    *XMLRoot, *XMLNodes, *XMLPathFind;
31        try
32        {
33                DataStreamPtr pStream = ResourceGroupManager::getSingleton().openResource( SceneName, groupName );
34
35                String data = pStream->getAsString();
36
37                // Open the .scene File
38                XMLDoc = new TiXmlDocument();
39                XMLDoc->Parse( data.c_str() );
40                pStream->close();
41                pStream.setNull();
42
43                if( XMLDoc->Error() )
44                {
45                        //We'll just log, and continue on gracefully
46                        LogManager::getSingleton().logMessage("Error in dotscene demo app!!!!!");
47                        delete XMLDoc;
48                        return;
49                }
50        }
51        catch(...)
52        {
53                //We'll just log, and continue on gracefully
54                LogManager::getSingleton().logMessage("Error in dotscene demo app!!!!!");
55                delete XMLDoc;
56                return;
57        }
58
59        // Validate the File
60        XMLRoot = XMLDoc->RootElement();
61        if( String( XMLRoot->Value()) != "scene"  ) {
62                LogManager::getSingleton().logMessage( "Error: Invalid .scene File. Missing <scene>" );
63                delete XMLDoc;         
64                return;
65        }
66               
67        XMLNodes = XMLRoot->FirstChildElement( "nodes" );
68       
69        // Read in the scene nodes
70        if( XMLNodes )
71        {
72                TiXmlElement *XMLNode, *XMLPosition, *XMLRotation, *XMLScale,  *XMLEntity, *XMLBillboardSet,  *XMLLight;
73
74                XMLNode = XMLNodes->FirstChildElement( "node" );
75               
76                while( XMLNode )
77                {
78                        // Process the current node
79                        // Grab the name of the node
80                        String NodeName = XMLNode->Attribute("name");
81                        // First create the new scene node
82                        SceneNode* NewNode = static_cast<SceneNode*>( mSceneMgr->getRootSceneNode()->createChild( NodeName ) );
83
84                        Vector3 TempVec;
85                        String TempValue;
86                               
87                        // Now position it...
88                        XMLPosition = XMLNode->FirstChildElement("position");
89                       
90                        if( XMLPosition )
91                        {
92                                TempValue = XMLPosition->Attribute("x");
93                                TempVec.x = StringConverter::parseReal(TempValue);
94                                TempValue = XMLPosition->Attribute("y");
95                                TempVec.y = StringConverter::parseReal(TempValue);
96                                TempValue = XMLPosition->Attribute("z");
97                                TempVec.z = StringConverter::parseReal(TempValue);
98                                NewNode->setPosition( TempVec );
99                        }
100
101                        // Rotate it...
102                        XMLRotation = XMLNode->FirstChildElement("rotation");
103                        if( XMLRotation )
104                        {
105                                Quaternion TempQuat;
106                                TempValue = XMLRotation->Attribute("qx");
107                                TempQuat.x = StringConverter::parseReal(TempValue);
108                                TempValue = XMLRotation->Attribute("qy");
109                                TempQuat.y = StringConverter::parseReal(TempValue);
110                                TempValue = XMLRotation->Attribute("qz");
111                                TempQuat.z = StringConverter::parseReal(TempValue);
112                                TempValue = XMLRotation->Attribute("qw");
113                                TempQuat.w = StringConverter::parseReal(TempValue);
114                                NewNode->setOrientation( TempQuat );
115                        }
116
117                        // Scale it.
118                        XMLScale = XMLNode->FirstChildElement("scale");
119                       
120                        if( XMLScale )
121                        {
122                                TempValue = XMLScale->Attribute("x");
123                                TempVec.x = StringConverter::parseReal(TempValue);
124                                TempValue = XMLScale->Attribute("y");
125                                TempVec.y = StringConverter::parseReal(TempValue);
126                                TempValue = XMLScale->Attribute("z");
127                                TempVec.z = StringConverter::parseReal(TempValue);
128                                NewNode->setScale( TempVec );
129                        }
130
131                        XMLLight = XMLNode->FirstChildElement( "light" );
132                       
133                        if( XMLLight )
134                                NewNode->attachObject( LoadLight( XMLLight ) );
135
136                        // Check for an Entity
137                        XMLEntity = XMLNode->FirstChildElement("entity");
138                       
139                        if( XMLEntity )
140                        {
141                                if( XMLEntity->Attribute("static") )
142                                {
143                                        if( strcmp( XMLEntity->Attribute("static"), "false" )==0 ){
144                                                String EntityName, EntityMeshFilename;
145                                                EntityName = XMLEntity->Attribute( "name" );
146                                                EntityMeshFilename = XMLEntity->Attribute( "meshFile" );
147
148                                                // Create entity
149                                                Entity* NewEntity = mSceneMgr->createEntity(EntityName, EntityMeshFilename);
150                                                NewNode->attachObject( NewEntity );
151                                        }
152                                }
153                        }
154
155                        XMLBillboardSet = XMLNode->FirstChildElement( "billboardSet" );
156                        if( XMLBillboardSet )
157                        {
158                                String TempValue;
159
160                                BillboardSet* bSet = mSceneMgr->createBillboardSet( NewNode->getName() );
161
162                                BillboardType Type;
163                                TempValue = XMLBillboardSet->Attribute( "type" );
164                                if( TempValue == "orientedCommon" )
165                                        Type = BBT_ORIENTED_COMMON;
166                                else if( TempValue == "orientedSelf" )
167                                        Type = BBT_ORIENTED_SELF;
168                                else Type = BBT_POINT;
169
170                                BillboardOrigin Origin;
171                                TempValue = XMLBillboardSet->Attribute( "type" );
172                                if( TempValue == "bottom_left" )
173                                        Origin = BBO_BOTTOM_LEFT;
174                                else if( TempValue == "bottom_center" )
175                                        Origin = BBO_BOTTOM_CENTER;
176                                else if( TempValue == "bottomRight"  )
177                                        Origin = BBO_BOTTOM_RIGHT;
178                                else if( TempValue == "left" )
179                                        Origin = BBO_CENTER_LEFT;
180                                else if( TempValue == "right" )
181                                        Origin = BBO_CENTER_RIGHT;
182                                else if( TempValue == "topLeft" )
183                                        Origin = BBO_TOP_LEFT;
184                                else if( TempValue == "topCenter" )
185                                        Origin = BBO_TOP_CENTER;
186                                else if( TempValue == "topRight" )
187                                        Origin = BBO_TOP_RIGHT;
188                                else
189                                        Origin = BBO_CENTER;
190
191                                bSet->setBillboardType( Type );
192                                bSet->setBillboardOrigin( Origin );
193
194                                TempValue = XMLBillboardSet->Attribute( "name" );
195                                bSet->setMaterialName( TempValue );
196
197                                int width, height;
198                                width = StringConverter::parseReal( XMLBillboardSet->Attribute( "width" ) );
199                                height = StringConverter::parseReal( XMLBillboardSet->Attribute( "height" ) );
200                                bSet->setDefaultDimensions( width, height );
201                                bSet->setVisible( true );
202                                NewNode->attachObject( bSet );
203
204                                TiXmlElement *XMLBillboard;
205
206                                XMLBillboard = XMLBillboardSet->FirstChildElement( "billboard" );
207
208                                while( XMLBillboard )
209                                {
210                                        Billboard *b;
211                                        TempValue;
212                                        TempVec = Vector3( 0, 0, 0 );
213                                        ColourValue TempColour(1,1,1,1);
214
215                                        XMLPosition = XMLBillboard->FirstChildElement( "position" );
216                                        if( XMLPosition ){
217                                                TempValue = XMLPosition->Attribute("x");
218                                                TempVec.x = StringConverter::parseReal(TempValue);
219                                                TempValue = XMLPosition->Attribute("y");
220                                                TempVec.y = StringConverter::parseReal(TempValue);
221                                                TempValue = XMLPosition->Attribute("z");
222                                                TempVec.z = StringConverter::parseReal(TempValue);
223                                        }
224
225                                        TiXmlElement* XMLColour = XMLBillboard->FirstChildElement( "colourDiffuse" );
226                                        if( XMLColour )
227                                        {
228                                                TempValue = XMLColour->Attribute("r");
229                                                TempColour.r = StringConverter::parseReal(TempValue);
230                                                TempValue = XMLColour->Attribute("g");
231                                                TempColour.g = StringConverter::parseReal(TempValue);
232                                                TempValue = XMLColour->Attribute("b");
233                                                TempColour.b = StringConverter::parseReal(TempValue);
234                                        }
235
236                                        b = bSet->createBillboard( TempVec, TempColour);
237
238                                        XMLBillboard = XMLBillboard->NextSiblingElement( "billboard" );
239                                }
240                        }
241
242                        // Move to the next node
243                        XMLNode = XMLNode->NextSiblingElement( "node" );
244                }
245        }
246
247        // Close the XML File
248        delete XMLDoc;
249}
250
251Light* TestCullingDotSceneApplication::LoadLight( TiXmlElement *XMLLight )
252{
253        TiXmlElement *XMLDiffuse, *XMLSpecular, *XMLAttentuation, *XMLPosition;
254
255        // Create a light (point | directional | spot | radPoint)
256        Light* light = mSceneMgr->createLight( XMLLight->Attribute("name") );
257        if( !XMLLight->Attribute("type") || String(XMLLight->Attribute("type")) == "point" )
258                light->setType( Light::LT_POINT );
259        else if( String(XMLLight->Attribute("type")) == "directional")
260                light->setType( Light::LT_DIRECTIONAL );
261        else if( String(XMLLight->Attribute("type")) == "spot")
262                light->setType( Light::LT_SPOTLIGHT );
263        else if( String(XMLLight->Attribute("type")) == "radPoint")
264                light->setType( Light::LT_POINT );
265
266        XMLDiffuse = XMLLight->FirstChildElement("colourDiffuse");
267        if( XMLDiffuse )
268        {
269                ColourValue Diffuse;
270                Diffuse.r = Ogre::StringConverter::parseReal( XMLDiffuse->Attribute("r") );
271                Diffuse.g = Ogre::StringConverter::parseReal( XMLDiffuse->Attribute("g") );
272                Diffuse.b = Ogre::StringConverter::parseReal( XMLDiffuse->Attribute("b") );
273                Diffuse.a = 1;
274                light->setDiffuseColour(Diffuse);
275        }
276       
277        XMLSpecular = XMLLight->FirstChildElement("colourSpecular");
278       
279        if( XMLSpecular )
280        {
281                ColourValue Specular;
282                Specular.r = Ogre::StringConverter::parseReal( XMLSpecular->Attribute("r") );
283                Specular.g = Ogre::StringConverter::parseReal( XMLSpecular->Attribute("g") );
284                Specular.b = Ogre::StringConverter::parseReal( XMLSpecular->Attribute("b") );
285                Specular.a = 1;
286                light->setSpecularColour(Specular);
287        }
288
289        XMLAttentuation = XMLLight->FirstChildElement("lightAttenuation");
290        if( XMLAttentuation )
291        {
292                //get defaults incase not all values specified
293                Real range, constant, linear, quadratic;
294                range = light->getAttenuationRange();
295                constant = light->getAttenuationConstant();
296                linear = light->getAttenuationLinear();
297                quadratic = light->getAttenuationQuadric();
298                       
299                if( XMLAttentuation->Attribute("range") )
300                        range = StringConverter::parseReal( XMLAttentuation->Attribute("range") );
301                if( XMLAttentuation->Attribute("constant") )
302                        constant = StringConverter::parseReal( XMLAttentuation->Attribute("constant") );
303                if( XMLAttentuation->Attribute("linear") )
304                        linear = StringConverter::parseReal( XMLAttentuation->Attribute("linear") );
305                if( XMLAttentuation->Attribute("quadratic") )
306                        quadratic = StringConverter::parseReal( XMLAttentuation->Attribute("quadratic") );
307                        light->setAttenuation( range, constant, linear, quadratic );
308        }
309
310        XMLPosition = XMLLight->FirstChildElement("position");
311        if( XMLPosition )
312        {
313                Vector3 p = Vector3(0,0,0);
314                if( XMLPosition->Attribute("x") )
315                        p.x = StringConverter::parseReal( XMLPosition->Attribute("x") );
316                if( XMLPosition->Attribute("y") )
317                        p.y = StringConverter::parseReal( XMLPosition->Attribute("y") );
318                if( XMLPosition->Attribute("z") )
319                        p.z = StringConverter::parseReal( XMLPosition->Attribute("z") );
320           
321                light->setPosition( p );
322        }
323
324        //castShadows           (true | false) "true"
325        light->setCastShadows( true );
326        if( XMLLight->Attribute("visible") )
327                if( String(XMLLight->Attribute("visible")) == "false" )
328                                light->setCastShadows( false );
329                       
330        //visible                       (true | false) "true"           
331        light->setVisible( true );
332        if( XMLLight->Attribute("visible") )
333                if( String(XMLLight->Attribute("visible")) == "false" )
334                        light->setVisible( false );
335
336        return light;
337}
338//-----------------------------------------------------------------------
339void TestCullingDotSceneApplication::createScene(void)
340{
341        mSceneMgr->setAmbientLight(ColourValue(0.09f, 0.09f, 0.09f));
342        mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox" );
343               
344        //This is default, though, set it anyway :)
345        ResourceGroupManager::getSingleton().setWorldResourceGroupName("General");
346        mSceneMgr->setWorldGeometry( "MyScene.scene" );
347        //mSceneMgr->SetOctreeVisible( 1 );
348               
349        ParseDotScene( "MyScene.scene", "General" );
350        // CEGUI setup
351        setupGui();
352}
353//-----------------------------------------------------------------------
354void TestCullingDotSceneApplication::setupGui( void )
355{
356         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, ST_GENERIC);
357     mGUISystem = new CEGUI::System(mGUIRenderer);
358
359         // Mouse
360     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
361     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
362         mGUISystem->setDefaultMouseCursor(
363                (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
364
365         CEGUI::MouseCursor::getSingleton().show( );
366     
367        /* CEGUI::Window* sheet =
368            CEGUI::WindowManager::getSingleton().loadWindowLayout(
369                (CEGUI::utf8*)"ogregui.layout");
370
371     mGUISystem->setGUISheet(sheet);*/
372}
373//-----------------------------------------------------------------------
374void TestCullingDotSceneApplication::createFrameListener(void)
375{
376        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr, mGUIRenderer);
377        mFrameListener->showDebugOverlay(true);
378        mRoot->addFrameListener(mFrameListener);
379}
380//-----------------------------------------------------------------------
381void TestCullingDotSceneApplication::chooseSceneManager(void)
382{
383        mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
384
385}
386//-----------------------------------------------------------------------
387void TestCullingDotSceneApplication::createViewports(void)
388{
389        // Create one viewport, entire window
390        Viewport* vp = mWindow->addViewport(mCamera);
391        // Look back along -Z
392    mCamera->lookAt(Vector3(0, 0, -300));
393        mCamera->setPosition(0 , 100, 600);
394}
395
396/***********************************************/
397/* MouseQueryListener implementation           */
398/***********************************************/
399
400//-----------------------------------------------------------------------
401MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer)
402        : ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer),
403                mShutdownRequested(false)
404{
405
406        // Setup default variables
407//      mCurrentObject = NULL;
408        mLMouseDown = false;
409        mRMouseDown = false;
410        mSceneMgr = sceneManager;
411
412    // Reduce move speed
413        mMoveSpeed = 50;
414        mRotateSpeed *= 2;
415
416        mCurrentAlgorithm = OcclusionCullingSceneTraverser::RENDER_COHERENT;
417        mThreshold = 0;
418   
419        // Register this so that we get mouse events.
420        mEventProcessor->addMouseListener(this);
421        mEventProcessor->addMouseMotionListener(this);
422        mEventProcessor->addKeyListener(this);
423
424        // show overlay
425        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/OcclusionDemoOverlay");
426
427        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/AlgorithmInfo");
428        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/ThresholdInfo");
429        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/FrustumCulledNodesInfo");
430        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/QueryCulledNodesInfo");
431    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/TraversedNodesInfo");
432
433        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
434        mThresholdInfo->setCaption(": 0");
435        mFrustumCulledNodesInfo->setCaption(": 0");
436        mQueryCulledNodesInfo->setCaption(": 0");
437        mTraversedNodesInfo->setCaption(": 0");
438
439    pOver->show();
440} // MouseQueryListener
441//-----------------------------------------------------------------------
442void MouseQueryListener::mouseMoved (MouseEvent *e)
443{
444        // Update CEGUI with the mouse motion
445    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight());
446}
447//-----------------------------------------------------------------------
448void MouseQueryListener::mousePressed(MouseEvent* e)
449{
450     // Left mouse button down
451     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
452     {
453                 CEGUI::MouseCursor::getSingleton().hide( );
454                 mLMouseDown = true;
455     } // if
456     // Right mouse button down
457     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
458     {
459         CEGUI::MouseCursor::getSingleton().hide( );
460         mRMouseDown = true;
461     } // else if
462} // mousePressed
463
464 //-----------------------------------------------------------------------
465void MouseQueryListener::mouseReleased(MouseEvent* e)
466{
467    // Left mouse button up
468    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
469    {
470                CEGUI::MouseCursor::getSingleton().show( );
471        mLMouseDown = false;
472    }
473    // Right mouse button up
474    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
475    {
476        CEGUI::MouseCursor::getSingleton().show( );
477        mRMouseDown = false;
478    }
479}
480//-----------------------------------------------------------------------
481void MouseQueryListener::mouseDragged (MouseEvent *e)
482 {
483         // If we are dragging the left mouse button.   
484         if ( mLMouseDown )
485         {
486                mCamera->yaw( -e->getRelX() * mRotateSpeed );
487                mCamera->pitch( -e->getRelY() * mRotateSpeed );
488     }
489                 
490         // If we are dragging the right mouse button.
491         if ( mRMouseDown )
492         {
493                 Vector3 translation;
494                 translation.x += -e->getRelX() * 0.13;
495                 translation.y -= -e->getRelY() * 0.13;
496
497                 mCamera->moveRelative(translation);           
498         }
499}
500//-----------------------------------------------------------------------
501bool MouseQueryListener::frameEnded(const FrameEvent& evt)
502{
503        if (mShutdownRequested)
504                return false;
505
506    if (timeDelay >= 0)
507        timeDelay -= evt.timeSinceLastFrame;
508
509    KEY_PRESSED(KC_SPACE, 0.3, changeAlgorithm());
510
511        KEY_PRESSED(KC_SUBTRACT, 0.0, changeThreshold(-10));
512        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
513        //KEY_PRESSED(KC_T, 1, change);
514     
515        changeStats();
516
517    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
518}
519//-----------------------------------------------------------------------
520void MouseQueryListener::changeThreshold(int incr)
521{
522        mThreshold += incr; if(mThreshold < 0) mThreshold = 0;
523       
524        char str[100]; sprintf(str,": %d", mThreshold);
525
526        mSceneMgr->setOption("Threshold", &mThreshold);
527        mThresholdInfo->setCaption(str);
528}
529//-----------------------------------------------------------------------
530void MouseQueryListener::changeAlgorithm()
531{
532    mCurrentAlgorithm = ++mCurrentAlgorithm % OcclusionCullingSceneTraverser::NUM_RENDERMODES;
533
534        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
535        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
536}
537//-----------------------------------------------------------------------
538void MouseQueryListener::changeStats()
539{
540        unsigned int opt = 0;
541        char str[100];
542       
543        mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
544        mFrustumCulledNodesInfo->setCaption(str);
545       
546        mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
547        mQueryCulledNodesInfo->setCaption(str);
548       
549        mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
550        mTraversedNodesInfo->setCaption(str);
551}
552//-----------------------------------------------------------------------
553void MouseQueryListener::keyPressed(KeyEvent* e)
554{
555        if(e->getKey() == KC_ESCAPE)
556    {
557                mShutdownRequested = true;
558                e->consume();
559                return;
560        }
561
562        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
563        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
564        e->consume();
565}
566//-----------------------------------------------------------------------
567void MouseQueryListener::keyReleased(KeyEvent* e)
568{
569        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
570        e->consume();
571}
572//-----------------------------------------------------------------------
573void MouseQueryListener::keyClicked(KeyEvent* e)
574{
575        // Do nothing
576        e->consume();
577}
578//-----------------------------------------------------------------------
579INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
580{
581    // Create application object
582    TestCullingDotSceneApplication app;
583
584        try
585        {
586        app.go();
587    }
588        catch( Ogre::Exception& e )
589        {
590        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
591    }   
592
593    return 0;
594}
Note: See TracBrowser for help on using the repository browser.