Changeset 1182 for GTP/trunk/Lib/Vis
- Timestamp:
- 08/03/06 17:25:01 (18 years ago)
- Location:
- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h
r1177 r1182 276 276 /** Returns real extent of the kdtree, i.e., the merged extent of the bounding boxes. 277 277 */ 278 AxisAlignedBox _getWorldAABB(void) const { return m WorldAABB; };278 AxisAlignedBox _getWorldAABB(void) const { return mAABB; }; 279 279 /** Updates bound of the real aabb of kdtree 280 280 */ … … 424 424 friend class KdTreeHierarchyInterface; 425 425 426 typedef KdTree::Node * NodePtr; 427 typedef KdTree::Branch * BranchPtr; 426 428 typedef KdTree::Leaf * LeafPtr; 427 429 typedef std::set<LeafPtr> LeafSet; 430 431 typedef struct Stats_ 432 { 433 unsigned int mNumNodes; 434 unsigned int mNumLeaves; 435 unsigned int mNumSceneNodes; 436 437 void clear(void) 438 { 439 mNumNodes = 0; 440 mNumLeaves = 0; 441 mNumSceneNodes = 0; 442 }; 443 } Stats; 428 444 429 445 enum RenderMethod … … 446 462 447 463 // DEBUG 448 void dump(); 449 void calcCost(); 464 void dump(void); 465 Real calcCost(void); 466 467 NodePtr getRoot(void) const { return mKdRoot; }; 450 468 451 469 // insert a new scene node into an existing kd-tree … … 461 479 462 480 // self-explanatory ... 463 int getMaxDepth() { return mMaxDepth; }; 464 AxisAlignedBox getBox() { if (mKdRoot) return mKdRoot->mAABB; else return AxisAlignedBox(); }; 481 int getMaxDepth(void) { return mMaxDepth; }; 482 Stats getStats(void) const { return mStats; }; 483 AxisAlignedBox getBox(void) { if (mKdRoot) return mKdRoot->mAABB; else return AxisAlignedBox(); }; 465 484 void setBuildMethod(BuildMethod bm) { mBuildMethod = bm; } 466 485 protected: … … 501 520 Log * mBuildLog; 502 521 522 // statistical information 523 Stats mStats; 524 503 525 // DEBUG 504 526 void KdTree::dump(KdTree::Node * node); -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h
r1177 r1182 32 32 virtual const String& getTypeName(void) const; 33 33 34 35 /************************************************************************/ 36 /* Functions overridden form SceneManager for KdTree */ 37 /************************************************************************/ 38 34 39 /** Override from SceneManager to create SceneNodes as instance of KdTreeSceneNode 35 40 */ … … 39 44 virtual SceneNode* createSceneNode(const String& name); 40 45 46 /** Override from Scenemanager, employ kd-tree based culling or CHC 47 */ 48 virtual void _findVisibleObjects(Camera *cam, bool onlyShadowCasters); 49 50 virtual bool setOption(const String& strKey, const void* pValue); 51 virtual bool getOption(const String& strKey, void* pDestValue); 52 53 bool getOptionValues(const String & key, StringVector &refValueList); 54 bool getOptionKeys(StringVector &refKeys); 55 56 /** Overide from scene manager to destroy kdtree properly (before the scene graph is destroyed) 57 */ 58 virtual void clearScene() 59 { 60 // DEBUG 61 //if (mKdTree) 62 // mKdTree->dump(); 63 64 // must happen before actual scene is cleared 65 OGRE_DELETE(mKdTree); 66 67 SceneManager::clearScene(); 68 } 69 70 /************************************************************************/ 71 /* Functions overridden from SceneManager for CHC */ 72 /************************************************************************/ 73 41 74 /** Override from SceneManager so that sub entities can be assigned an id for item buffer. 42 75 */ 43 76 Entity* createEntity(const String& entityName, const String& meshName); 44 77 78 /** Override from scene manager to set up culling manager 79 */ 80 virtual void _updateSceneGraph(Camera* cam); 81 82 /** Override from SceneManager, employ normal rendering or CHC 83 */ 84 virtual void _renderVisibleObjects(); 85 86 /** Override pass so we can do the z-fail pass. 87 */ 88 const Pass* _setPass(Pass* pass); 89 90 /** Render a queue group. 91 Override so we can handle delayed rendering of transparent objects 92 */ 93 void renderBasicQueueGroupObjects(RenderQueueGroup* pGroup, 94 QueuedRenderableCollection::OrganisationMode om); 95 96 /** Override from scene manager 97 */ 98 void _renderQueueGroupObjects(RenderQueueGroup* pGroup, 99 QueuedRenderableCollection::OrganisationMode om); 100 101 /** Override from SceneManager so we can skip all but first pass for depth pass. 102 */ 103 bool validatePassForRendering(Pass* pass); 104 105 /** Override from SceneManager because idontknow 106 */ 107 void renderAdditiveStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup, 108 QueuedRenderableCollection::OrganisationMode om); 109 void renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup, 110 QueuedRenderableCollection::OrganisationMode om); 111 112 113 /************************************************************************/ 114 /* Functions which are specific to the KdTree */ 115 /************************************************************************/ 116 45 117 /** Update the KdTree with the node (more or less disabled now) 46 118 */ 47 119 virtual void _updateNode(KdTreeSceneNode *node); // TODO: 48 120 49 /** Override from scene manager to st up culling manager 50 */ 51 virtual void _updateSceneGraph(Camera* cam); 52 /** Override from Scenemanager, employ kd-tree based culling 53 or CHC 54 */ 55 virtual void _findVisibleObjects(Camera *cam, bool onlyShadowCasters); 56 //virtual void _renderVisibleObjects(); 121 /** Show or hide the bounding boxes of KdTree nodes - obsolete, use options 122 */ 123 virtual void setShowBoxes(bool showboxes); 124 /** Tell if show boxes is enabled - obsolete, use options 125 */ 126 virtual bool getShowBoxes(void) const; 127 128 /************************************************************************/ 129 /* Functions for CHC */ 130 /************************************************************************/ 57 131 58 132 /** Render a list of scenenodes … … 61 135 bool onlyShadowCasters, int leavePassesInQueue); 62 136 63 virtual void setShowBoxes(bool showboxes);64 virtual bool getShowBoxes(void) const;65 66 virtual bool setOption(const String& strKey, const void* pValue);67 virtual bool getOption(const String& strKey, void* pDestValue);68 69 bool getOptionValues(const String & key, StringVector &refValueList);70 bool getOptionKeys(StringVector &refKeys);71 72 137 /** Sets the visibility manager. 73 138 @param visManager the visibility manager … … 86 151 KdTreeHierarchyInterface *GetHierarchyInterface(); 87 152 88 89 ///** Render a queue group. 90 //Override so we can handle delayed rendering of transparent objects 91 //*/ 92 //void renderBasicQueueGroupObjects(RenderQueueGroup* pGroup, 93 // QueuedRenderableCollection::OrganisationMode om); 94 95 ///** Writes out stats into the Ogre log file. 96 //*/ 97 //void WriteLog(); 98 99 ///** Override pass so we can do the z-fail pass. 100 //*/ 101 //const Pass* _setPass(Pass* pass); 102 103 ///** Override from SceneManager so we can skip all but first pass for depth pass. 104 //*/ 105 //bool validatePassForRendering(Pass* pass); 106 107 virtual void clearScene() 108 { 109 // DEBUG must happen before scene is cleared 110 // might be a solution to detach problem 111 //if (mKdTree) 112 // mKdTree->dump(); 113 114 OGRE_DELETE(mKdTree); 115 116 SceneManager::clearScene(); 117 } 153 /** Creates material for depth pass, e.g., a pass that only fills the depth buffer. 154 */ 155 void InitDepthPass(); 156 /** Creates material for item buffer. 157 */ 158 void InitItemBufferPass(); 159 /** Fills render queue so that a visualization can be rendered. 160 */ 161 void PrepareVisualization(Camera *cam); 162 /** Initialises necessary parameters for hierarchical visibility culling. 163 */ 164 void InitVisibilityCulling(Camera *cam); 165 166 /** Writes out stats into the Ogre log file. 167 */ 168 void WriteLog(); 169 170 118 171 119 172 protected: 173 /************************************************************************/ 174 /* CHC-specific options & members */ 175 /************************************************************************/ 176 // pointer to the visibility manager 120 177 GtpVisibility::VisibilityManager *mVisibilityManager; 121 178 179 // the hierarchy interface for CHC 122 180 KdTreeHierarchyInterface *mHierarchyInterface; 123 181 124 /// consecutive number for sub-entities 182 // if hierarchical culling is currently in use 183 bool mIsHierarchicalCulling; 184 185 // if a visualization of the hierarchical culling is shown 186 bool mShowVisualization; 187 188 // if the culled nodes are indicated in the visualization 189 bool mVisualizeCulledNodes; 190 191 // consecutive number for sub-entities 125 192 int mCurrentEntityId; 126 193 127 // /flag for passes which should not be deleted from queue during first traversal194 // flag for passes which should not be deleted from queue during first traversal 128 195 int mLeavePassesInQueue; 196 197 // if symbols for the nodes are shown in the visualization 198 bool mRenderNodesForViz; 199 // if content of the nodes is shown in the visualization 200 bool mRenderNodesContentForViz; 201 /// render transparents after the hierarchical traversal 202 bool mDelayRenderTransparents; 129 203 204 // if transparent object are considered for item buffer visibility 205 bool mRenderTransparentsForItemBuffer; 206 // Always execute the vertex program of a pass, e.g., for the depth pass or item buffer 207 bool mExecuteVertexProgramForAllPasses; 208 209 // the depth pass (no lighting, just filling the depth buffer) 210 Pass *mDepthPass; 211 // use a depth pass (i.e., fill only the depth buffer in the first pass) 212 bool mUseDepthPass; 213 // flag indicating if we currently render the depth pass 214 bool mIsDepthPassPhase; 215 // if depth write should be enabled 216 bool mEnableDepthWrite; 217 // if transparents are skipped during rendering 218 bool mSkipTransparents; 219 220 // the item buffer pass (render items color-coded) 221 Pass *mItemBufferPass; 222 // if we use an item buffer for rendering (i.e., object ids as color codes 223 bool mUseItemBuffer; 224 // if we currently render the item buffer 225 bool mIsItemBufferPhase; 226 227 /************************************************************************/ 228 /* Kd-Tree specific options & members */ 229 /************************************************************************/ 230 // maximum depth of the kdtree 130 231 int mMaxDepth; 131 232 233 // the kdtree which holds the scene 132 234 KdTree *mKdTree; 133 235 236 // if bounding boxes of kdtree nodes are shown 134 237 bool mShowBoxes; 135 238 239 // the method/algorithm used when rendering the scene 136 240 KdTree::RenderMethod mRenderMethod; 137 241 242 // the method of building the tree 138 243 KdTree::BuildMethod mBuildMethod; 139 244 #ifdef KDTREE_DEBUG 245 // bounding boxes of kd nodes will be highlighted on this level of the kd tree 140 246 int mHighlighLevel; 247 // if all bounding boxes shall be displayed, not only the highlighted level 141 248 bool mShowAllBoxes; 142 249 #endif -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp
r1177 r1182 332 332 { 333 333 #ifdef KDTREE_DEBUG 334 try 334 MaterialPtr mp = MaterialManager::getSingleton().getByName("aabbHiLite"); 335 if (mp.isNull()) 335 336 { 336 337 ColourValue cv(0.0, 1.0, 0.0); … … 339 340 mp->setDiffuse(cv); 340 341 } 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 //} 345 353 #endif 346 354 try … … 645 653 unsigned long t1, t2, t3, t4; 646 654 //AxisAlignedBox aabb; 655 656 mStats.clear(); 647 657 648 658 // data we want to collect … … 657 667 t3 = timer->getMicroseconds(); // DEBUG 658 668 669 mStats.mNumSceneNodes = nObjects; 659 670 // <DEBUG> 660 671 //lm->logMessage("# of perfect splits " + StringConverter::toString(events.size())); … … 685 696 t4 = timer->getMicroseconds(); // DEBUG 686 697 698 String method = "Invalid"; 699 if (mBuildMethod == KDBM_RECURSIVE) 700 method = "Recursive"; 701 else if (mBuildMethod == KDBM_PRIORITYQUEUE) 702 method = "Priority Queue"; 703 687 704 mBuildLog->logMessage("######## SAH Statistics ########"); 705 mBuildLog->logMessage("Build Method: " + method); 688 706 mBuildLog->logMessage("Time for events build: " + StringConverter::toString(t2 - t1) + "µs"); 689 707 mBuildLog->logMessage("Time for events sort: " + StringConverter::toString(t3 - t2) + "µs"); 690 708 mBuildLog->logMessage("Time for tree build: " + StringConverter::toString(t4 - t3) + "µs"); 691 709 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("################################"); 694 715 } 695 716 … … 847 868 it++; 848 869 } 870 // update stats 871 ++ mStats.mNumNodes; 872 ++ mStats.mNumLeaves; 849 873 return leaf; 850 874 } … … 930 954 branch->mRight = recBuild(eventsRight, nBothS + nRightS, best.bright, branch); 931 955 } 956 957 // update stats 958 ++ mStats.mNumNodes; 932 959 933 960 //assert(branch->mRight || branch->mLeft); … … 1008 1035 if (!topNode) 1009 1036 topNode = leaf; 1037 // update stats 1038 ++ mStats.mNumNodes; 1039 ++ mStats.mNumLeaves; 1010 1040 } 1011 1041 … … 1172 1202 #endif 1173 1203 } 1204 // cleanup 1205 else 1206 { 1207 delete eventsLeft; 1208 } 1174 1209 if (eventsRight->size() > 0) 1175 1210 { … … 1193 1228 #endif 1194 1229 } 1230 // cleanup 1231 else 1232 { 1233 delete eventsRight; 1234 } 1195 1235 1196 1236 newNode = branch; 1197 1237 if (!topNode) 1198 1238 topNode = branch; 1239 1240 1241 // update stats 1242 ++ mStats.mNumNodes; 1199 1243 } 1200 1244 … … 1385 1429 } 1386 1430 1387 void KdTree::calcCost() 1388 { 1389 Real cost = 0; 1431 Real KdTree::calcCost() 1432 { 1390 1433 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; 1395 1437 } 1396 1438 -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp
r1177 r1182 10 10 #include <OgreCamera.h> 11 11 #include <OgreSubEntity.h> 12 #include <OgreMaterialManager.h> 12 13 #include "OgreKdTreeSceneManager.h" 13 14 #include "OgreKdTreeSceneNode.h" … … 21 22 namespace Ogre 22 23 { 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 25 KdTreeSceneManager::KdTreeSceneManager(const String& name, GtpVisibility::VisibilityManager *vm): 26 SceneManager(name), 27 mVisibilityManager(vm), 28 mKdTree(0), 29 mMaxDepth(KDTREE_MAX_DEPTH), 30 mShowBoxes(false), 29 31 #ifdef KDTREE_DEBUG 30 31 32 mHighlighLevel(0), 33 mShowAllBoxes(false), 32 34 #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 } 35 mBuildMethod(KdTree::KDBM_PRIORITYQUEUE), 36 mRenderMethod(KdTree::KDRM_INTERNAL), 37 mShowVisualization(false), 38 mRenderNodesForViz(false), 39 mRenderNodesContentForViz(false), 40 mVisualizeCulledNodes(false), 41 mLeavePassesInQueue(0), 42 mDelayRenderTransparents(true), 43 mUseDepthPass(false), 44 mIsDepthPassPhase(false), 45 mUseItemBuffer(false), 46 mIsItemBufferPhase(false), 47 mCurrentEntityId(1), 48 mEnableDepthWrite(true), 49 mSkipTransparents(false), 50 mRenderTransparentsForItemBuffer(true), 51 mExecuteVertexProgramForAllPasses(false), 52 mIsHierarchicalCulling(false) 53 { 54 // Replace root node with my node 55 OGRE_DELETE(mSceneRoot); 56 57 mSceneRoot = new KdTreeSceneNode(this, "root node"); 58 mSceneRoot->_notifyRootNode(); 59 60 mHierarchyInterface = new KdTreeHierarchyInterface(this, mDestRenderSystem); 61 } 62 63 KdTreeSceneManager::~KdTreeSceneManager(void) 64 { 65 delete mHierarchyInterface; 66 delete mKdTree; 67 } 68 69 const String& KdTreeSceneManager::getTypeName(void) const 70 { 71 return KdTreeSceneManagerFactory::FACTORY_TYPE_NAME; 72 } 73 74 void KdTreeSceneManager::setShowBoxes(bool showboxes) 75 { 76 mShowBoxes = showboxes; 77 } 78 79 bool KdTreeSceneManager::getShowBoxes(void) const 80 { 81 return mShowBoxes; 82 } 83 84 bool 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 80 231 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 247 bool 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 } 83 264 #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 } 86 275 #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 324 bool 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"); 125 334 #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"); 145 337 #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 342 bool KdTreeSceneManager::getOptionValues(const String & key, StringVector &refValueList) 343 { 344 return SceneManager::getOptionValues(key, refValueList); 345 } 346 347 void KdTreeSceneManager::setVisibilityManager(GtpVisibility::VisibilityManager *visManager) 348 { 349 mVisibilityManager = visManager; 350 } 351 352 GtpVisibility::VisibilityManager * KdTreeSceneManager::getVisibilityManager() 353 { 354 return mVisibilityManager; 355 } 356 357 GtpVisibility::VisibilityManager * KdTreeSceneManager::GetVisibilityManager() 358 { 359 return mVisibilityManager; 360 } 361 362 KdTreeHierarchyInterface * KdTreeSceneManager::GetHierarchyInterface() 363 { 364 return mHierarchyInterface; 365 } 366 367 SceneNode* 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 375 SceneNode* 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 391 Entity * 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; 258 402 #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 407 void 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 449 void KdTreeSceneManager::_updateSceneGraph(Camera* cam) 450 { 451 mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface); 452 mHierarchyInterface->SetRenderSystem(mDestRenderSystem); 453 454 SceneManager::_updateSceneGraph(cam); 455 } 456 457 void KdTreeSceneManager::_findVisibleObjects(Camera *cam, bool onlyShadowCasters) 458 { 459 if (mRenderMethod == KdTree::KDRM_INTERNAL) 441 460 { 442 461 getRenderQueue()->clear(); 443 462 if (mKdTree) 444 463 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 497 void 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 452 555 #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 629 void 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 454 634 #else 455 635 getRenderQueue()->clear(); 456 636 #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 //----------------------------------------------------------------------- 649 void 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 //----------------------------------------------------------------------- 680 bool 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 //----------------------------------------------------------------------- 701 void 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 //----------------------------------------------------------------------- 723 void 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 //----------------------------------------------------------------------- 757 void 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 //----------------------------------------------------------------------- 782 void 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 //----------------------------------------------------------------------- 803 void 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 //----------------------------------------------------------------------- 827 void 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 //----------------------------------------------------------------------- 882 void 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 //----------------------------------------------------------------------- 953 void 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 //----------------------------------------------------------------------- 973 const 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 //----------------------------------------------------------------------- 1051 const String KdTreeSceneManagerFactory::FACTORY_TYPE_NAME = "KdTreeSceneManager"; 1052 //----------------------------------------------------------------------- 1053 void 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 //----------------------------------------------------------------------- 1061 SceneManager* KdTreeSceneManagerFactory::createInstance( 1062 const String& instanceName) 1063 { 1064 return new KdTreeSceneManager(instanceName, visManager); 1065 } 1066 //----------------------------------------------------------------------- 1067 void KdTreeSceneManagerFactory::destroyInstance(SceneManager* instance) 1068 { 1069 delete instance; 1070 } 491 1071 492 1072 } // namespace Ogre -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp
r1173 r1182 33 33 { 34 34 static_cast<KdTreeSceneManager *>(mCreator)->_updateNode(this); 35 }36 }37 38 void KdTreeSceneNode::forceComputeAABB(AxisAlignedBox& aabb) // OBSOLETE !!39 {40 41 // Update bounds from own attached objects42 ObjectMap::iterator i;43 for (i = mObjectsByName.begin(); i != mObjectsByName.end(); ++i)44 {45 // Merge world bounds of each object46 aabb.merge(i->second->getWorldBoundingBox(true));47 }48 // Merge with children49 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);54 35 } 55 36 }
Note: See TracChangeset
for help on using the changeset viewer.