Ignore:
Timestamp:
04/12/05 10:50:19 (19 years ago)
Author:
mattausch
Message:
 
Location:
trunk/VUT/OcclusionCullingSceneManager/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingDotSceneManager.cpp

    r39 r42  
    4141                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE); 
    4242 
    43                 mOcclusionCullingSceneTraverser->renderScene(mCameraInProgress, mSceneRoot); 
     43                mOcclusionCullingSceneTraverser->setSceneRoot(mSceneRoot); 
     44                mOcclusionCullingSceneTraverser->renderScene(mCameraInProgress); 
    4445                _deleteRenderedQueueGroups(); 
    4546 
     
    5960        void OcclusionCullingDotSceneManager::_updateSceneGraph(Camera* cam) 
    6061        { 
    61                 mOcclusionCullingSceneTraverser->setNumSceneNodes(mSceneNodes.size()); 
     62                mOcclusionCullingSceneTraverser->setNumSceneNodes((int)mSceneNodes.size()); 
    6263                mOcclusionCullingSceneTraverser->setRenderSystem(mDestRenderSystem); 
    6364 
    64         mOcclusionCullingSceneTraverser->preprocess(); 
     65        //mOcclusionCullingSceneTraverser->preprocess(); 
    6566                 
    6667                DotSceneManager::_updateSceneGraph(cam); 
  • trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingSceneManager.cpp

    r41 r42  
    3030        void OcclusionCullingSceneManager::_renderVisibleObjects( void ) 
    3131        { 
    32                 mOcclusionCullingSceneTraverser->renderScene(mCameraInProgress, mSceneRoot); 
     32                        //-- render background 
     33                clearSpecialCaseRenderQueues(); 
     34                addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND); 
     35                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY); 
     36         
     37                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE); 
    3338                SceneManager::_renderVisibleObjects( ); 
     39                _deleteRenderedQueueGroups(); 
     40 
     41                //-- render visible objects (i.e., all but overlay) 
     42                clearSpecialCaseRenderQueues(); 
     43                addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY); 
     44                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE); 
     45 
     46                mOcclusionCullingSceneTraverser->setSceneRoot(mSceneRoot); 
     47                mOcclusionCullingSceneTraverser->renderScene(mCameraInProgress); 
     48 
     49                _deleteRenderedQueueGroups(); 
     50 
     51                //-- render overlay 
     52                clearSpecialCaseRenderQueues(); 
     53                SceneManager::_renderVisibleObjects( ); 
     54         
     55                clearSpecialCaseRenderQueues(); 
    3456        } 
    3557        //----------------------------------------------------------------------- 
     
    4163        void OcclusionCullingSceneManager::_updateSceneGraph( Camera* cam ) 
    4264        { 
    43                 mOcclusionCullingSceneTraverser->setNumSceneNodes(mSceneNodes.size()); 
    44                 mOcclusionCullingSceneTraverser->setNumQueries(mSceneNodes.size()); 
     65                mOcclusionCullingSceneTraverser->setNumSceneNodes((int)mSceneNodes.size()); 
    4566                mOcclusionCullingSceneTraverser->setRenderSystem(mDestRenderSystem); 
    46  
    47         mOcclusionCullingSceneTraverser->preprocess(); 
     67                 
     68                //mOcclusionCullingSceneTraverser->setNumQueries((int)mSceneNodes.size()); 
     69        //mOcclusionCullingSceneTraverser->preprocess(); 
    4870                 
    4971                SceneManager::_updateSceneGraph(cam); 
  • trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingSceneTraverser.cpp

    r41 r42  
    1717        mQueryMode(MODE_RENDER), mNumSceneNodes(0), mCurrentAlgorithm(RENDER_COHERENT), 
    1818        mNumQueries(0), mNumTraversedNodes(0), mNumQueryCulledNodes(0), mNumFrustumCulledNodes(0),  
    19         mNumRenderedGeometry(0), mSceneManager(sm), mRenderSystem(rsys) 
     19        mNumRenderedGeometry(0), mSceneManager(sm), mRenderSystem(rsys), mSceneRoot(NULL) 
    2020        {                
    2121                mHalfBoundingBox[0] = mHalfBoundingBox[1] = 0; 
     
    2828 
    2929                deleteQueries(); 
     30 
     31                if(mDistanceQueue) 
     32                        delete mDistanceQueue; 
    3033                //SceneManager::~SceneManager(); 
    3134        } 
    3235        //----------------------------------------------------------------------- 
    33         void OcclusionCullingSceneTraverser::renderScene( Camera *cam, SceneNode *root ) 
     36        void OcclusionCullingSceneTraverser::renderScene( Camera *cam ) 
    3437        { 
    3538                mNumTraversedNodes = 0; 
     
    3841                mNumRenderedGeometry = 0; 
    3942                 
    40                 mDistanceQueue = new PriorityQueue(myless<SceneNode *>(cam)); 
    41                 mDistanceQueue->push(root); 
    4243                mCurrentTestIdx = 0; 
     44 
     45                initDistanceQueue(cam); 
    4346 
    4447//mCurrentAlgorithm = RENDER_CULL_FRUSTUM; 
     
    5962                }        
    6063                 
    61                 delete mDistanceQueue; 
    62  
    6364                mFrameId ++; 
    6465        } 
     
    8586                                if(visiblePixels > mVisibilityThreshold) 
    8687                                { 
    87                                         pullUpVisibility(node); 
     88                                        pullUpVisibility(cam, node); 
    8889                                        traverseNode(cam, node); 
    8990                                } 
     
    100101                                mDistanceQueue->pop(); 
    101102                                 
     103                                bool intersects = false; 
    102104                                //TODO: Isvisible also checked inside scenenode::findvisibleobjects 
    103                                 if(!cam->isVisible(node->_getWorldAABB())) 
     105                                if(!cam->isVisible(node->_getWorldAABB(), intersects)) 
    104106                                { 
    105107                    mNumFrustumCulledNodes ++; 
     108                                        continue; 
     109                                } 
     110 
     111                                // if intersects near plane => skip occlusion query because wrong results possible 
     112                                if(intersects) 
     113                                { 
     114                                        // update node's visited flag 
     115                                        node->setLastVisited(mFrameId); 
     116                                        pullUpVisibility(cam, node);                     
     117                                        traverseNode(cam, node); 
     118 
    106119                                        continue; 
    107120                                } 
     
    152165                        if(!cam->isVisible(node->_getWorldAABB())) 
    153166                        {                        
    154                                 char msg2[100]; 
    155                                 sprintf(msg2,"no, invisible\n"); 
    156                                 OutputDebugString(msg2); 
    157  
    158167                                mNumFrustumCulledNodes ++; 
    159168                                continue; 
     
    164173                        node->setNodeVisible(true); 
    165174                        traverseNode(cam, node); 
    166  
    167                         char msg2[100]; 
    168                         sprintf(msg2,"yes, visible\n"); 
    169                         OutputDebugString(msg2); 
    170175                } 
    171176        }        
     
    182187                        node->setLastVisited(mFrameId); 
    183188 
     189                        bool intersects = false; 
    184190                        //TODO: Isvisible also checked inside scenenode::findvisibleobjects 
    185                         if(!cam->isVisible(node->_getWorldAABB())) 
     191                        if(!cam->isVisible(node->_getWorldAABB(), intersects)) 
    186192                        { 
    187193                                mNumFrustumCulledNodes ++; 
     194                                continue; 
     195                        } 
     196 
     197                        // if intersects near plane => skip occlusion query because wrong results possible 
     198                        if(intersects) 
     199                        { 
     200                                node->setNodeVisible(true); 
     201                                traverseNode(cam, node); 
     202 
    188203                                continue; 
    189204                        } 
     
    198213                        if(visiblePixels > mVisibilityThreshold) 
    199214                        { 
     215                                node->setNodeVisible(true); 
    200216                                traverseNode(cam, node); 
    201217                        } 
     
    215231                //setRenderingMode(MODE_RENDER); 
    216232 
    217                 char msg2[100]; 
    218                 sprintf(msg2,"this is query %d of overall %d\n", mCurrentTestIdx, mNumQueries); 
    219                 OutputDebugString(msg2); 
    220  
    221233                // get next available test id 
    222                 HardwareOcclusionQuery *query = mOcclusionQueries[mCurrentTestIdx++]; 
     234                HardwareOcclusionQuery *query = getNextOcclusionQuery(); 
    223235 
    224236                //-- the actual query test 
     
    275287        } 
    276288        //----------------------------------------------------------------------- 
    277         void OcclusionCullingSceneTraverser::preprocess( void ) 
     289/*      void OcclusionCullingSceneTraverser::preprocess( void ) 
    278290        { 
    279291                //-- initialise occlusion queries. 
     
    284296                        mOcclusionQueries.push_back(mRenderSystem->createHardwareOcclusionQuery()); 
    285297                }        
    286         } 
     298        }*/ 
    287299        //----------------------------------------------------------------------- 
    288300        void OcclusionCullingSceneTraverser::setSceneManager( SceneManager *sm ) 
     
    316328        } 
    317329        //----------------------------------------------------------------------- 
    318         void OcclusionCullingSceneTraverser::pullUpVisibility( SceneNode *node ) 
     330        void OcclusionCullingSceneTraverser::pullUpVisibility( Camera *cam, SceneNode *node ) 
    319331        { 
    320332                while(node && !node->isNodeVisible()) 
    321333                { 
     334                        // if we come across some renderable geometry => render it 
     335                        if(node->numAttachedObjects() > 0) 
     336                        { 
     337                                renderSceneNode(cam, node); 
     338                        } 
     339 
    322340                        node->setNodeVisible(true); 
    323                         node = static_cast<SceneNode *>(node->getParent()); 
     341                        node = node->getParentSceneNode(); 
    324342                } 
    325343        } 
     
    327345        void OcclusionCullingSceneTraverser::deleteQueries( void ) 
    328346        { 
    329                 for(unsigned int i=0; i < mOcclusionQueries.size(); i++) 
     347                for(unsigned int i=0; i < (unsigned int)mOcclusionQueries.size(); i++) 
    330348                        delete mOcclusionQueries[i]; 
    331349 
     
    363381 
    364382                return mHalfBoundingBox[half];   
     383        } 
     384        //----------------------------------------------------------------------- 
     385        void OcclusionCullingSceneTraverser::setNumSceneNodes(int num) 
     386        { 
     387                mNumSceneNodes = num; 
     388        } 
     389        //----------------------------------------------------------------------- 
     390        /*void OcclusionCullingSceneTraverser::setNumQueries(int num) 
     391        { 
     392                mNumQueries = num; 
     393        }*/ 
     394        //----------------------------------------------------------------------- 
     395        void OcclusionCullingSceneTraverser::setSceneRoot(SceneNode *root) 
     396        { 
     397                mSceneRoot = root; 
     398        } 
     399        //----------------------------------------------------------------------- 
     400        void OcclusionCullingSceneTraverser::initDistanceQueue(Camera *cam) 
     401        { 
     402                mDistanceQueue = new PriorityQueue(myless<SceneNode *>(cam)); 
     403                mDistanceQueue->push(mSceneRoot); 
     404        } 
     405        //----------------------------------------------------------------------- 
     406        HardwareOcclusionQuery *OcclusionCullingSceneTraverser::getNextOcclusionQuery(void) 
     407        { 
     408                if(mCurrentTestIdx == mOcclusionQueries.size()) 
     409                { 
     410                        mOcclusionQueries.push_back(mRenderSystem->createHardwareOcclusionQuery()); 
     411                } 
     412                 
     413                return mOcclusionQueries[mCurrentTestIdx ++]; 
    365414        } 
    366415        //----------------------------------------------------------------------- 
     
    428477                return true; 
    429478        } 
    430         //----------------------------------------------------------------------- 
    431         void OcclusionCullingSceneTraverser::setNumSceneNodes(int num) 
    432         { 
    433                 mNumSceneNodes = num; 
    434         } 
    435         //----------------------------------------------------------------------- 
    436         void OcclusionCullingSceneTraverser::setNumQueries(int num) 
    437         { 
    438                 mNumQueries = num; 
    439         } 
    440479}        
  • trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneManager.cpp

    r41 r42  
    1616                mOcclusionCullingTerrainSceneTraverser =  
    1717                        new OcclusionCullingTerrainSceneTraverser(this, mDestRenderSystem); 
    18                         //new OcclusionCullingSceneTraverser(this, mDestRenderSystem); 
    1918 
    2019                //mDisplayNodes = true; 
    2120                //mShowBoundingBoxes = true; 
    2221                mShowBoxes = true; 
    23                 mMaxDepth = 20; 
     22                //mMaxDepth = 20; 
    2423        } 
    2524        //----------------------------------------------------------------------- 
     
    4544                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE); 
    4645 
    47                 mOcclusionCullingTerrainSceneTraverser->renderScene(mCameraInProgress, mOctree); 
    48                 //mOcclusionCullingTerrainSceneTraverser->renderScene(mCameraInProgress, mTerrainRoot); 
    49                 //mOcclusionCullingTerrainSceneTraverser->renderScene(mCameraInProgress, mSceneRoot); 
     46                mOcclusionCullingTerrainSceneTraverser->setSceneRoot(mOctree); 
     47                mOcclusionCullingTerrainSceneTraverser->renderScene(mCameraInProgress); 
     48                 
    5049                _deleteRenderedQueueGroups(); 
    5150 
     
    6160                // must be empty because objects are found and rendered in an interleaved fashion 
    6261                // in _renderVisibibleObjects  
     62                //char *msg = "now finding visible objects\n"; OutputDebugString(msg); 
    6363        } 
    6464        //----------------------------------------------------------------------- 
    6565        void OcclusionCullingTerrainSceneManager::_updateSceneGraph(Camera* cam) 
    6666        { 
    67         mOcclusionCullingTerrainSceneTraverser->setNumSceneNodes(mSceneNodes.size()); 
    68                 //HACK 
    69                 mOcclusionCullingTerrainSceneTraverser->setNumQueries(countOctreeSize(mOctree)); 
     67                //char *msg = "now updating scenegraph\n"; OutputDebugString(msg); 
     68        mOcclusionCullingTerrainSceneTraverser->setNumSceneNodes((int)mSceneNodes.size()); 
    7069                mOcclusionCullingTerrainSceneTraverser->setRenderSystem(mDestRenderSystem); 
     70        //mOcclusionCullingTerrainSceneTraverser->preprocess(); 
     71                mOcclusionCullingTerrainSceneTraverser->setNumOctreeNodes(mNumOctreeNodes); 
    7172 
    72         mOcclusionCullingTerrainSceneTraverser->preprocess(); 
    73                  
    7473                TerrainSceneManager::_updateSceneGraph(cam); 
    7574        } 
     
    132131        } 
    133132        //----------------------------------------------------------------------- 
    134         unsigned int OcclusionCullingTerrainSceneManager::countOctreeSize(Octree *root) 
     133        /*unsigned int OcclusionCullingTerrainSceneManager::countNumOctrees(Octree *root) 
    135134        { 
    136135                unsigned int result = 1; 
    137136                                 
    138                 for(int i=0; i<8; i++) 
     137                for(int i=0; i<8; ++i) 
    139138                { 
    140139                        Octree *nextChild = root->mChildren[(i & 4) >> 2][(i & 2) >> 1][i & 1]; 
    141140                 
    142141                        if(nextChild != 0) 
    143                                 result += countOctreeSize(nextChild); 
     142                                result += countNumOctrees(nextChild); 
    144143                } 
    145144                 
    146145                return result; 
    147         } 
     146        }*/ 
    148147}        
  • trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneTraverser.cpp

    r41 r42  
    88        //----------------------------------------------------------------------- 
    99        OcclusionCullingTerrainSceneTraverser::OcclusionCullingTerrainSceneTraverser(SceneManager *sm, RenderSystem *rsys):  
    10         OcclusionCullingSceneTraverser(sm, rsys) 
    11         { 
     10        OcclusionCullingSceneTraverser(sm, rsys), mOctreeSceneRoot(0), mOctreeDistanceQueue(0) 
     11        { 
     12        } 
     13        //----------------------------------------------------------------------- 
     14        OcclusionCullingTerrainSceneTraverser::~OcclusionCullingTerrainSceneTraverser() 
     15        {                
     16                if(mOctreeDistanceQueue) 
     17                        delete mOctreeDistanceQueue; 
    1218        } 
    1319        //----------------------------------------------------------------------- 
     
    1622                mNumTraversedNodes ++; 
    1723         
    18                 //if(octant->numNodes() > 0) 
     24                // if we come across some renderable geometry => render it 
     25                if(octant->numNodes() > 0) 
     26                { 
    1927                        renderOctant(cam, octant); 
     28                } 
    2029 
    2130                for(int i=0; i<8; i++) 
     
    2332                        Octree *nextChild = octant->mChildren[(i & 4) >> 2][(i & 2) >> 1][i & 1]; 
    2433                 
    25                         if(nextChild != 0) 
    26                                 mDistanceQueue->push(nextChild); 
    27                 } 
    28         } 
    29         //----------------------------------------------------------------------- 
    30         void OcclusionCullingTerrainSceneTraverser::renderScene( Camera *cam, Octree *root ) 
    31                 //TODO: Renderscene independent from hierarchynode => implement only once 
    32         { 
    33                 mNumTraversedNodes = 0; 
    34                 mNumQueryCulledNodes = 0; 
    35                 mNumFrustumCulledNodes = 0; 
    36                 mNumRenderedGeometry = 0; 
    37                  
    38                 mDistanceQueue = new OctreePriorityQueue(octreeless<Octree *>(cam)); 
    39                 mDistanceQueue->push(root); 
    40                 mCurrentTestIdx = 0; 
    41                  
    42 //mCurrentAlgorithm = RENDER_CULL_FRUSTUM; 
    43                 switch(mCurrentAlgorithm) 
    44                 { 
    45                         case RENDER_CULL_FRUSTUM: 
    46                                 renderCullFrustum(cam); 
    47                         break; 
    48                         case RENDER_STOP_AND_WAIT: 
    49                                 renderStopAndWait(cam); 
    50                                 break; 
    51                         case RENDER_COHERENT: 
    52                                 //renderCoherentWithQueue(cam); 
    53                                 renderStopAndWait(cam); 
    54                                 break; 
    55                         default: 
    56                                 renderCullFrustum(cam); 
    57                                 break; 
    58                 }        
    59                  
    60                 delete mDistanceQueue; 
    61  
    62                 mFrameId ++; 
     34                        if(nextChild) 
     35                                mOctreeDistanceQueue->push(nextChild); 
     36                } 
    6337        } 
    6438        //----------------------------------------------------------------------- 
     
    6741                AxisAlignedBox box; 
    6842 
    69                 while(!mDistanceQueue->empty()) 
    70                 { 
    71                         Octree *octant = mDistanceQueue->top(); 
    72                         mDistanceQueue->pop(); 
     43                while(!mOctreeDistanceQueue->empty()) 
     44                { 
     45                        Octree *octant = mOctreeDistanceQueue->top(); 
     46                        mOctreeDistanceQueue->pop(); 
    7347         
    7448                        // interesting for visualization purpose 
     
    7650                        octant->_getCullBounds(&box); 
    7751                         
    78                         if(static_cast<OctreeCamera *>(cam)->getVisibility(box) == OctreeCamera::NONE) 
     52                        //if(static_cast<OctreeCamera *>(cam)->getVisibility(box) == OctreeCamera::NONE) 
    7953                        if(!cam->isVisible(box)) 
    8054                        { 
     
    8458 
    8559                        // update node's visited flag  
    86                         //TODO: octree->setLastVisited(mFrameId); 
    87                         //TODO: octree->setNodeVisible(true); 
     60                        octant->setLastVisited(mFrameId); 
     61                        octant->setOctreeVisible(true); 
    8862                 
    8963                        traverseOctant(cam, octant); 
     
    9670                AxisAlignedBox box; 
    9771 
    98                 while(!mDistanceQueue->empty()) 
    99                 { 
    100                         Octree *octant = mDistanceQueue->top(); 
    101                         mDistanceQueue->pop(); 
     72                while(!mOctreeDistanceQueue->empty()) 
     73                { 
     74                        Octree *octant = mOctreeDistanceQueue->top(); 
     75                        mOctreeDistanceQueue->pop(); 
    10276                 
    10377                        // interesting for visualization purpose 
    104                         //octant->setNodeVisible(false); 
    105                         //octant->setLastVisited(mFrameId); 
     78                        octant->setOctreeVisible(false); 
     79                        octant->setLastVisited(mFrameId); 
    10680 
    10781                        //TODO: Isvisible also checked inside scenenode::findvisibleobjects 
    10882                        octant->_getCullBounds(&box); 
    10983 
    110                         char msg[100];  
    111                         Vector3 max = box.getMaximum(); 
    112                         Vector3 min = box.getMinimum(); 
    113  
    114                         sprintf(msg, "box max: %3.3f, %3.3f, %3.3f, min: %3.3f, %3.3f, %3.3f\n",max.x,max.y,max.z,min.x,min.y,min.z); 
    115                         OutputDebugString(msg); 
    116  
    117                         if(static_cast<OctreeCamera *>(cam)->getVisibility(box) == OctreeCamera::NONE) 
    118                         //if(!cam->isVisible(box)) 
     84                        bool intersects = false; 
     85 
     86                        //if(vis == OctreeCamera::NONE) 
     87                        if(!cam->isVisible(box, intersects)) 
    11988                        { 
    12089                                mNumFrustumCulledNodes ++; 
     90                                continue; 
     91                        } 
     92                        // if intersects near plane => skip occlusion query because wrong results possible 
     93                        if(intersects) 
     94                        { 
     95                                octant->setOctreeVisible(true); 
     96                                traverseOctant(cam, octant); 
    12197                                continue; 
    12298                        } 
     
    127103                        // wait if result not available 
    128104                        query->pullOcclusionQuery(&visiblePixels); 
    129 //traverseOctant(cam, octant);                   
     105                         
    130106                        // node visible 
    131107                        if(visiblePixels > mVisibilityThreshold) 
    132108                        { 
    133109                                traverseOctant(cam, octant); 
    134                                 //mNumQueryCulledNodes ++; 
    135110                        } 
    136111                        else 
     
    144119        void OcclusionCullingTerrainSceneTraverser::renderCoherentWithQueue( Camera *cam ) 
    145120        { 
    146         } 
    147         //----------------------------------------------------------------------- 
    148         void OcclusionCullingTerrainSceneTraverser::pullUpVisibility( Octree *node ) 
    149         { 
    150         } 
    151         //----------------------------------------------------------------------- 
    152         void OcclusionCullingTerrainSceneTraverser::renderOctant( Camera *cam, Octree *octree ) 
    153         { 
    154                 setRenderingMode(MODE_RENDER); 
    155                 ((OcclusionCullingTerrainSceneManager *)mSceneManager)->_renderOctant(cam, octree); 
     121                OctreeQueryQueue queryQueue; 
     122                AxisAlignedBox box; 
     123 
     124                //-- PART 1: process finished occlusion queries 
     125                while(!mOctreeDistanceQueue->empty() || !queryQueue.empty()) 
     126                { 
     127                        while(!queryQueue.empty() &&  
     128                                  ((queryQueue.front().second)->resultAvailable() || mOctreeDistanceQueue->empty())) 
     129                        { 
     130                                Octree *octant = queryQueue.front().first; 
     131                                HardwareOcclusionQuery *query = queryQueue.front().second; 
     132 
     133                                queryQueue.pop(); 
     134                         
     135                                // wait until result available 
     136                                unsigned int visiblePixels; 
     137                                query->pullOcclusionQuery(&visiblePixels); 
     138 
     139                                if(visiblePixels > mVisibilityThreshold) 
     140                                { 
     141                                        pullUpVisibility(cam, octant); 
     142                                        traverseOctant(cam, octant); 
     143                                } 
     144                                else 
     145                                { 
     146                                        mNumQueryCulledNodes ++; 
     147                                } 
     148                        }        
     149 
     150                        //-- PART 2: hierarchical traversal 
     151                        if(!mOctreeDistanceQueue->empty()) 
     152                        { 
     153                                Octree *octant = mOctreeDistanceQueue->top(); 
     154                                mOctreeDistanceQueue->pop(); 
     155                                         
     156                                octant->_getCullBounds(&box); 
     157 
     158                                bool intersects = false; 
     159                                //TODO: Isvisible also checked inside scenenode::findvisibleobjects 
     160                                if(!cam->isVisible(box, intersects)) 
     161                                { 
     162                    mNumFrustumCulledNodes ++; 
     163                                        continue; 
     164                                } 
     165 
     166                                // if intersects near plane => skip occlusion query because wrong results possible 
     167                                if(intersects) 
     168                                { 
     169                                        // update node's visited flag 
     170                                        octant->setLastVisited(mFrameId); 
     171                                        pullUpVisibility(cam, octant);                   
     172                                        traverseOctant(cam, octant); 
     173 
     174                                        continue; 
     175                                } 
     176 
     177                                // identify previously visible nodes 
     178                                bool wasVisible = octant->isOctreeVisible() && (octant->lastVisited() == mFrameId - 1); 
     179                                         
     180                                // identify nodes that we cannot skip queries for 
     181                                bool leafOrWasInvisible = !wasVisible || isLeaf(octant); 
     182 
     183                                // reset node's visibility classification  
     184                                octant->setOctreeVisible(false); 
     185 
     186                                // update node's visited flag 
     187                                octant->setLastVisited(mFrameId); 
     188                         
     189                                // skip testing previously visible interior nodes 
     190                                if(leafOrWasInvisible) 
     191                                { 
     192                                        HardwareOcclusionQuery *query = issueOcclusionQuery(&box, wasVisible); 
     193                                        queryQueue.push(OctreeQueryPair(octant, query)); 
     194                                } 
     195                                         
     196                                // always traverse a node if it was visible 
     197                                if(wasVisible) 
     198                                { 
     199                                        traverseOctant(cam, octant); 
     200                                } 
     201                                else 
     202                                { 
     203                                        mNumFrustumCulledNodes ++; 
     204                                } 
     205                        } 
     206                } 
     207        } 
     208        //----------------------------------------------------------------------- 
     209        void OcclusionCullingTerrainSceneTraverser::pullUpVisibility( Camera *cam, Octree *octant ) 
     210        { 
     211                while(octant && !octant->isOctreeVisible()) 
     212                { 
     213                        // if we come across some renderable geometry => render it 
     214                        if(octant->numNodes() > 0) 
     215                        { 
     216                                renderOctant(cam, octant); 
     217                        } 
     218 
     219                        octant->setOctreeVisible(true); 
     220                        octant = octant->getParent(); 
     221                } 
     222        } 
     223        //----------------------------------------------------------------------- 
     224        void OcclusionCullingTerrainSceneTraverser::renderOctant( Camera *cam, Octree *octant ) 
     225        { 
     226                if(octant->lastVisited() != octant->lastRendered()) 
     227                { 
     228                        setRenderingMode(MODE_RENDER); 
     229 
     230                        octant->setLastRendered(octant->lastVisited()); 
     231                        ((OcclusionCullingTerrainSceneManager *)mSceneManager)->_renderOctant(cam, octant); 
     232                } 
     233                else OutputDebugString("already rendered"); 
     234        } 
     235        //----------------------------------------------------------------------- 
     236        void OcclusionCullingTerrainSceneTraverser::setSceneRoot(Octree *root) 
     237        { 
     238                mOctreeSceneRoot = root; 
     239        } 
     240        //----------------------------------------------------------------------- 
     241        void OcclusionCullingTerrainSceneTraverser::initDistanceQueue(Camera *cam) 
     242        { 
     243                if(mOctreeDistanceQueue) 
     244                        delete mOctreeDistanceQueue; 
     245 
     246                mOctreeDistanceQueue = new OctreePriorityQueue(octreeless<Octree *>(cam)); 
     247                mOctreeDistanceQueue->push(mOctreeSceneRoot); 
     248        } 
     249        //----------------------------------------------------------------------- 
     250        bool OcclusionCullingTerrainSceneTraverser::isLeaf(Octree *octant) 
     251        { 
     252                for(int i=0; i<8; i++) 
     253                { 
     254                        if(octant->mChildren[(i & 4) >> 2][(i & 2) >> 1][i & 1]) 
     255                                return false; 
     256                } 
     257 
     258                return true; 
     259        } 
     260        //----------------------------------------------------------------------- 
     261        void OcclusionCullingTerrainSceneTraverser::setNumOctreeNodes(unsigned int num) 
     262        { 
     263                mNumOctreeNodes = num; 
     264        } 
     265        //----------------------------------------------------------------------- 
     266        bool OcclusionCullingTerrainSceneTraverser::getOption( const String & key, void *val ) 
     267        { 
     268                if ( key == "NumOctreeNodes" ) 
     269                { 
     270                        * static_cast < unsigned int * > ( val ) = mNumOctreeNodes; 
     271                        return true; 
     272                } 
     273 
     274                return OcclusionCullingSceneTraverser::getOption(key, val); 
     275        } 
     276        //----------------------------------------------------------------------- 
     277        bool OcclusionCullingTerrainSceneTraverser::getOptionKeys( StringVector & refKeys ) 
     278        { 
     279                refKeys.push_back( "NumOctreeNodes" ); 
     280                 
     281                return OcclusionCullingSceneTraverser::getOptionKeys(refKeys);           
    156282        } 
    157283}        
Note: See TracChangeset for help on using the changeset viewer.