Ignore:
Timestamp:
08/03/06 17:25:01 (18 years ago)
Author:
szydlowski
Message:

all functions for CHC implemented in KdTreeSceneManager?, however CHC not working yet, many issues to resolve

Location:
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp

    r1177 r1182  
    332332        { 
    333333#ifdef KDTREE_DEBUG 
    334                 try 
     334                MaterialPtr mp = MaterialManager::getSingleton().getByName("aabbHiLite"); 
     335                if (mp.isNull()) 
    335336                { 
    336337                        ColourValue cv(0.0, 1.0, 0.0); 
     
    339340                        mp->setDiffuse(cv); 
    340341                } 
    341                 catch (Ogre::Exception&) 
    342                 { 
    343                         // SO FUCKING DON'T CARE !!! 
    344                 } 
     342                //try 
     343                //{ 
     344                //      ColourValue cv(0.0, 1.0, 0.0); 
     345                //      MaterialPtr mp = MaterialManager::getSingleton().create("aabbHiLite","General"); 
     346                //      mp->setSelfIllumination(cv); 
     347                //      mp->setDiffuse(cv); 
     348                //} 
     349                //catch (Ogre::Exception&) 
     350                //{ 
     351                //      // SO FUCKING DON'T CARE !!! 
     352                //} 
    345353#endif 
    346354                try 
     
    645653                unsigned long t1, t2, t3, t4; 
    646654                //AxisAlignedBox aabb; 
     655 
     656                mStats.clear(); 
    647657                 
    648658                // data we want to collect 
     
    657667                t3 = timer->getMicroseconds(); // DEBUG 
    658668 
     669                mStats.mNumSceneNodes = nObjects; 
    659670                // <DEBUG> 
    660671                //lm->logMessage("# of perfect splits " + StringConverter::toString(events.size())); 
     
    685696                t4 = timer->getMicroseconds(); // DEBUG 
    686697 
     698                String method = "Invalid"; 
     699                if (mBuildMethod == KDBM_RECURSIVE) 
     700                        method = "Recursive"; 
     701                else if (mBuildMethod == KDBM_PRIORITYQUEUE) 
     702                        method = "Priority Queue"; 
     703 
    687704                mBuildLog->logMessage("######## SAH Statistics ########"); 
     705                mBuildLog->logMessage("Build Method: " + method); 
    688706                mBuildLog->logMessage("Time for events build: " + StringConverter::toString(t2 - t1) + "µs"); 
    689707                mBuildLog->logMessage("Time for events sort: " + StringConverter::toString(t3 - t2) + "µs"); 
    690708                mBuildLog->logMessage("Time for tree build: " + StringConverter::toString(t4 - t3) + "µs"); 
    691709                mBuildLog->logMessage("Total time: " + StringConverter::toString(t4 - t1) + "µs"); 
    692                 mBuildLog->logMessage("######## SAH Statistics ########"); 
    693                 calcCost(); 
     710                mBuildLog->logMessage("Number of Objects: " + StringConverter::toString(mStats.mNumSceneNodes)); 
     711                mBuildLog->logMessage("Number of Leaves: " + StringConverter::toString(mStats.mNumLeaves)); 
     712                mBuildLog->logMessage("Number of Nodes: " + StringConverter::toString(mStats.mNumNodes)); 
     713                mBuildLog->logMessage("Total cost: " + StringConverter::toString(calcCost())); 
     714                mBuildLog->logMessage("################################"); 
    694715        } 
    695716 
     
    847868                                it++; 
    848869                        } 
     870                        // update stats 
     871                        ++ mStats.mNumNodes; 
     872                        ++ mStats.mNumLeaves; 
    849873                        return leaf; 
    850874                } 
     
    930954                                branch->mRight = recBuild(eventsRight, nBothS + nRightS, best.bright, branch); 
    931955                        } 
     956 
     957                        // update stats 
     958                        ++ mStats.mNumNodes; 
    932959 
    933960                        //assert(branch->mRight || branch->mLeft); 
     
    10081035                                if (!topNode) 
    10091036                                        topNode = leaf; 
     1037                                // update stats 
     1038                                ++ mStats.mNumNodes; 
     1039                                ++ mStats.mNumLeaves; 
    10101040                        } 
    10111041 
     
    11721202#endif 
    11731203                                } 
     1204                                // cleanup 
     1205                                else 
     1206                                { 
     1207                                        delete eventsLeft; 
     1208                                } 
    11741209                                if (eventsRight->size() > 0) 
    11751210                                { 
     
    11931228#endif 
    11941229                                } 
     1230                                // cleanup 
     1231                                else 
     1232                                { 
     1233                                        delete eventsRight; 
     1234                                } 
    11951235 
    11961236                                newNode = branch; 
    11971237                                if (!topNode) 
    11981238                                        topNode = branch; 
     1239 
     1240 
     1241                                // update stats 
     1242                                ++ mStats.mNumNodes; 
    11991243                        } 
    12001244 
     
    13851429        } 
    13861430 
    1387         void KdTree::calcCost() 
    1388         { 
    1389                 Real cost = 0; 
     1431        Real KdTree::calcCost() 
     1432        { 
    13901433                if (mKdRoot) 
    1391                         cost = calcCost(mKdRoot, PlaneEvent::surfaceArea(mKdRoot->mAABB)); 
    1392  
    1393                 //LogManager::getSingleton().logMessage("#@#@#@ One KdTree: €" + StringConverter::toString(cost)); 
    1394                 mBuildLog->logMessage("#@#@#@ One KdTree: €" + StringConverter::toString(cost)); 
     1434                        return calcCost(mKdRoot, PlaneEvent::surfaceArea(mKdRoot->mAABB)); 
     1435                else 
     1436                        return 0; 
    13951437        } 
    13961438 
  • GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp

    r1177 r1182  
    1010#include <OgreCamera.h> 
    1111#include <OgreSubEntity.h> 
     12#include <OgreMaterialManager.h> 
    1213#include "OgreKdTreeSceneManager.h" 
    1314#include "OgreKdTreeSceneNode.h" 
     
    2122namespace Ogre 
    2223{ 
    23         KdTreeSceneManager::KdTreeSceneManager(const String& name, GtpVisibility::VisibilityManager *vm): 
    24                 SceneManager(name),  
    25                 mVisibilityManager(vm),  
    26                 mKdTree(0),  
    27                 mMaxDepth(KDTREE_MAX_DEPTH), 
    28                 mShowBoxes(false), 
     24 
     25KdTreeSceneManager::KdTreeSceneManager(const String& name, GtpVisibility::VisibilityManager *vm): 
     26SceneManager(name),  
     27mVisibilityManager(vm),  
     28mKdTree(0),  
     29mMaxDepth(KDTREE_MAX_DEPTH), 
     30mShowBoxes(false), 
    2931#ifdef KDTREE_DEBUG 
    30                 mHighlighLevel(0), 
    31                 mShowAllBoxes(false), 
     32mHighlighLevel(0), 
     33mShowAllBoxes(false), 
    3234#endif 
    33                 mBuildMethod(KdTree::KDBM_PRIORITYQUEUE), 
    34                 mRenderMethod(KdTree::KDRM_INTERNAL), 
    35                 mLeavePassesInQueue(0), 
    36                 mCurrentEntityId(1) 
    37         { 
    38                 // Replace root node with my node 
    39                 OGRE_DELETE(mSceneRoot); 
    40  
    41                 mSceneRoot = new KdTreeSceneNode(this, "root node"); 
    42                 mSceneRoot->_notifyRootNode(); 
    43  
    44                 mHierarchyInterface = new KdTreeHierarchyInterface(this, mDestRenderSystem); 
    45         } 
    46  
    47         KdTreeSceneManager::~KdTreeSceneManager(void) 
    48         { 
    49                 delete mKdTree; 
    50         } 
    51  
    52         const String& KdTreeSceneManager::getTypeName(void) const 
    53         { 
    54                 return KdTreeSceneManagerFactory::FACTORY_TYPE_NAME; 
    55         } 
    56  
    57         void KdTreeSceneManager::setShowBoxes(bool showboxes) 
    58         { 
    59                 mShowBoxes = showboxes; 
    60         } 
    61  
    62         bool KdTreeSceneManager::getShowBoxes(void) const 
    63         { 
    64                 return mShowBoxes; 
    65         } 
    66  
    67         bool KdTreeSceneManager::setOption(const String& strKey, const void* pValue) 
    68         { 
    69                 // change max depth of the kdtree 
    70                 // rebuild the tree if already exists 
    71                 if (strKey == "KdTreeMaxDepth") 
    72                 { 
    73                         int maxdepth = *static_cast<const int *>(pValue); 
    74  
    75                         // no negative depth, plz! 
    76                         if (maxdepth < 0) 
    77                         { 
    78                                 return false; 
    79                         } 
     35mBuildMethod(KdTree::KDBM_PRIORITYQUEUE), 
     36mRenderMethod(KdTree::KDRM_INTERNAL), 
     37mShowVisualization(false), 
     38mRenderNodesForViz(false), 
     39mRenderNodesContentForViz(false), 
     40mVisualizeCulledNodes(false), 
     41mLeavePassesInQueue(0), 
     42mDelayRenderTransparents(true), 
     43mUseDepthPass(false), 
     44mIsDepthPassPhase(false), 
     45mUseItemBuffer(false), 
     46mIsItemBufferPhase(false), 
     47mCurrentEntityId(1), 
     48mEnableDepthWrite(true), 
     49mSkipTransparents(false), 
     50mRenderTransparentsForItemBuffer(true), 
     51mExecuteVertexProgramForAllPasses(false), 
     52mIsHierarchicalCulling(false) 
     53{ 
     54// Replace root node with my node 
     55OGRE_DELETE(mSceneRoot); 
     56 
     57mSceneRoot = new KdTreeSceneNode(this, "root node"); 
     58mSceneRoot->_notifyRootNode(); 
     59 
     60mHierarchyInterface = new KdTreeHierarchyInterface(this, mDestRenderSystem); 
     61} 
     62 
     63KdTreeSceneManager::~KdTreeSceneManager(void) 
     64{ 
     65        delete mHierarchyInterface; 
     66        delete mKdTree; 
     67} 
     68 
     69const String& KdTreeSceneManager::getTypeName(void) const 
     70{ 
     71        return KdTreeSceneManagerFactory::FACTORY_TYPE_NAME; 
     72} 
     73 
     74void KdTreeSceneManager::setShowBoxes(bool showboxes) 
     75{ 
     76        mShowBoxes = showboxes; 
     77} 
     78 
     79bool KdTreeSceneManager::getShowBoxes(void) const 
     80{ 
     81        return mShowBoxes; 
     82} 
     83 
     84bool KdTreeSceneManager::setOption(const String& strKey, const void* pValue) 
     85{ 
     86        // change max depth of the kdtree 
     87        // rebuild the tree if already exists 
     88        if (strKey == "KdTreeMaxDepth") 
     89        { 
     90                int maxdepth = *static_cast<const int *>(pValue); 
     91 
     92                // no negative depth, plz! 
     93                if (maxdepth < 0) 
     94                { 
     95                        return false; 
     96                } 
     97                else 
     98                { 
     99                        mMaxDepth = maxdepth; 
     100#ifdef KDTREE_DEBUG 
     101                        if (mHighlighLevel > mMaxDepth) 
     102                                mHighlighLevel = mMaxDepth; 
     103#endif 
     104                        return true; 
     105                } 
     106                return true; 
     107        } 
     108        else if (strKey == "KT") 
     109        { 
     110                Real kt = *static_cast<const Real *>(pValue); 
     111                if (kt > 0) 
     112                { 
     113                        PlaneEvent::KT = kt; 
     114                        return true; 
     115                } 
     116                else 
     117                { 
     118                        return false; 
     119                } 
     120        } 
     121        else if (strKey == "KI") 
     122        { 
     123                Real ki = *static_cast<const Real *>(pValue); 
     124                if (ki > 0) 
     125                { 
     126                        PlaneEvent::KI = ki; 
     127                        return true; 
     128                } 
     129                else 
     130                { 
     131                        return false; 
     132                } 
     133        } 
     134        else if (strKey == "RebuildKdTree") 
     135        { 
     136                OGRE_DELETE(mKdTree); 
     137                mKdTree = new KdTree(mMaxDepth); 
     138                mKdTree->setBuildMethod(mBuildMethod); 
     139                mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot)); 
     140                return true; 
     141        } 
     142#ifdef KDTREE_DEBUG 
     143        else if (strKey == "HighlightLevel") 
     144        { 
     145                int hl = *static_cast<const int *>(pValue); 
     146                if (hl >= 0 && hl <= mMaxDepth) 
     147                { 
     148                        mHighlighLevel = hl; 
     149                        return true; 
     150                } 
     151                else 
     152                { 
     153                        return false; 
     154                } 
     155        } 
     156        else if (strKey == "ShowAllBoxes") 
     157        { 
     158                bool sa = *static_cast<const bool *>(pValue); 
     159                mShowAllBoxes = sa; 
     160                return true; 
     161        } 
     162#endif 
     163        else if (strKey == "BuildMethod") 
     164        { 
     165                String bm = *static_cast<const String *>(pValue); 
     166                if (bm == "PriorityQueue") 
     167                { 
     168                        mBuildMethod = KdTree::KDBM_PRIORITYQUEUE; 
     169                        return true; 
     170                } 
     171                else if (bm == "Recursive") 
     172                { 
     173                        mBuildMethod = KdTree::KDBM_RECURSIVE; 
     174                        return true; 
     175                } 
     176                else 
     177                { 
     178                        return false; 
     179                } 
     180        } 
     181        else if (strKey == "RenderMethod") 
     182        { 
     183                String rm = *static_cast<const String *>(pValue); 
     184                if (rm == "INT") 
     185                { 
     186                        mRenderMethod = KdTree::KDRM_INTERNAL; 
     187                        return true; 
     188                } 
     189                else if (rm == "VFC") 
     190                { 
     191                        mRenderMethod = KdTree::KDRM_GTP_VFC; 
     192                        int cmt = GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING; 
     193                        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
     194                                .setOption("Algorithm", &cmt); 
     195                } 
     196                else if (rm == "SWC") 
     197                { 
     198                        mRenderMethod = KdTree::KDRM_GTP_SWC; 
     199                        int cmt = GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING; 
     200                        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
     201                                .setOption("Algorithm", &cmt); 
     202                } 
     203                else if (rm == "CHC") 
     204                { 
     205                        mRenderMethod = KdTree::KDRM_GTP_CHC; 
     206                        int cmt = GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING; 
     207                        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
     208                                .setOption("Algorithm", &cmt); 
     209                } 
     210                else 
     211                { 
     212                        return false; 
     213                } 
     214        } 
     215        // little hack in case someone uses "Algorithm" option from VisOptMan directly 
     216        else if (strKey == "Algorithm") 
     217        { 
     218                bool success = VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
     219                        .setOption(strKey, pValue); 
     220                // change setting only if change in VisOptMan was successful 
     221                if (success) 
     222                { 
     223                        int val = *static_cast<const int *>(pValue); 
     224                        if (val == GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING) 
     225                                mRenderMethod = KdTree::KDRM_GTP_VFC; 
     226                        else if (val == GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING) 
     227                                mRenderMethod = KdTree::KDRM_GTP_SWC; 
     228                        else if (val == GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING) 
     229                                mRenderMethod = KdTree::KDRM_GTP_CHC; 
     230                        // default, should never happen 
    80231                        else 
    81                         { 
    82                                 mMaxDepth = maxdepth; 
     232                                mRenderMethod = KdTree::KDRM_INTERNAL; 
     233                } 
     234                return success; 
     235        } 
     236        else if (strKey == "ShowKdTree") 
     237        { 
     238                bool sk = *static_cast<const bool *>(pValue); 
     239                mShowBoxes = sk; 
     240                return true; 
     241        } 
     242 
     243        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
     244                .setOption(strKey, pValue) || SceneManager::setOption(strKey, pValue); 
     245} 
     246 
     247bool KdTreeSceneManager::getOption(const String& strKey, void* pDestValue) 
     248{ 
     249        if (strKey == "KdTreeMaxDepth") 
     250        { 
     251                *static_cast<int *>(pDestValue) = mMaxDepth; 
     252                return true; 
     253        } 
     254        else if (strKey == "KT") 
     255        { 
     256                *static_cast<Real *>(pDestValue) = PlaneEvent::KT; 
     257                return true; 
     258        } 
     259        else if (strKey == "KI") 
     260        { 
     261                *static_cast<Real *>(pDestValue) = PlaneEvent::KI; 
     262                return true; 
     263        } 
    83264#ifdef KDTREE_DEBUG 
    84                                 if (mHighlighLevel > mMaxDepth) 
    85                                         mHighlighLevel = mMaxDepth; 
     265        else if (strKey == "HighlightLevel") 
     266        { 
     267                *static_cast<int *>(pDestValue) = mHighlighLevel; 
     268                return true; 
     269        } 
     270        else if (strKey == "ShowAllBoxes") 
     271        { 
     272                *static_cast<bool *>(pDestValue) = mShowAllBoxes; 
     273                return true; 
     274        } 
    86275#endif 
    87                                 return true; 
    88                         } 
    89                         return true; 
    90                 } 
    91                 else if (strKey == "KT") 
    92                 { 
    93                         Real kt = *static_cast<const Real *>(pValue); 
    94                         if (kt > 0) 
    95                         { 
    96                                 PlaneEvent::KT = kt; 
    97                                 return true; 
    98                         } 
    99                         else 
    100                         { 
    101                                 return false; 
    102                         } 
    103                 } 
    104                 else if (strKey == "KI") 
    105                 { 
    106                         Real ki = *static_cast<const Real *>(pValue); 
    107                         if (ki > 0) 
    108                         { 
    109                                 PlaneEvent::KI = ki; 
    110                                 return true; 
    111                         } 
    112                         else 
    113                         { 
    114                                 return false; 
    115                         } 
    116                 } 
    117                 else if (strKey == "RebuildKdTree") 
    118                 { 
    119                         OGRE_DELETE(mKdTree); 
    120                         mKdTree = new KdTree(mMaxDepth); 
    121                         mKdTree->setBuildMethod(mBuildMethod); 
    122                         mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot)); 
    123                         return true; 
    124                 } 
     276        else if (strKey == "BuildMethod") 
     277        { 
     278                if (mBuildMethod == KdTree::KDBM_PRIORITYQUEUE) 
     279                { 
     280                        *static_cast<String *>(pDestValue) = "PriorityQueue"; 
     281                } 
     282                else if (mBuildMethod == KdTree::KDBM_RECURSIVE) 
     283                { 
     284                        *static_cast<String *>(pDestValue) = "Recursive"; 
     285                } 
     286                return true; 
     287        } 
     288        else if (strKey == "RenderMethod") 
     289        { 
     290                if (mRenderMethod == KdTree::KDRM_INTERNAL) 
     291                { 
     292                        *static_cast<String *>(pDestValue) = "INT"; 
     293                } 
     294                else if (mRenderMethod == KdTree::KDRM_GTP_VFC) 
     295                { 
     296                                *static_cast<String *>(pDestValue) = "VFC"; 
     297                } 
     298                else if (mRenderMethod == KdTree::KDRM_GTP_SWC) 
     299                { 
     300                                *static_cast<String *>(pDestValue) = "SWC"; 
     301                } 
     302                else if (mRenderMethod == KdTree::KDRM_GTP_CHC) 
     303                { 
     304                                *static_cast<String *>(pDestValue) = "CHC"; 
     305                } 
     306                else 
     307                { 
     308                        return false; 
     309                } 
     310                return true; 
     311        } 
     312        else if (strKey == "TreeBox") 
     313        { 
     314                if (mKdTree) 
     315                        *static_cast<AxisAlignedBox *>(pDestValue) = mKdTree->getBox(); 
     316                else 
     317                        *static_cast<AxisAlignedBox *>(pDestValue) = AxisAlignedBox(); 
     318        } 
     319 
     320        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
     321                .getOption(strKey, pDestValue) || SceneManager::getOption(strKey, pDestValue); 
     322} 
     323 
     324bool KdTreeSceneManager::getOptionKeys(StringVector &refKeys) 
     325{ 
     326        refKeys.push_back("BuildMethod"); 
     327        refKeys.push_back("KI"); 
     328        refKeys.push_back("KT"); 
     329        refKeys.push_back("KdTreeMaxDepth"); 
     330        refKeys.push_back("RebuildKdTree"); 
     331        refKeys.push_back("RenderMethod"); 
     332        refKeys.push_back("ShowKdTree"); 
     333        refKeys.push_back("TreeBox"); 
    125334#ifdef KDTREE_DEBUG 
    126                 else if (strKey == "HighlightLevel") 
    127                 { 
    128                         int hl = *static_cast<const int *>(pValue); 
    129                         if (hl >= 0 && hl <= mMaxDepth) 
    130                         { 
    131                                 mHighlighLevel = hl; 
    132                                 return true; 
    133                         } 
    134                         else 
    135                         { 
    136                                 return false; 
    137                         } 
    138                 } 
    139                 else if (strKey == "ShowAllBoxes") 
    140                 { 
    141                         bool sa = *static_cast<const bool *>(pValue); 
    142                         mShowAllBoxes = sa; 
    143                         return true; 
    144                 } 
     335        refKeys.push_back("HighlightLevel"); 
     336        refKeys.push_back("ShowAllBoxes"); 
    145337#endif 
    146                 else if (strKey == "BuildMethod") 
    147                 { 
    148                         String bm = *static_cast<const String *>(pValue); 
    149                         if (bm == "PriorityQueue") 
    150                         { 
    151                                 mBuildMethod = KdTree::KDBM_PRIORITYQUEUE; 
    152                                 return true; 
    153                         } 
    154                         else if (bm == "Recursive") 
    155                         { 
    156                                 mBuildMethod = KdTree::KDBM_RECURSIVE; 
    157                                 return true; 
    158                         } 
    159                         else 
    160                         { 
    161                                 return false; 
    162                         } 
    163                 } 
    164                 else if (strKey == "RenderMethod") 
    165                 { 
    166                         String rm = *static_cast<const String *>(pValue); 
    167                         if (rm == "INT") 
    168                         { 
    169                                 mRenderMethod = KdTree::KDRM_INTERNAL; 
    170                                 return true; 
    171                         } 
    172                         else if (rm == "VFC") 
    173                         { 
    174                                 mRenderMethod = KdTree::KDRM_GTP_VFC; 
    175                                 int cmt = GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING; 
    176                                 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
    177                                         .setOption("Algorithm", &cmt); 
    178                         } 
    179                         else if (rm == "SWC") 
    180                         { 
    181                                 mRenderMethod = KdTree::KDRM_GTP_SWC; 
    182                                 int cmt = GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING; 
    183                                 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
    184                                         .setOption("Algorithm", &cmt); 
    185                         } 
    186                         else if (rm == "CHC") 
    187                         { 
    188                                 mRenderMethod = KdTree::KDRM_GTP_CHC; 
    189                                 int cmt = GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING; 
    190                                 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
    191                                         .setOption("Algorithm", &cmt); 
    192                         } 
    193                         else 
    194                         { 
    195                                 return false; 
    196                         } 
    197                 } 
    198                 // little hack in case someone uses "Algorithm" option from VisOptMan directly 
    199                 else if (strKey == "Algorithm") 
    200                 { 
    201                         bool success = VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
    202                                 .setOption(strKey, pValue); 
    203                         // change setting only if change in VisOptMan was successful 
    204                         if (success) 
    205                         { 
    206                                 int val = *static_cast<const int *>(pValue); 
    207                                 if (val == GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING) 
    208                                         mRenderMethod = KdTree::KDRM_GTP_VFC; 
    209                                 else if (val == GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING) 
    210                                         mRenderMethod = KdTree::KDRM_GTP_SWC; 
    211                                 else if (val == GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING) 
    212                                         mRenderMethod = KdTree::KDRM_GTP_CHC; 
    213                                 // default, should never happen 
    214                                 else 
    215                                         mRenderMethod = KdTree::KDRM_INTERNAL; 
    216                         } 
    217                         return success; 
    218                 } 
    219                 else if (strKey == "ShowKdTree") 
    220                 { 
    221                         bool sk = *static_cast<const bool *>(pValue); 
    222                         mShowBoxes = sk; 
    223                         return true; 
    224                 } 
    225  
    226                 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
    227                         .setOption(strKey, pValue) || SceneManager::setOption(strKey, pValue); 
    228         } 
    229  
    230         bool KdTreeSceneManager::getOption(const String& strKey, void* pDestValue) 
    231         { 
    232                 if (strKey == "KdTreeMaxDepth") 
    233                 { 
    234                         *static_cast<int *>(pDestValue) = mMaxDepth; 
    235                         return true; 
    236                 } 
    237                 else if (strKey == "KT") 
    238                 { 
    239                         *static_cast<Real *>(pDestValue) = PlaneEvent::KT; 
    240                         return true; 
    241                 } 
    242                 else if (strKey == "KI") 
    243                 { 
    244                         *static_cast<Real *>(pDestValue) = PlaneEvent::KI; 
    245                         return true; 
    246                 } 
    247 #ifdef KDTREE_DEBUG 
    248                 else if (strKey == "HighlightLevel") 
    249                 { 
    250                         *static_cast<int *>(pDestValue) = mHighlighLevel; 
    251                         return true; 
    252                 } 
    253                 else if (strKey == "ShowAllBoxes") 
    254                 { 
    255                         *static_cast<bool *>(pDestValue) = mShowAllBoxes; 
    256                         return true; 
    257                 } 
     338        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
     339                .getOptionKeys(refKeys); 
     340} 
     341 
     342bool KdTreeSceneManager::getOptionValues(const String & key, StringVector &refValueList) 
     343{ 
     344        return SceneManager::getOptionValues(key, refValueList); 
     345} 
     346 
     347void KdTreeSceneManager::setVisibilityManager(GtpVisibility::VisibilityManager *visManager) 
     348{ 
     349        mVisibilityManager = visManager; 
     350} 
     351 
     352GtpVisibility::VisibilityManager * KdTreeSceneManager::getVisibilityManager() 
     353{ 
     354        return mVisibilityManager; 
     355} 
     356 
     357GtpVisibility::VisibilityManager * KdTreeSceneManager::GetVisibilityManager() 
     358{ 
     359        return mVisibilityManager; 
     360} 
     361 
     362KdTreeHierarchyInterface * KdTreeSceneManager::GetHierarchyInterface() 
     363{ 
     364        return mHierarchyInterface; 
     365} 
     366 
     367SceneNode* KdTreeSceneManager::createSceneNode(void) 
     368{ 
     369        SceneNode* sn = new KdTreeSceneNode(this); 
     370        assert(mSceneNodes.find(sn->getName()) == mSceneNodes.end()); 
     371        mSceneNodes[sn->getName()] = sn; 
     372        return sn; 
     373} 
     374 
     375SceneNode* KdTreeSceneManager::createSceneNode(const String& name) 
     376{ 
     377        // Check name not used 
     378        if (mSceneNodes.find(name) != mSceneNodes.end()) 
     379        { 
     380                OGRE_EXCEPT( 
     381                        Exception::ERR_DUPLICATE_ITEM, 
     382                        "A scene node with the name " + name + " already exists", 
     383                        "KdTreeSceneManager::createSceneNode" ); 
     384        } 
     385 
     386        SceneNode* sn = new KdTreeSceneNode(this, name); 
     387        mSceneNodes[sn->getName()] = sn; 
     388        return sn; 
     389} 
     390 
     391Entity * KdTreeSceneManager::createEntity(const String& entityName, const String& meshName) 
     392{ 
     393        Entity *ent = SceneManager::createEntity(entityName, meshName); 
     394#ifdef GTP_VISIBILITY_MODIFIED_OGRE 
     395        for (int i = 0; i < (int)ent->getNumSubEntities(); ++i) 
     396        { 
     397                ent->getSubEntity(i)->setId(mCurrentEntityId); 
     398        } 
     399 
     400        // increase counter of entity id values 
     401        ++ mCurrentEntityId; 
    258402#endif 
    259                 else if (strKey == "BuildMethod") 
    260                 { 
    261                         if (mBuildMethod == KdTree::KDBM_PRIORITYQUEUE) 
    262                         { 
    263                                 *static_cast<String *>(pDestValue) = "PriorityQueue"; 
    264                         } 
    265                         else if (mBuildMethod == KdTree::KDBM_RECURSIVE) 
    266                         { 
    267                                 *static_cast<String *>(pDestValue) = "Recursive"; 
    268                         } 
    269                         return true; 
    270                 } 
    271                 else if (strKey == "RenderMethod") 
    272                 { 
    273                         if (mRenderMethod == KdTree::KDRM_INTERNAL) 
    274                         { 
    275                                 *static_cast<String *>(pDestValue) = "INT"; 
    276                         } 
    277                         else if (mRenderMethod == KdTree::KDRM_GTP_VFC) 
    278                         { 
    279                                         *static_cast<String *>(pDestValue) = "VFC"; 
    280                         } 
    281                         else if (mRenderMethod == KdTree::KDRM_GTP_SWC) 
    282                         { 
    283                                         *static_cast<String *>(pDestValue) = "SWC"; 
    284                         } 
    285                         else if (mRenderMethod == KdTree::KDRM_GTP_CHC) 
    286                         { 
    287                                         *static_cast<String *>(pDestValue) = "CHC"; 
    288                         } 
    289                         else 
    290                         { 
    291                                 return false; 
    292                         } 
    293                         return true; 
    294                 } 
    295                 else if (strKey == "TreeBox") 
    296                 { 
    297                         if (mKdTree) 
    298                                 *static_cast<AxisAlignedBox *>(pDestValue) = mKdTree->getBox(); 
    299                         else 
    300                                 *static_cast<AxisAlignedBox *>(pDestValue) = AxisAlignedBox(); 
    301                 } 
    302  
    303                 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
    304                         .getOption(strKey, pDestValue) || SceneManager::getOption(strKey, pDestValue); 
    305         } 
    306  
    307         bool KdTreeSceneManager::getOptionKeys(StringVector &refKeys) 
    308         { 
    309                 refKeys.push_back("BuildMethod"); 
    310                 refKeys.push_back("KI"); 
    311                 refKeys.push_back("KT"); 
    312                 refKeys.push_back("KdTreeMaxDepth"); 
    313                 refKeys.push_back("RebuildKdTree"); 
    314                 refKeys.push_back("RenderMethod"); 
    315                 refKeys.push_back("ShowKdTree"); 
    316                 refKeys.push_back("TreeBox"); 
    317 #ifdef KDTREE_DEBUG 
    318                 refKeys.push_back("HighlightLevel"); 
    319                 refKeys.push_back("ShowAllBoxes"); 
    320 #endif 
    321                 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface) 
    322                         .getOptionKeys(refKeys); 
    323         } 
    324  
    325         bool KdTreeSceneManager::getOptionValues(const String & key, StringVector &refValueList) 
    326         { 
    327                 return SceneManager::getOptionValues(key, refValueList); 
    328         } 
    329  
    330         void KdTreeSceneManager::setVisibilityManager(GtpVisibility::VisibilityManager *visManager) 
    331         { 
    332                 mVisibilityManager = visManager; 
    333         } 
    334  
    335         GtpVisibility::VisibilityManager * KdTreeSceneManager::getVisibilityManager() 
    336         { 
    337                 return mVisibilityManager; 
    338         } 
    339  
    340         GtpVisibility::VisibilityManager * KdTreeSceneManager::GetVisibilityManager() 
    341         { 
    342                 return mVisibilityManager; 
    343         } 
    344  
    345         KdTreeHierarchyInterface * KdTreeSceneManager::GetHierarchyInterface() 
    346         { 
    347                 return mHierarchyInterface; 
    348         } 
    349  
    350         SceneNode* KdTreeSceneManager::createSceneNode(void) 
    351         { 
    352                 SceneNode* sn = new KdTreeSceneNode(this); 
    353                 assert(mSceneNodes.find(sn->getName()) == mSceneNodes.end()); 
    354                 mSceneNodes[sn->getName()] = sn; 
    355                 return sn; 
    356         } 
    357  
    358         SceneNode* KdTreeSceneManager::createSceneNode(const String& name) 
    359         { 
    360                 // Check name not used 
    361                 if (mSceneNodes.find(name) != mSceneNodes.end()) 
    362                 { 
    363                         OGRE_EXCEPT( 
    364                                 Exception::ERR_DUPLICATE_ITEM, 
    365                                 "A scene node with the name " + name + " already exists", 
    366                                 "KdTreeSceneManager::createSceneNode" ); 
    367                 } 
    368  
    369                 SceneNode* sn = new KdTreeSceneNode(this, name); 
    370                 mSceneNodes[sn->getName()] = sn; 
    371                 return sn; 
    372         } 
    373  
    374         Entity * KdTreeSceneManager::createEntity(const String& entityName, const String& meshName) 
    375         { 
    376                 Entity *ent = SceneManager::createEntity(entityName, meshName); 
    377 #ifdef GTP_VISIBILITY_MODIFIED_OGRE 
    378                 for (int i = 0; i < (int)ent->getNumSubEntities(); ++i) 
    379                 { 
    380                         ent->getSubEntity(i)->setId(mCurrentEntityId); 
    381                 } 
    382  
    383                 // increase counter of entity id values 
    384                 ++ mCurrentEntityId; 
    385 #endif 
    386                 return ent; 
    387         } 
    388  
    389         // make sure it's called only for non-empty nodes .. avoids one uneccessary funciton call 
    390         void KdTreeSceneManager::_updateNode(KdTreeSceneNode *node) 
    391         { 
    392                 //LogManager::getSingleton().logMessage("### _updateNode called for " + node->getName()); 
    393  
    394                 /* Rebuild kdtree when it was wiped out 
    395                  * Usually this happens only before the first frame 
    396                  * The initial AABB shall enclose all objects present 
    397                  * in the scene at the time of construction 
    398                  * TODO: find a more appropriate place for it, 
    399                  * e.g., before the first render call 
    400                  * teh stupid thing is I can't find any other place so far ... 
    401                  */ 
    402                 if (!mKdTree) 
    403                 { 
    404                         mKdTree = new KdTree(mMaxDepth); 
    405                         mKdTree->setBuildMethod(mBuildMethod); 
    406                         mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot)); 
    407                 } 
    408  
    409                 // if the node is in the tree and _updateNode was called, then the node was moved/rotated/resized/wahtever 
    410                 if (node->isAttached()) 
    411                 { 
    412                         // TEST: perfomance when adding & removing for every frame 
    413                         //mKdTree->remove(node); 
    414                         //mKdTree->insert(node); 
    415                 } 
    416                 // there's a new node in town ...  
    417                 else 
    418                 {                        
    419                         // inserting single nodes yields sub-optimal results 
    420                         // rebuilding tree takes too long 
    421                         // "What now?", spoke Zeus ... 
    422  
    423                         //mKdTree->insert(node); 
    424                          
    425                         //delete mKdTree; 
    426                         //mKdTree = new KdTree(mMaxDepth); 
    427                         //mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot)); 
    428                 } 
    429  
    430         } 
    431  
    432         void KdTreeSceneManager::_updateSceneGraph(Camera* cam) 
    433         { 
    434                 mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface); 
    435                 mHierarchyInterface->SetRenderSystem(mDestRenderSystem); 
    436  
    437                 SceneManager::_updateSceneGraph(cam); 
    438         } 
    439  
    440         void KdTreeSceneManager::_findVisibleObjects(Camera *cam, bool onlyShadowCasters) 
     403        return ent; 
     404} 
     405 
     406// make sure it's called only for non-empty nodes .. avoids one uneccessary funciton call 
     407void KdTreeSceneManager::_updateNode(KdTreeSceneNode *node) 
     408{ 
     409        //LogManager::getSingleton().logMessage("### _updateNode called for " + node->getName()); 
     410 
     411        /* Rebuild kdtree when it was wiped out 
     412                * Usually this happens only before the first frame 
     413                * The initial AABB shall enclose all objects present 
     414                * in the scene at the time of construction 
     415                * TODO: find a more appropriate place for it, 
     416                * e.g., before the first render call 
     417                * teh stupid thing is I can't find any other place so far ... 
     418                */ 
     419        if (!mKdTree) 
     420        { 
     421                mKdTree = new KdTree(mMaxDepth); 
     422                mKdTree->setBuildMethod(mBuildMethod); 
     423                mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot)); 
     424        } 
     425 
     426        // if the node is in the tree and _updateNode was called, then the node was moved/rotated/resized/wahtever 
     427        if (node->isAttached()) 
     428        { 
     429                // TEST: perfomance when adding & removing for every frame 
     430                //mKdTree->remove(node); 
     431                //mKdTree->insert(node); 
     432        } 
     433        // there's a new node in town ...  
     434        else 
     435        {                        
     436                // inserting single nodes yields sub-optimal results 
     437                // rebuilding tree takes too long 
     438                // "What now?", spoke Zeus ... 
     439 
     440                //mKdTree->insert(node); 
     441                 
     442                //delete mKdTree; 
     443                //mKdTree = new KdTree(mMaxDepth); 
     444                //mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot)); 
     445        } 
     446 
     447} 
     448 
     449void KdTreeSceneManager::_updateSceneGraph(Camera* cam) 
     450{ 
     451        mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface); 
     452        mHierarchyInterface->SetRenderSystem(mDestRenderSystem); 
     453 
     454        SceneManager::_updateSceneGraph(cam); 
     455} 
     456 
     457void KdTreeSceneManager::_findVisibleObjects(Camera *cam, bool onlyShadowCasters) 
     458{ 
     459        if (mRenderMethod == KdTree::KDRM_INTERNAL) 
    441460        { 
    442461                getRenderQueue()->clear(); 
    443462                if (mKdTree) 
    444463                        mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, mRenderMethod, mShowBoxes); 
    445                 //SceneManager::_findVisibleObjects(cam, onlyShadowCasters); 
    446         } 
    447  
    448         // TODO: looks too easy, verify if it works  
    449         void KdTreeSceneManager::_renderNodes(const KdRenderableList& nodelist, Camera * cam,  
    450                 bool onlyShadowCasters, int leavePassesInQueue) 
    451         { 
     464        } 
     465        else 
     466        { 
     467                //-- show visible scene nodes and octree bounding boxes from last frame 
     468                if (mShowVisualization) 
     469                { 
     470                        PrepareVisualization(cam); 
     471                } 
     472                else  
     473                {        
     474                        // for hierarchical culling, we interleave identification  
     475                        // and rendering of objects in _renderVisibibleObjects 
     476 
     477                        // for the shadow pass we use only standard rendering 
     478                        // because of low occlusion 
     479                        if (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&  
     480                                mIlluminationStage == IRS_RENDER_TO_TEXTURE) 
     481                        { 
     482                                getRenderQueue()->clear(); 
     483                                if (mKdTree) 
     484                                        mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, mRenderMethod, mShowBoxes); 
     485                        } 
     486 
     487                        // only shadow casters will be rendered in shadow texture pass 
     488                        if (0) mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters); 
     489 
     490 
     491                        //-- apply view cell pvs - TODO 
     492                        //updatePvs(cam); 
     493                } 
     494        } 
     495} 
     496 
     497void KdTreeSceneManager::_renderVisibleObjects() 
     498{ 
     499        if (mRenderMethod == KdTree::KDRM_INTERNAL) 
     500        { 
     501                SceneManager::_renderVisibleObjects(); 
     502        } 
     503        else 
     504        { 
     505                InitDepthPass();          // create material for depth pass 
     506                InitItemBufferPass(); // create material for item buffer pass 
     507 
     508                // save ambient light to reset later 
     509                ColourValue savedAmbient = mAmbientLight; 
     510 
     511                //-- apply standard rendering for some modes (e.g., visualization, shadow pass) 
     512 
     513                if (mShowVisualization || 
     514                        (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&  
     515                        mIlluminationStage == IRS_RENDER_TO_TEXTURE)) 
     516                {        
     517                        IlluminationRenderStage savedStage = mIlluminationStage;  
     518 
     519                        if (mShowVisualization)  
     520                        { 
     521                                // disable illumination stage to prevent rendering shadows 
     522                                mIlluminationStage = IRS_NONE; 
     523                        } 
     524 
     525                        // standard rendering for shadow maps because of performance 
     526                        SceneManager::_renderVisibleObjects(); 
     527 
     528                        mIlluminationStage = savedStage; 
     529                } 
     530                else //-- the hierarchical culling algorithm 
     531                { 
     532                        // this is also called in TerrainSceneManager: really 
     533                        // necessary? 
     534                        //mDestRenderSystem -> setLightingEnabled(false); 
     535 
     536                        // don't render backgrounds for item buffer 
     537                        if (mUseItemBuffer) 
     538                        { 
     539                                clearSpecialCaseRenderQueues(); 
     540                                getRenderQueue()->clear(); 
     541                        } 
     542 
     543                        //-- hierarchical culling 
     544                        // the objects of different layers (e.g., background, scene,  
     545                        // overlay) must be identified and rendered one after another 
     546 
     547                        //-- render all early skies 
     548                        clearSpecialCaseRenderQueues(); 
     549                        addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND); 
     550                        addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY); 
     551                        setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE); 
     552 
     553                        SceneManager::_renderVisibleObjects(); 
     554 
    452555#ifdef GTP_VISIBILITY_MODIFIED_OGRE 
    453                 _deleteRenderedQueueGroups(leavePassesInQueue); //try avoiding modified ogre code 
     556                        // delete previously rendered content 
     557                        _deleteRenderedQueueGroups(); 
     558#endif 
     559 
     560                        //-- prepare queue for visible objects (i.e., all but overlay and skies late) 
     561                        clearSpecialCaseRenderQueues(); 
     562                        addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE); 
     563                        addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY); 
     564 
     565                        // exclude this queues from hierarchical rendering 
     566                        setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE); 
     567 
     568 
     569                        // set all necessary parameters for  
     570                        // hierarchical visibility culling and rendering 
     571                        InitVisibilityCulling(mCameraInProgress); 
     572 
     573 
     574                        /**  
     575                        * the hierarchical culling algorithm 
     576                        * for depth pass: we just find objects and update depth buffer 
     577                        * for "delayed" rendering: we render some passes afterwards 
     578                        * e.g., transparents, because they need front-to-back sorting 
     579                        **/ 
     580 
     581                        mVisibilityManager->ApplyVisibilityCulling(); 
     582 
     583                        // delete remaining renderables from queue: 
     584                        // all which are not in mLeavePassesInQueue) 
     585#ifdef GTP_VISIBILITY_MODIFIED_OGRE 
     586                        _deleteRenderedQueueGroups(mLeavePassesInQueue); 
     587#endif 
     588 
     589                        //-- reset parameters 
     590                        mIsDepthPassPhase = false; 
     591                        mIsItemBufferPhase = false; 
     592                        mSkipTransparents = false; 
     593                        mIsHierarchicalCulling = false; 
     594 
     595                        mLeavePassesInQueue = 0; 
     596 
     597#if 1    
     598                        // add visible nodes found by the visibility culling algorithm 
     599                        if (mUseDepthPass) 
     600                        { 
     601                                //NodeList::const_iterator it, it_end = mVisible.end(); 
     602 
     603                                ////getRenderQueue()->clear(); 
     604                                //for (it = mVisible.begin(); it != it_end; ++ it) 
     605                                //{ 
     606                                //      (*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false); 
     607                                //} 
     608                        } 
     609#endif   
     610                        //-- now we can render all remaining queue objects 
     611                        //-- used for depth pass, transparents, overlay 
     612                        clearSpecialCaseRenderQueues(); 
     613 
     614                        SceneManager::_renderVisibleObjects(); 
     615                } // hierarchical culling 
     616 
     617 
     618                // reset ambient light 
     619                setAmbientLight(savedAmbient); 
     620 
     621                getRenderQueue()->clear(); // finally clear render queue 
     622                if (0) OGRE_DELETE(mRenderQueue); // HACK: should rather only be cleared ... 
     623 
     624                if (0) WriteLog(); // write out stats 
     625        } 
     626} 
     627 
     628// TODO: looks too easy, verify if it works  
     629void KdTreeSceneManager::_renderNodes(const KdRenderableList& nodelist, Camera * cam,  
     630        bool onlyShadowCasters, int leavePassesInQueue) 
     631{ 
     632#ifdef GTP_VISIBILITY_MODIFIED_OGRE 
     633        _deleteRenderedQueueGroups(leavePassesInQueue); //try avoiding modified ogre code 
    454634#else 
    455                 getRenderQueue()->clear(); 
     635        getRenderQueue()->clear(); 
    456636#endif 
    457                 KdRenderableList::const_iterator it = nodelist.begin(); 
    458                 KdRenderableList::const_iterator end = nodelist.end(); 
    459                 while (it != end) 
    460                 { 
    461                         (*it)->queueObjects(cam, getRenderQueue(), onlyShadowCasters); 
    462                         it++; 
    463                 } 
    464  
    465                 SceneManager::_renderVisibleObjects(); 
    466  
    467         } 
    468  
    469         //----------------------------------------------------------------------- 
    470         //----------------------------------------------------------------------- 
    471         const String KdTreeSceneManagerFactory::FACTORY_TYPE_NAME = "KdTreeSceneManager"; 
    472         //----------------------------------------------------------------------- 
    473         void KdTreeSceneManagerFactory::initMetaData(void) const 
    474         { 
    475                 mMetaData.typeName = FACTORY_TYPE_NAME; 
    476                 mMetaData.description = "Scene manager that organises the scene based on a kd-tree"; 
    477                 mMetaData.sceneTypeMask = 0xFFFF; // support all types of scenes (hopefully) 
    478                 mMetaData.worldGeometrySupported = false; 
    479         } 
    480         //----------------------------------------------------------------------- 
    481         SceneManager* KdTreeSceneManagerFactory::createInstance( 
    482                 const String& instanceName) 
    483         { 
    484                 return new KdTreeSceneManager(instanceName, visManager); 
    485         } 
    486         //----------------------------------------------------------------------- 
    487         void KdTreeSceneManagerFactory::destroyInstance(SceneManager* instance) 
    488         { 
    489                 delete instance; 
    490         } 
     637        KdRenderableList::const_iterator it = nodelist.begin(); 
     638        KdRenderableList::const_iterator end = nodelist.end(); 
     639        while (it != end) 
     640        { 
     641                (*it)->queueObjects(cam, getRenderQueue(), onlyShadowCasters); 
     642                it++; 
     643        } 
     644 
     645        SceneManager::_renderVisibleObjects(); 
     646 
     647} 
     648//----------------------------------------------------------------------- 
     649void KdTreeSceneManager::renderBasicQueueGroupObjects(RenderQueueGroup* pGroup, 
     650                                                                                                          QueuedRenderableCollection::OrganisationMode om) 
     651{ 
     652        // Basic render loop 
     653        // Iterate through priorities 
     654        RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); 
     655 
     656        while (groupIt.hasMoreElements()) 
     657        { 
     658                RenderPriorityGroup* pPriorityGrp = groupIt.getNext(); 
     659 
     660                // Sort the queue first 
     661                pPriorityGrp->sort(mCameraInProgress); 
     662 
     663                // Do solids 
     664                renderObjects(pPriorityGrp->getSolidsBasic(), om, true); 
     665 
     666                // for correct rendering, transparents must be rendered after hierarchical culling 
     667                // => do nothing 
     668 
     669                // Do transparents (always descending) 
     670                if (mRenderMethod == KdTree::KDRM_INTERNAL || !mSkipTransparents) 
     671                { 
     672                        renderObjects(pPriorityGrp->getTransparents(),  
     673                                QueuedRenderableCollection::OM_SORT_DESCENDING, true); 
     674                } 
     675 
     676 
     677        }// for each priority 
     678} 
     679//----------------------------------------------------------------------- 
     680bool KdTreeSceneManager::validatePassForRendering(Pass* pass) 
     681{ 
     682        if (mRenderMethod == KdTree::KDRM_INTERNAL) 
     683        { 
     684                return SceneManager::validatePassForRendering(pass); 
     685        } 
     686 
     687        // skip all but first pass if we are doing the depth pass 
     688        if ((mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() > 0)) 
     689        { 
     690                return false; 
     691        } 
     692        // all but first pass 
     693        /*else if ((!mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() != 0)) 
     694        { 
     695        return false; 
     696        }*/ 
     697 
     698        return SceneManager::validatePassForRendering(pass); 
     699} 
     700//----------------------------------------------------------------------- 
     701void KdTreeSceneManager::_renderQueueGroupObjects(RenderQueueGroup* pGroup,  
     702                                                                                                  QueuedRenderableCollection::OrganisationMode om) 
     703{ 
     704        if (mRenderMethod == KdTree::KDRM_INTERNAL || !mIsItemBufferPhase) 
     705        { 
     706                SceneManager::_renderQueueGroupObjects(pGroup, om); 
     707                return; 
     708        } 
     709#ifdef  ITEM_BUFFER 
     710        //-- item buffer 
     711        //-- item buffer: render objects using false colors 
     712 
     713        // Iterate through priorities 
     714        RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); 
     715 
     716        while (groupIt.hasMoreElements()) 
     717        { 
     718                RenderItemBuffer(groupIt.getNext()); 
     719        } 
     720#endif // ITEM_BUFFER 
     721} 
     722//----------------------------------------------------------------------- 
     723void KdTreeSceneManager::renderAdditiveStencilShadowedQueueGroupObjects( 
     724        RenderQueueGroup* pGroup, QueuedRenderableCollection::OrganisationMode om) 
     725{ 
     726        // only render solid passes during hierarchical culling 
     727        if (mIsHierarchicalCulling) 
     728        { 
     729                RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); 
     730                LightList lightList; 
     731 
     732                while (groupIt.hasMoreElements()) 
     733                { 
     734                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext(); 
     735 
     736                        // Sort the queue first 
     737                        pPriorityGrp->sort(mCameraInProgress); 
     738 
     739                        // Clear light list 
     740                        lightList.clear(); 
     741 
     742                        // Render all the ambient passes first, no light iteration, no lights 
     743                        /*** msz: no more IRS_AMBIENT, see OgreSceneManager.h ***/ 
     744                        // mIlluminationStage = IRS_AMBIENT; 
     745 
     746                        SceneManager::renderObjects(pPriorityGrp->getSolidsBasic(), om, false, &lightList); 
     747                        // Also render any objects which have receive shadows disabled 
     748                        SceneManager::renderObjects(pPriorityGrp->getSolidsNoShadowReceive(), om, true); 
     749                } 
     750        } 
     751        else // render the rest of the passes 
     752        { 
     753                SceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup, om); 
     754        } 
     755} 
     756//----------------------------------------------------------------------- 
     757void KdTreeSceneManager::renderModulativeStencilShadowedQueueGroupObjects( 
     758        RenderQueueGroup* pGroup, QueuedRenderableCollection::OrganisationMode om) 
     759{ 
     760        if (mIsHierarchicalCulling) 
     761        { 
     762                // Iterate through priorities 
     763                RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); 
     764 
     765                while (groupIt.hasMoreElements()) 
     766                { 
     767                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext(); 
     768 
     769                        // Sort the queue first 
     770                        pPriorityGrp->sort(mCameraInProgress); 
     771 
     772                        // Do (shadowable) solids 
     773                        SceneManager::renderObjects(pPriorityGrp->getSolidsBasic(), om, true); 
     774                } 
     775        } 
     776        else 
     777        { 
     778                SceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup, om); 
     779        } 
     780} 
     781//----------------------------------------------------------------------- 
     782void KdTreeSceneManager::InitDepthPass() 
     783{ 
     784        MaterialPtr depthMat = MaterialManager::getSingleton().getByName("Visibility/DepthPass"); 
     785 
     786        if (depthMat.isNull()) 
     787        { 
     788                depthMat = MaterialManager::getSingleton().create( 
     789                        "Visibility/DepthPass", 
     790                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); 
     791 
     792                mDepthPass = depthMat->getTechnique(0)->getPass(0); 
     793                mDepthPass->setColourWriteEnabled(false); 
     794                mDepthPass->setDepthWriteEnabled(true); 
     795                mDepthPass->setLightingEnabled(false); 
     796        } 
     797        else 
     798        { 
     799                mDepthPass = depthMat->getTechnique(0)->getPass(0); 
     800        } 
     801} 
     802//----------------------------------------------------------------------- 
     803void KdTreeSceneManager::InitItemBufferPass() 
     804{ 
     805        MaterialPtr itemBufferMat = MaterialManager::getSingleton(). 
     806                getByName("Visibility/ItemBufferPass"); 
     807 
     808        if (itemBufferMat.isNull()) 
     809        { 
     810                // Init 
     811                itemBufferMat = MaterialManager::getSingleton().create("Visibility/ItemBufferPass", 
     812                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); 
     813 
     814                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0); 
     815                mItemBufferPass->setColourWriteEnabled(true); 
     816                mItemBufferPass->setDepthWriteEnabled(true); 
     817                mItemBufferPass->setLightingEnabled(true); 
     818                //mItemBufferPass->setLightingEnabled(false); 
     819        } 
     820        else 
     821        { 
     822                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0); 
     823        } 
     824        //mItemBufferPass->setAmbient(1, 1, 0); 
     825} 
     826//----------------------------------------------------------------------- 
     827void KdTreeSceneManager::PrepareVisualization(Camera *cam) 
     828{ 
     829        // add player camera for visualization purpose 
     830        try  
     831        { 
     832                Camera *c; 
     833                if ((c = getCamera("PlayerCam")) != NULL) 
     834                { 
     835                        getRenderQueue()->addRenderable(c); 
     836                }    
     837        } 
     838        catch (...) 
     839        { 
     840                // ignore 
     841        } 
     842        // add bounding boxes of rendered objects 
     843        if (0) 
     844                //for (BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) 
     845                //{ 
     846                //      getRenderQueue()->addRenderable(*it); 
     847                //} 
     848 
     849                if (mRenderNodesForViz || mRenderNodesContentForViz) 
     850                { 
     851                        // HACK: change node material so it is better suited for visualization 
     852                        MaterialPtr nodeMat = MaterialManager::getSingleton().getByName("Core/NodeMaterial"); 
     853                        nodeMat->setAmbient(1, 1, 0); 
     854                        nodeMat->setLightingEnabled(true); 
     855                        nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); 
     856 
     857                        //for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it) 
     858                        //{ 
     859                        //      if (mRenderNodesForViz) 
     860                        //      { 
     861                        //              // render the leaf nodes 
     862                        //              if ((*it)->numAttachedObjects() &&  
     863                        //                      !(*it)->numChildren() &&  
     864                        //                      ((*it)->getAttachedObject(0)->getMovableType() == "Entity") && 
     865                        //                      (*it)->getAttachedObject(0)->isVisible()) 
     866                        //              { 
     867                        //                      getRenderQueue()->addRenderable((*it)); 
     868                        //              } 
     869 
     870                        //              // addbounding boxes instead of node itself 
     871                        //              //(*it)->_addBoundingBoxToQueue(getRenderQueue()); 
     872                        //      } 
     873                        //      // add renderables itself 
     874                        //      if (mRenderNodesContentForViz)  
     875                        //      { 
     876                        //              (*it)->_addToRenderQueue(cam, getRenderQueue(), false); 
     877                        //      } 
     878                        //} 
     879                }        
     880} 
     881//----------------------------------------------------------------------- 
     882void KdTreeSceneManager::InitVisibilityCulling(Camera *cam) 
     883{ 
     884        // reset culling manager stats 
     885        mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes); 
     886 
     887        // set depth pass flag before rendering 
     888        mIsDepthPassPhase = mUseDepthPass; 
     889 
     890        mIsHierarchicalCulling = true; // during hierarchical culling 
     891 
     892        // item buffer needs full ambient lighting to use item colors as unique id 
     893        if (mUseItemBuffer)  
     894        { 
     895                mIsItemBufferPhase = true; 
     896                setAmbientLight(ColourValue(1,1,1,1)); 
     897        } 
     898 
     899 
     900        // set passes which are stored in render queue  
     901        // for rendering AFTER hierarchical culling, i.e., passes which need  
     902        // a special rendering order 
     903 
     904        mLeavePassesInQueue = 0; 
     905 
     906        // if we have the depth pass or use an item buffer, no passes are left in the queue 
     907        if (1 && !mUseDepthPass && !mUseItemBuffer) 
     908        { 
     909                if (mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE) 
     910                { 
     911                        // TODO: remove this pass because it should be processed during hierarchical culling 
     912                        //mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW; 
     913 
     914                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DECAL; 
     915                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DIFFUSE_SPECULAR; 
     916                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES; 
     917 
     918                        // just render ambient passes 
     919                        /*** msz: no more IRS_AMBIENT, see OgreSceneManager.h ***/ 
     920                        // mIlluminationStage = IRS_AMBIENT;  
     921                        //getRenderQueue()->setSplitPassesByLightingType(true); 
     922                } 
     923 
     924                if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE) 
     925                { 
     926                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW; 
     927                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES; 
     928                } 
     929 
     930                // transparents should be rendered after hierarchical culling to  
     931                // provide front-to-back ordering 
     932                if (mDelayRenderTransparents) 
     933                { 
     934                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES; 
     935                } 
     936        } 
     937 
     938        // skip rendering transparents during the hierarchical culling 
     939        // (because they will be rendered afterwards) 
     940        mSkipTransparents =  
     941                (mIsDepthPassPhase || (mLeavePassesInQueue & RenderPriorityGroup::TRANSPARENT_PASSES)); 
     942 
     943        // -- initialise interface for rendering traversal of the hierarchy 
     944        mHierarchyInterface->SetHierarchyRoot(mKdTree->getRoot()); 
     945 
     946        // possible two cameras (one for culling, one for rendering) 
     947        mHierarchyInterface->InitTraversal(mCameraInProgress,  
     948                /*mCullCamera ? getCamera("CullCamera") : */NULL, 
     949                mLeavePassesInQueue); 
     950 
     951} 
     952//----------------------------------------------------------------------- 
     953void KdTreeSceneManager::WriteLog() 
     954{ 
     955        std::stringstream d; 
     956 
     957        d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", " 
     958                << "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", " 
     959                << "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetTestGeometryForVisibleLeaves()) << ", " 
     960                << "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << ", " 
     961//              << "Hierarchy nodes: " << mNumOctants << ", "  
     962                << "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", " 
     963                << "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", " 
     964                << "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", " 
     965                << "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", " 
     966                << "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << ", " 
     967//              << "Found objects: " << (int)mVisible.size() << "\n" 
     968                ; 
     969 
     970        LogManager::getSingleton().logMessage(d.str()); 
     971} 
     972//----------------------------------------------------------------------- 
     973const Pass *KdTreeSceneManager::_setPass(Pass* pass) 
     974{ 
     975        if (mRenderMethod == KdTree::KDRM_INTERNAL) 
     976        { 
     977                return SceneManager::_setPass(pass); 
     978        } 
     979 
     980        // TODO: setting vertex program is not efficient 
     981        //Pass *usedPass = ((mIsDepthPassPhase && !pass->hasVertexProgram()) ? mDepthPass : pass);  
     982 
     983        // set depth fill pass if we currently do not make an aabb occlusion query 
     984        const bool useDepthPass =  
     985                (mIsDepthPassPhase && !mHierarchyInterface->IsBoundingBoxQuery()); 
     986 
     987        Pass *usedPass = useDepthPass ? mDepthPass : pass; 
     988 
     989 
     990        const IlluminationRenderStage savedStage = mIlluminationStage;  
     991 
     992        // set illumination stage to NONE so no shadow material is used  
     993        // for depth pass or for occlusion query 
     994        if (mIsDepthPassPhase || mHierarchyInterface->IsBoundingBoxQuery()) 
     995        { 
     996                mIlluminationStage = IRS_NONE; 
     997        } 
     998 
     999        // --- set vertex program of current pass in order to set correct depth 
     1000        if (mExecuteVertexProgramForAllPasses &&  
     1001                mIsDepthPassPhase &&  
     1002                pass->hasVertexProgram()) 
     1003        { 
     1004                // add vertex program of current pass to depth pass 
     1005                mDepthPass->setVertexProgram(pass->getVertexProgramName()); 
     1006 
     1007                if (mDepthPass->hasVertexProgram()) 
     1008                { 
     1009                        const GpuProgramPtr& prg = mDepthPass->getVertexProgram(); 
     1010                        // Load this program if not done already 
     1011                        if (!prg->isLoaded()) 
     1012                                prg->load(); 
     1013                        // Copy params 
     1014                        mDepthPass->setVertexProgramParameters(pass->getVertexProgramParameters()); 
     1015                } 
     1016        } 
     1017        else if (mDepthPass->hasVertexProgram()) // reset vertex program 
     1018        { 
     1019                mDepthPass->setVertexProgram(""); 
     1020        } 
     1021 
     1022        // save old depth write: needed for item buffer 
     1023        const bool IsDepthWrite = usedPass->getDepthWriteEnabled(); 
     1024 
     1025        // global option which enables / disables depth writes 
     1026        if (!mEnableDepthWrite) 
     1027        { 
     1028                usedPass->setDepthWriteEnabled(false); 
     1029        } 
     1030        //else if (mIsItemBufferPass) {usedPass = mItemBufferPass;} 
     1031 
     1032 
     1033        //-- set actual pass here 
     1034        const Pass *result = SceneManager::_setPass(usedPass); 
     1035 
     1036 
     1037        // reset depth write 
     1038        if (!mEnableDepthWrite) 
     1039        { 
     1040                usedPass->setDepthWriteEnabled(IsDepthWrite); 
     1041        } 
     1042 
     1043        // reset illumination stage 
     1044        mIlluminationStage = savedStage; 
     1045 
     1046        return result; 
     1047} 
     1048 
     1049//----------------------------------------------------------------------- 
     1050//----------------------------------------------------------------------- 
     1051const String KdTreeSceneManagerFactory::FACTORY_TYPE_NAME = "KdTreeSceneManager"; 
     1052//----------------------------------------------------------------------- 
     1053void KdTreeSceneManagerFactory::initMetaData(void) const 
     1054{ 
     1055        mMetaData.typeName = FACTORY_TYPE_NAME; 
     1056        mMetaData.description = "Scene manager that organises the scene based on a kd-tree"; 
     1057        mMetaData.sceneTypeMask = 0xFFFF; // support all types of scenes (hopefully) 
     1058        mMetaData.worldGeometrySupported = false; 
     1059} 
     1060//----------------------------------------------------------------------- 
     1061SceneManager* KdTreeSceneManagerFactory::createInstance( 
     1062        const String& instanceName) 
     1063{ 
     1064        return new KdTreeSceneManager(instanceName, visManager); 
     1065} 
     1066//----------------------------------------------------------------------- 
     1067void KdTreeSceneManagerFactory::destroyInstance(SceneManager* instance) 
     1068{ 
     1069        delete instance; 
     1070} 
    4911071 
    4921072} // namespace Ogre 
  • GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp

    r1173 r1182  
    3333                { 
    3434                        static_cast<KdTreeSceneManager *>(mCreator)->_updateNode(this); 
    35                 } 
    36         } 
    37  
    38         void KdTreeSceneNode::forceComputeAABB(AxisAlignedBox& aabb) // OBSOLETE !! 
    39         { 
    40  
    41                 // Update bounds from own attached objects 
    42                 ObjectMap::iterator i; 
    43                 for (i = mObjectsByName.begin(); i != mObjectsByName.end(); ++i) 
    44                 { 
    45                         // Merge world bounds of each object 
    46                         aabb.merge(i->second->getWorldBoundingBox(true)); 
    47                 } 
    48                 // Merge with children 
    49                 ChildNodeMap::iterator child; 
    50                 for (child = mChildren.begin(); child != mChildren.end(); ++child) 
    51                 { 
    52                         KdTreeSceneNode* sceneChild = static_cast<KdTreeSceneNode*>(child->second); 
    53                         sceneChild->forceComputeAABB(aabb); 
    5435                } 
    5536        } 
Note: See TracChangeset for help on using the changeset viewer.