Changeset 1187 for GTP/trunk/Lib/Vis
- Timestamp:
- 08/08/06 18:25:06 (18 years ago)
- Location:
- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h
r1183 r1187 207 207 virtual bool isEmpty() const = 0; 208 208 virtual bool hasGeometry() const = 0; 209 210 virtual void queueVisibleObjects(unsigned long currentFrame, 211 Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes) = 0; 209 212 210 213 // consider using typesafe callback functions … … 288 291 int mLevel; 289 292 AxisAlignedBox mAABB; 290 protected:291 WireBoundingBox * mWBB;292 293 293 294 // for the CHC hierarchy interface 294 295 /** the real extent of the node. */ 295 296 AxisAlignedBox mWorldAABB; 297 protected: 298 WireBoundingBox * mWBB; 296 299 297 300 unsigned int mLastRendered; … … 327 330 virtual bool hasGeometry() const { return false; }; 328 331 332 virtual void queueVisibleObjects(unsigned long currentFrame, 333 Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes) 334 { 335 if (showBoxes) 336 { 337 WireBoundingBox * wbb = getWireBoundingBox(); 338 if (wbb) 339 queue->addRenderable(wbb); 340 } 341 } 342 329 343 // branches do not posses geometry => just merge child aabbs 330 344 virtual void _updateBounds(bool recurse = true) … … 334 348 335 349 if (mLeft) 336 mWorldAABB.merge(mLeft-> _getWorldAABB());350 mWorldAABB.merge(mLeft->mWorldAABB); 337 351 if (mRight) 338 mWorldAABB.merge(mRight-> _getWorldAABB());352 mWorldAABB.merge(mRight->mWorldAABB); 339 353 340 354 // update parent recursively … … 367 381 virtual bool hasGeometry() const { return !mKdRenderables.empty(); }; 368 382 383 virtual void queueVisibleObjects(unsigned long currentFrame, 384 Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes); 385 369 386 // update the world aabb based on the contained geometry 370 387 virtual void _updateBounds(bool recurse = true); … … 430 447 typedef KdTree::Branch * BranchPtr; 431 448 typedef KdTree::Leaf * LeafPtr; 449 450 typedef std::list<NodePtr> NodeList; 432 451 typedef std::set<LeafPtr> LeafSet; 433 452 … … 484 503 485 504 // test visibility of objects and add to render queue 486 void queueVisibleObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters, 487 RenderMethod renderMethod, bool showBoxes = false); 505 void queueVisibleObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes = false); 488 506 489 507 // self-explanatory ... -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h
r1185 r1187 16 16 #include "OgreKdTree.h" 17 17 18 #define KDTREE_MAX_DEPTH 2018 #define KDTREE_MAX_DEPTH 12 19 19 20 20 namespace Ogre … … 134 134 /** Render a list of scenenodes 135 135 */ 136 virtual void _renderNodes(const KdRenderableList& nodelist, Camera * cam, 136 //virtual void _renderNodes(const KdRenderableList& nodelist, Camera * cam, 137 // bool onlyShadowCasters, int leavePassesInQueue); 138 virtual void _renderNode(KdTree::NodePtr node, Camera * cam, 137 139 bool onlyShadowCasters, int leavePassesInQueue); 138 140 … … 227 229 228 230 // remember visited scene nodes for viz 229 KdRenderableList mVisibleNodes; 231 //KdRenderableList mVisibleNodes; 232 KdTree::NodeList mVisibleNodes; 230 233 231 234 /************************************************************************/ -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneNode.h
r1173 r1187 43 43 virtual AxisAlignedBox getBoundingBox() const; 44 44 45 // custom render op, show bounding box instead of axes 46 //virtual void getRenderOperation(RenderOperation& op); 47 45 48 //virtual void _findVisibleObjects(Camera* cam, RenderQueue* queue, 46 49 // bool includeChildren = true, bool displayNodes = false, bool onlyShadowCasters = false); -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp
r1183 r1187 22 22 23 23 #define KDTREE_LOGNAME "KdTreeBuild.log" 24 #define PLT_SIZE 101 24 25 25 26 namespace Ogre … … 28 29 Real PlaneEvent::KI = 1.0; 29 30 31 //---------------------------------------------------------------------------- 32 // determine if this event is left or right of the reference event 30 33 void PlaneEvent::classify(const PlaneEvent& e, PlaneEvent::Side side) 31 34 { … … 57 60 } 58 61 62 //---------------------------------------------------------------------------- 63 // clip this event to an aabb (move it so that the plane on one of the box planes) 59 64 PlaneEvent PlaneEvent::clip(AxisAlignedBox& box, PlaneEvent::Dimension dim) 60 65 { … … 68 73 } 69 74 75 //---------------------------------------------------------------------------- 76 // the surface area heuristic to determine the cost of splitting the parent aabb 77 // along the plane represented by this event 70 78 void PlaneEvent::SAH(const AxisAlignedBox& parent, int nLeft, int nPlane, int nRight, SplitInfo& split) 71 79 { 72 73 #ifdef KDTREE_DEBUG_OFF74 80 Real mu = splitBox(parent, split.bleft, split.bright); 75 Real sav = surfaceArea(parent); // optimize?? called several times for the same box 76 Real savl = surfaceArea(split.bleft); 77 Real savr = surfaceArea(split.bright); 78 Real pl = savl / sav; 79 Real pr = savr / sav; 80 Real costl = splitCost(pl, pr, nLeft + nPlane, nRight, mu); 81 Real costr = splitCost(pl, pr, nLeft, nPlane + nRight, mu); 82 83 Log * log = LogManager::getSingleton().getLog(KDTREE_LOGNAME); 84 log->logMessage("SAH: SA-parent=" + StringConverter::toString(sav) + 85 "\n\tSA-left=" + StringConverter::toString(savl) + 86 " SA-right=" + StringConverter::toString(savr) + 87 "\n\tp-left=" + StringConverter::toString(pl) + 88 " p-right=" + StringConverter::toString(pr) + 89 "\n\tmu=" + StringConverter::toString(mu) + 90 "\n\tcost-left=" + StringConverter::toString(costl) + 91 " cost-right=" + StringConverter::toString(costr)); 92 #else 93 Real mu = splitBox(parent, split.bleft, split.bright); 94 Real sav = surfaceArea(parent); // optimize?? called several times for the same box 81 Real sav = surfaceArea(parent); 95 82 Real pl = surfaceArea(split.bleft) / sav; 96 83 Real pr = surfaceArea(split.bright) / sav; … … 98 85 Real costr = splitCost(pl, pr, nLeft, nPlane + nRight, mu); 99 86 100 #endif101 87 if (costl < costr) 102 88 { … … 117 103 } 118 104 105 //---------------------------------------------------------------------------- 106 // split the parent aabb with the plane in this event 119 107 Real PlaneEvent::splitBox(const AxisAlignedBox& parent, AxisAlignedBox& left, AxisAlignedBox& right) 120 108 { 121 109 Vector3 bmin = parent.getMinimum(); 122 110 Vector3 bmax = parent.getMaximum(); 123 #ifdef KDTREE_DEBUG_OFF124 if(bmin[mDimension] > mPosition[mDimension] || bmax[mDimension] < mPosition[mDimension])125 {126 Log * log = LogManager::getSingleton().getLog(KDTREE_LOGNAME);127 log->logMessage("SPLITBOX SNAFU in event " + print() +128 "\n\tmin=" + StringConverter::toString(bmin[mDimension]) +129 " split=" + StringConverter::toString(mPosition[mDimension]) +130 " max=" + StringConverter::toString(bmax[mDimension]));131 }132 #endif133 111 // calculate the penalty for spliting the box that way 134 Real mu = lookupPenalty((mPosition[mDimension] - bmin[mDimension]) / (bmax[mDimension] - bmin[mDimension])); 112 Real mu = lookupPenalty( 113 (mPosition[mDimension] - bmin[mDimension]) / 114 (bmax[mDimension] - bmin[mDimension])); 135 115 // set corners which are the same as parent AABB 136 116 left.setMinimum(bmin); … … 146 126 } 147 127 128 //---------------------------------------------------------------------------- 129 // compute surface area of a box ... DUH! 130 Real PlaneEvent::surfaceArea(const AxisAlignedBox& box) 131 { 132 Vector3 sides = box.getMaximum() - box.getMinimum(); 133 return 2 * sides.x * sides.y + 134 2 * sides.y * sides.z + 135 2 * sides.z * sides.x; 136 } 137 138 //---------------------------------------------------------------------------- 139 // lookup the penalty for placing the splitting plane near to the edge of the AABB 140 // 0.0 <= p <= 1.0, p = 0.5 means the plane divides the aabb in half 141 Real PlaneEvent::lookupPenalty(Real p) 142 { 143 // precomputed table of {x^6 + 1|0 <= x <= 1} 144 static Real mPenaltyLookupTable[PLT_SIZE]; 145 static bool init_done = false; 146 147 if (!init_done) 148 { 149 Real step = 1.0 / (PLT_SIZE - 1); 150 Real x = 0.0; 151 //LogManager::getSingleton().logMessage("### Calculating Lookup Table ###"); 152 for (int i = 0; i < PLT_SIZE; i++) 153 { 154 mPenaltyLookupTable[i] = Math::Pow(x, 6) + 1.0; 155 x += step; 156 //LogManager::getSingleton().logMessage("### mPenaltyLookupTable[" + StringConverter::toString(i,3) + "]=" + StringConverter::toString(mPenaltyLookupTable[i])); 157 } 158 init_done = true; 159 //LogManager::getSingleton().logMessage("### Lookup Table Calculated ###"); 160 } 161 162 // normalize p to [0,1] 163 Real x = Math::Abs(p * 2 - 1); 164 // compute index 165 int i = Math::IFloor(x * (PLT_SIZE - 1)); 166 167 return mPenaltyLookupTable[i]; 168 } 169 170 //---------------------------------------------------------------------------- 171 // compute cost of the split, reward splitting of empty space (lambda, const), 172 // penalize splitting off 'thin' slices (mu, const) 148 173 Real PlaneEvent::splitCost(Real pLeft, Real pRight, int nLeft, int nRight) 149 174 { 150 //assert(pLeft <= 1.0 && pRight <= 1.0);151 152 175 // reward splitting off chunks of empty space 153 176 Real lambda = 1.0; … … 157 180 } 158 181 159 // penalize splitting off small chunks 182 // penalize splitting off small chunks (thin slices) 160 183 Real mu = 1.0; 161 184 if (pLeft < 0.1 || pRight < 0.1 || pLeft > 0.9 || pRight > 0.9) … … 164 187 } 165 188 return lambda * mu * (KT + (KI * (pLeft*nLeft + pRight*nRight))); 166 167 //return lambda * (KT + (KI * (pLeft*nLeft + pRight*nRight))); 168 } 169 189 } 190 191 //---------------------------------------------------------------------------- 192 // compute cost of the split, reward splitting of empty space (lambda, const), 193 // penalize splitting off 'thin' slices (mu, parameter) 170 194 Real PlaneEvent::splitCost(Real pLeft, Real pRight, int nLeft, int nRight, Real mu) 171 195 { 172 //assert(pLeft <= 1.0 && pRight <= 1.0);173 174 196 // reward splitting off chunks of empty space 175 197 Real lambda = 1.0; … … 182 204 } 183 205 184 Real PlaneEvent::surfaceArea(const AxisAlignedBox& box) 185 { 186 Vector3 sides = box.getMaximum() - box.getMinimum(); 187 #ifdef KDTREE_DEBUG_OFF 188 if(sides.x < 0 || sides.y < 0 || sides.z < 0) 189 { 190 Log * log = LogManager::getSingleton().getLog(KDTREE_LOGNAME); 191 log->logMessage("AABB SNAFU: x=" + StringConverter::toString(sides.x) + 192 " y=" + StringConverter::toString(sides.y) + " z=" + StringConverter::toString(sides.z) + 193 " BOX=" + StringConverter::toString(box.getMinimum()) + "," + StringConverter::toString(box.getMaximum())); 194 } 195 #endif 196 return 2 * sides.x * sides.y + 197 2 * sides.y * sides.z + 198 2 * sides.z * sides.x; 199 } 200 201 void PlaneEvent::pqSAH(Real globalSA, Real parentSA, int nLeft, int nPlane, int nRight, AxisAlignedBox& parentBox, SplitInfo& split) 206 //---------------------------------------------------------------------------- 207 // surface area heuristic modified for the priority queue method of building 208 // the probabilities (p, pl, pr) are relative to the global (all enclosing) aabb 209 void PlaneEvent::pqSAH(Real globalSA, Real parentSA, int nLeft, int nPlane, int nRight, 210 AxisAlignedBox& parentBox, SplitInfo& split) 202 211 { 203 212 Real mu = splitBox(parentBox, split.bleft, split.bright); … … 226 235 } 227 236 237 //---------------------------------------------------------------------------- 238 // compute split cost without any penalties 228 239 Real PlaneEvent::pqSplitCost(Real pParent, Real pLeft, Real pRight, int nLeft, int nRight, Real mu) 229 240 { 230 // reward splitting off chunks of empty space 231 //Real lambda = 1.0; 232 //if (nLeft == 0 || nRight == 0) 233 //{ 234 // lambda = 0.8; 235 //} 236 237 return /* lambda * mu * */ (pParent*KT + (KI * (pLeft*nLeft + pRight*nRight))); 238 } 239 240 #define PLT_SIZE 101 241 242 // lookup the penalty for placing the splitting plane near to the edge of the AABB 243 // 0.0 <= p <= 1.0, p = 0.5 means the plane divides the aabb in half 244 Real PlaneEvent::lookupPenalty(Real p) 245 { 246 // precomputed table of {x^6 + 1|0 <= x <= 1} 247 static Real mPenaltyLookupTable[PLT_SIZE]; 248 static bool init_done = false; 249 250 if (!init_done) 251 { 252 Real step = 1.0 / (PLT_SIZE - 1); 253 Real x = 0.0; 254 //LogManager::getSingleton().logMessage("### Calculating Lookup Table ###"); 255 for (int i = 0; i < PLT_SIZE; i++) 256 { 257 mPenaltyLookupTable[i] = Math::Pow(x, 6) + 1.0; 258 x += step; 259 //LogManager::getSingleton().logMessage("### mPenaltyLookupTable[" + StringConverter::toString(i,3) + "]=" + StringConverter::toString(mPenaltyLookupTable[i])); 260 } 261 init_done = true; 262 //LogManager::getSingleton().logMessage("### Lookup Table Calculated ###"); 263 } 264 265 // normalize p to [0,1] 266 Real x = Math::Abs(p * 2 - 1); 267 int i = Math::IFloor(x * (PLT_SIZE - 1)); 268 269 return mPenaltyLookupTable[i]; 270 } 271 241 return pParent * KT + (KI * (pLeft * nLeft + pRight * nRight)); 242 } 243 244 //---------------------------------------------------------------------------- 272 245 // DEBUG 273 246 String PlaneEvent::print() … … 290 263 }; 291 264 265 //---------------------------------------------------------------------------- 292 266 String SplitInfo::print() 293 267 { … … 308 282 }; 309 283 284 //---------------------------------------------------------------------------- 310 285 String KdTree::SplitCandidate::print() 311 286 { … … 361 336 } 362 337 338 /************************************************************************/ 339 /* KdTree insert/delete functions */ 340 /************************************************************************/ 341 363 342 void KdTree::remove(KdRenderable * rend) 364 343 { … … 640 619 } 641 620 621 /************************************************************************/ 622 /* KdTree build functions */ 623 /************************************************************************/ 624 642 625 void KdTree::build(KdRenderable * sceneRoot) 643 626 { 644 // DEBUG645 //LogManager *lm = LogManager::getSingletonPtr();646 627 Timer *timer = Root::getSingleton().getTimer(); 647 628 unsigned long t1, t2, t3, t4; 648 //AxisAlignedBox aabb;649 629 650 630 mStats.clear(); … … 662 642 663 643 mStats.mNumSceneNodes = nObjects; 664 // <DEBUG>665 //lm->logMessage("# of perfect splits " + StringConverter::toString(events.size()));666 //PlaneEventList::iterator it;667 //for (it = events.begin(); it != events.end(); it++)668 //{669 // lm->logMessage(it->print());670 //}671 // </DEBUG>672 644 673 645 assert(! aabb.isNull() && "Teh stubid worldAABB iz NULL ... waht now?"); … … 702 674 mBuildLog->logMessage("Time for tree build: " + StringConverter::toString(t4 - t3) + "µs"); 703 675 mBuildLog->logMessage("Total time: " + StringConverter::toString(t4 - t1) + "µs"); 676 mBuildLog->logMessage("Tree Depth: " + StringConverter::toString(mMaxDepth)); 704 677 mBuildLog->logMessage("Number of Objects: " + StringConverter::toString(mStats.mNumSceneNodes)); 705 678 mBuildLog->logMessage("Number of Leaves: " + StringConverter::toString(mStats.mNumLeaves)); … … 723 696 it++; 724 697 } 698 725 699 events.sort(); 700 726 701 // HACK 727 702 if (aabb.isNull()) 728 703 { 729 //LogManager::getSingleton().logMessage("AABB empty, using node AABB.");730 704 aabb = nodeaabb; 731 705 } 732 733 // this must never happen!!734 //AxisAlignedBox isect = aabb.intersection(nodeaabb);735 //if (isect.getMinimum() != nodeaabb.getMinimum() || isect.getMaximum() != nodeaabb.getMaximum())736 //{737 // LogManager::getSingleton().logMessage("#+#+#+#+#+ SceneNodes outside of node AABB.");738 //}739 706 740 707 if (mBuildMethod == KDBM_RECURSIVE) … … 760 727 } 761 728 762 #ifdef KDTREE_DEBUG_OFF763 mBuildLog->logMessage("events.size()=" + StringConverter::toString(events.size()));764 #endif765 #ifdef KDTREE_DEBUG_OFF766 PlaneEventList::iterator xit, xbegin, xend;767 xbegin = events.begin();768 xend = events.end();769 xit = xbegin;770 while (xit != xend)771 {772 mBuildLog->logMessage(xit->print());773 xit++;774 }775 #endif776 777 729 /************************************************/ 778 730 /**************** BEGIN FINDPLANE ***************/ 779 731 /************************************************/ 780 732 // find optimal split plane and split node accordingly 733 734 // initialize 781 735 const int dim = 3; 782 736 int pStart, pOn, pEnd; … … 789 743 SplitInfo split, best; 790 744 best.cost = Math::POS_INFINITY; 791 792 745 793 746 PlaneEventList::iterator begin = events.begin(); … … 821 774 } 822 775 823 #ifdef KDTREE_DEBUG_OFF824 Real lvol = best.bleft.volume();825 Real rvol = best.bright.volume();826 827 if (lvol == 0 || rvol == 0)828 {829 mBuildLog->logMessage("WARNING INVALID SPLIT!!!");830 String side;831 if (best.side == PlaneEvent::PES_LEFT)832 side = "left";833 else834 side = "right";835 836 mBuildLog->logMessage("Splitting node on level " + StringConverter::toString(level) +837 "\n\tcost=" + StringConverter::toString(best.cost) + " term=" + StringConverter::toString(PlaneEvent::KI*nObjects) +838 " side=" + side +839 "\n\tVolume: left=" + StringConverter::toString(lvol) +840 " right=" + StringConverter::toString(rvol));841 }842 #endif843 776 /************************************************/ 844 777 /**************** BEGIN TERMINATE ***************/ … … 858 791 { 859 792 leaf->insert(rend); 860 //LogManager::getSingleton().logMessage("++ Adding SceneNode: " + (static_cast<KdTreeSceneNode *>(rend))->getName());861 793 } 862 794 it++; … … 873 805 /**************** BEGIN CLASSIFY ****************/ 874 806 /************************************************/ 807 // split the event list in left and right sub-lists 875 808 else 876 809 { … … 896 829 while (it != end) 897 830 { 898 // right-only nodes g et moved831 // right-only nodes go in right list 899 832 if (it->getRenderable()->getSide() == PlaneEvent::PES_RIGHT) 900 833 { … … 904 837 nRightS++; 905 838 } 906 907 839 eventsRight.push_back(*it); 908 840 } 909 // both-only nodes get copied 910 // must clip AABBs to child AABB !!! 911 else if (it->getRenderable()->getSide() == PlaneEvent::PES_BOTH) 912 { 913 if (!it->getRenderable()->isClassified()) 914 { 915 it->getRenderable()->setClassified(true); 916 nBothS++; 917 } 918 919 //eventsRight.push_back(*it); 920 //eventsLeft.push_back(*it); 921 eventsRight.push_back(it->clip(best.bright, best.event.getDimension())); 922 eventsLeft.push_back(it->clip(best.bleft, best.event.getDimension())); 923 } 924 else 841 // left-only nodes go in left list 842 else if (it->getRenderable()->getSide() == PlaneEvent::PES_LEFT) 925 843 { 926 844 if (!it->getRenderable()->isClassified()) … … 931 849 eventsLeft.push_back(*it); 932 850 } 851 // remaining nodes go in both lists, bust must be clipped to prevent 852 // events from lying outside the new nodes aabb 853 else 854 { 855 if (!it->getRenderable()->isClassified()) 856 { 857 it->getRenderable()->setClassified(true); 858 nBothS++; 859 } 860 eventsRight.push_back(it->clip(best.bright, best.event.getDimension())); 861 eventsLeft.push_back(it->clip(best.bleft, best.event.getDimension())); 862 } 933 863 it++; 934 864 } 935 865 936 #ifdef KDTREE_DEBUG_OFF 937 mBuildLog->logMessage("Splitting on " + best.event.print()); 938 mBuildLog->logMessage("eventsLeft.size()=" + StringConverter::toString(eventsLeft.size())); 939 mBuildLog->logMessage("eventsRight.size()=" + StringConverter::toString(eventsRight.size())); 940 #endif 866 // create a new branch node and continue recursion 941 867 KdTree::Branch * branch = new KdTree::Branch(level, aabb, parent, best.event.getSplitPlane(), best.side); 942 868 … … 956 882 // update bounding box 957 883 branch->_updateBounds(false); 958 959 960 //assert(branch->mRight || branch->mLeft);961 884 962 885 return branch; … … 979 902 // inital split candidate 980 903 SplitInfo * best = pqFindPlane(e, nObjects, aabb, globalSA); 981 SplitCandidate splitcandidate(e, nObjects, aabb, parent, globalTreeCost, globalTreeCost - best->cost, best, PlaneEvent::PES_BOTH); 904 SplitCandidate splitcandidate(e, nObjects, aabb, parent, globalTreeCost, 905 globalTreeCost - best->cost, best, PlaneEvent::PES_BOTH); 982 906 pqueue.push(splitcandidate); 983 984 #ifdef KDTREE_DEBUG_OFF985 //mBuildLog->logMessage("best.pevent=" + best->event.print() +986 // " events.size()=" + StringConverter::toString(events.size()));987 mBuildLog->logMessage("New split on " + splitcandidate.print());988 #endif989 907 990 908 … … 1001 919 level = sc.parent->mLevel + 1; 1002 920 } 1003 1004 #ifdef KDTREE_DEBUG_OFF1005 //mBuildLog->logMessage("Splitting on " + sc.best->event.print() +1006 // " sc.events.size()=" + StringConverter::toString(sc.events->size()));1007 mBuildLog->logMessage("Splitting on " + sc.print());1008 #endif1009 921 1010 922 /************************************************/ … … 1012 924 /************************************************/ 1013 925 // check terminating condition 1014 //if (best.cost > PlaneEvent::KI*sc.nObjects || level >= mMaxDepth)1015 926 if (sc.decrease < 0.0 || level >= mMaxDepth) 1016 927 { … … 1028 939 { 1029 940 leaf->insert(rend); 1030 //LogManager::getSingleton().logMessage("++ Adding SceneNode: " + (static_cast<KdTreeSceneNode *>(rend))->getName());1031 941 } 1032 942 it++; … … 1053 963 while (it != end) 1054 964 { 1055 #ifdef KDTREE_DEBUG_OFF1056 mBuildLog->logMessage(it->print());1057 #endif1058 965 it->getRenderable()->setSide(PlaneEvent::PES_BOTH); 1059 966 it->getRenderable()->setClassified(false); 1060 967 it++; 1061 968 } 969 1062 970 // now classify all renderables. do they belong to the left child, the right child or both? 1063 #ifdef KDTREE_DEBUG_OFF1064 bool bla = true;1065 971 it = begin; 1066 972 while (it != end) 1067 973 { 1068 974 it->classify(sc.best->event, sc.best->side); 1069 if (*it == sc.best->event)1070 {1071 mBuildLog->logMessage("YEEPEE classified against valid event");1072 bla = false;1073 }1074 975 it++; 1075 976 } 1076 if (bla)1077 mBuildLog->logMessage("FUCKIT! Invalid classification");1078 #else1079 it = begin;1080 while (it != end)1081 {1082 it->classify(sc.best->event, sc.best->side);1083 it++;1084 }1085 #endif1086 1087 977 1088 978 // divide the event lists … … 1091 981 while (it != end) 1092 982 { 983 // right-only events go in the right list 1093 984 if (it->getRenderable()->getSide() == PlaneEvent::PES_RIGHT) 1094 985 { … … 1101 992 eventsRight->push_back(*it); 1102 993 } 1103 else if (it->getRenderable()->getSide() == PlaneEvent::PES_BOTH) 1104 { 1105 if (!it->getRenderable()->isClassified()) 1106 { 1107 it->getRenderable()->setClassified(true); 1108 nBothS++; 1109 } 1110 1111 eventsRight->push_back(it->clip(sc.best->bright, sc.best->event.getDimension())); 1112 eventsLeft->push_back(it->clip(sc.best->bleft, sc.best->event.getDimension())); 1113 } 1114 else 994 // left-only events go in the left list 995 else if (it->getRenderable()->getSide() == PlaneEvent::PES_LEFT) 1115 996 { 1116 997 if (!it->getRenderable()->isClassified()) … … 1121 1002 eventsLeft->push_back(*it); 1122 1003 } 1004 // the rest goes in both lists after being clipped 1005 else 1006 { 1007 if (!it->getRenderable()->isClassified()) 1008 { 1009 it->getRenderable()->setClassified(true); 1010 nBothS++; 1011 } 1012 1013 eventsRight->push_back(it->clip(sc.best->bright, sc.best->event.getDimension())); 1014 eventsLeft->push_back(it->clip(sc.best->bleft, sc.best->event.getDimension())); 1015 } 1123 1016 it++; 1124 1017 } 1125 1018 1126 #ifdef KDTREE_DEBUG_OFF 1127 mBuildLog->logMessage("#### Splitting node on level " + StringConverter::toString(level)); 1128 Plane * vplane; 1129 int count = 0; 1130 PlaneEventList::iterator vit, vbegin, vend; 1131 vbegin = eventsLeft->begin(); 1132 vend = eventsLeft->end(); 1133 vit = vbegin; 1134 while (vit != vend) 1135 { 1136 vplane = vit->getSplitPlane(); 1137 if (!sc.best.bleft.intersects(*vplane)) 1138 { 1139 mBuildLog->logMessage("Invalid event classification! Plane: " + 1140 StringConverter::toString(vplane->normal) + ", " + StringConverter::toString(-vplane->d) + 1141 " Box: |" + StringConverter::toString(sc.best.bleft.getMinimum()) + "|" + 1142 StringConverter::toString(sc.best.bleft.getMaximum()) + "|"); 1143 count++; 1144 } 1145 OGRE_DELETE(vplane); 1146 vit++; 1147 } 1148 mBuildLog->logMessage("@@@@ Number of invalid events on the left: " + 1149 StringConverter::toString(count) + 1150 " Number of events on both sides: " + StringConverter::toString(nBothS)); 1151 count = 0; 1152 vbegin = eventsRight->begin(); 1153 vend = eventsRight->end(); 1154 vit = vbegin; 1155 while (vit != vend) 1156 { 1157 vplane = vit->getSplitPlane(); 1158 if (!sc.best.bright.intersects(*vplane)) 1159 { 1160 mBuildLog->logMessage("Invalid event classification! Plane: " + 1161 StringConverter::toString(vplane->normal) + ", " + StringConverter::toString(-vplane->d) + 1162 " Box: |" + StringConverter::toString(sc.best.bright.getMinimum()) + "|" + 1163 StringConverter::toString(sc.best.bright.getMaximum()) + "|"); 1164 count++; 1165 } 1166 OGRE_DELETE(vplane); 1167 vit++; 1168 } 1169 mBuildLog->logMessage("@@@@ Number of invalid events on the right: " + 1170 StringConverter::toString(count) + 1171 " Number of events on both sides: " + StringConverter::toString(nBothS)); 1172 #endif 1173 1019 // create a new branch node 1174 1020 KdTree::Branch * branch = 1175 1021 new KdTree::Branch(level, sc.aabb, sc.parent, sc.best->event.getSplitPlane(), sc.best->side); 1176 1022 1177 //Real decr = (PlaneEvent::surfaceArea(sc.aabb)/globalSA*PlaneEvent::KI*sc.nObjects) - sc.best.cost;1178 1023 globalTreeCost -= sc.decrease; 1179 1024 1180 //mBuildLog->logMessage("Splitting, cost is now " + StringConverter::toString(globalTreeCost) + ""); 1181 1182 // now create the child nodes and continue recursion1025 1026 // now for each potential child node, compute the split plane and the cost decrease 1027 // and place them in the queue 1183 1028 if (eventsLeft->size() > 0) 1184 1029 { … … 1188 1033 branch, old, old - best->cost, best, PlaneEvent::PES_LEFT); 1189 1034 pqueue.push(scleft); 1190 1191 #ifdef KDTREE_DEBUG_OFF1192 //mBuildLog->logMessage("best.pevent: " + best->event.print() +1193 // " eventsLeft.size()=" + StringConverter::toString(eventsLeft->size()));1194 mBuildLog->logMessage("New split on " + scleft.print());1195 Plane * plane = best->event.getSplitPlane();1196 if (!sc.best->bleft.intersects(*plane))1197 {1198 mBuildLog->logMessage("Best plane outside parent box on level " +1199 StringConverter::toString(level));1200 }1201 OGRE_DELETE(plane);1202 #endif1203 1035 } 1204 1036 // cleanup … … 1207 1039 delete eventsLeft; 1208 1040 } 1041 1209 1042 if (eventsRight->size() > 0) 1210 1043 { … … 1214 1047 branch, old, old - best->cost, best, PlaneEvent::PES_RIGHT); 1215 1048 pqueue.push(scright); 1216 1217 #ifdef KDTREE_DEBUG_OFF1218 //mBuildLog->logMessage("best.pevent: " + best->event.print() +1219 // " eventsRight.size()=" + StringConverter::toString(eventsRight->size()));1220 mBuildLog->logMessage("New split on " + scright.print());1221 Plane * plane = best->event.getSplitPlane();1222 if (!sc.best->bright.intersects(*plane))1223 {1224 mBuildLog->logMessage("Best plane outside parent box on level " +1225 StringConverter::toString(level));1226 }1227 OGRE_DELETE(plane);1228 #endif1229 1049 } 1230 1050 // cleanup … … 1273 1093 } 1274 1094 1095 //------------------------------------------------------------------------- 1275 1096 SplitInfo * KdTree::pqFindPlane(PlaneEventList * events, int nObjects, AxisAlignedBox& aabb, Real globalSA) 1276 1097 { … … 1320 1141 } 1321 1142 1322 void KdTree::queueVisibleObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters, 1323 KdTree::RenderMethod renderMethod, bool showBoxes) 1324 { 1325 // for now only recurse or stack render methods 1143 /************************************************************************/ 1144 /* KdTree rendering functions */ 1145 /************************************************************************/ 1146 1147 //------------------------------------------------------------------------- 1148 void KdTree::queueVisibleObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes) 1149 { 1326 1150 if (mKdRoot) 1327 {1328 1151 recQueueVisibleObjects(mKdRoot, Root::getSingleton().getCurrentFrameNumber(), 1329 1152 cam, queue, onlyShadowCasters, showBoxes); 1330 1331 } 1332 1153 } 1154 1155 //------------------------------------------------------------------------- 1333 1156 void KdTree::recQueueVisibleObjects(KdTree::Node * node, unsigned long currentFrame, 1334 1157 Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes) … … 1383 1206 } 1384 1207 1208 /************************************************************************/ 1209 /* KdTree debug & helper functions */ 1210 /************************************************************************/ 1211 1212 //------------------------------------------------------------------------- 1385 1213 void KdTree::dump() 1386 1214 { … … 1390 1218 } 1391 1219 1220 //------------------------------------------------------------------------- 1392 1221 void KdTree::dump(KdTree::Node * node) 1393 1222 { … … 1411 1240 { 1412 1241 scenenode = dynamic_cast<KdTreeSceneNode *>(*it); 1413 log->logMessage(pad + "# Leaf level " + StringConverter::toString(node->mLevel) + 1242 log->logMessage(pad + "# Leaf level " + 1243 StringConverter::toString(node->mLevel) + 1414 1244 " SceneNode " + scenenode->getName()); 1415 1245 log->logMessage(pad + "## Objects: " + scenenode->dumpToString()); … … 1422 1252 if (branch->mLeft) 1423 1253 { 1424 log->logMessage(pad + "# Branch level " + StringConverter::toString(node->mLevel) + " Left Child"); 1254 log->logMessage(pad + "# Branch level " + 1255 StringConverter::toString(node->mLevel) + " Left Child"); 1425 1256 dump(branch->mLeft); 1426 1257 } 1427 1258 if (branch->mRight) 1428 1259 { 1429 log->logMessage(pad + "# Branch level " + StringConverter::toString(node->mLevel) + " Right Child"); 1260 log->logMessage(pad + "# Branch level " + 1261 StringConverter::toString(node->mLevel) + " Right Child"); 1430 1262 dump(branch->mRight); 1431 1263 } … … 1433 1265 } 1434 1266 1267 //------------------------------------------------------------------------- 1435 1268 Real KdTree::calcCost() 1436 1269 { … … 1441 1274 } 1442 1275 1276 //------------------------------------------------------------------------- 1443 1277 Real KdTree::calcCost(KdTree::Node * node, Real vs) 1444 1278 { … … 1449 1283 { 1450 1284 KdTree::Leaf * leaf = KDLEAFPTR_CAST(node); 1451 return (PlaneEvent::surfaceArea(node->mAABB)/vs)*PlaneEvent::KI*leaf->mKdRenderables.size(); 1285 return (PlaneEvent::surfaceArea(node->mAABB)/vs) * 1286 PlaneEvent::KI * leaf->mKdRenderables.size(); 1452 1287 } 1453 1288 else 1454 1289 { 1455 1290 KdTree::Branch * branch = KDBRANCHPTR_CAST(node); 1456 return (PlaneEvent::surfaceArea(node->mAABB)/vs)*PlaneEvent::KT + calcCost(branch->mLeft, vs) + calcCost(branch->mRight, vs); 1457 } 1458 } 1459 1291 return (PlaneEvent::surfaceArea(node->mAABB)/vs) * PlaneEvent::KT + 1292 calcCost(branch->mLeft, vs) + calcCost(branch->mRight, vs); 1293 } 1294 } 1295 1296 /************************************************************************/ 1297 /* KdTree::Node/Branch/Leaf functions */ 1298 /************************************************************************/ 1299 1300 //------------------------------------------------------------------------- 1460 1301 KdTree::Leaf::~Leaf() 1461 1302 { … … 1472 1313 } 1473 1314 1315 void KdTree::Leaf::queueVisibleObjects(unsigned long currentFrame, 1316 Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes) 1317 { 1318 KdRenderableList::iterator it = mKdRenderables.begin(); 1319 KdRenderableList::iterator end = mKdRenderables.end(); 1320 while (it != end) 1321 { 1322 if (!(*it)->isQueued(currentFrame, cam)) 1323 { 1324 (*it)->queueObjects(cam, queue, onlyShadowCasters); 1325 } 1326 it++; 1327 } 1328 1329 if (showBoxes) 1330 { 1331 WireBoundingBox * wbb = getWireBoundingBox(); 1332 if (wbb) 1333 queue->addRenderable(wbb); 1334 } 1335 } 1336 1337 //------------------------------------------------------------------------- 1474 1338 // update the world aabb based on the contained geometry 1475 1339 void KdTree::Leaf::_updateBounds(bool recurse) -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeHierarchyInterface.cpp
r1173 r1187 58 58 KdTreeSceneManager * ksm = static_cast<KdTreeSceneManager *>(mSceneManager); 59 59 60 // render only if the node is a leaf 61 if (kdnode->isLeaf()) 62 { 63 ksm->_renderNodes(KDLEAFPTR_CAST(node)->mKdRenderables, mCamera, 64 mOnlyShadowCasters, mLeavePassesInQueue); 65 } 60 ksm->_renderNode(kdnode, mCamera, mOnlyShadowCasters, mLeavePassesInQueue); 66 61 67 62 mVisibleNodes.push_back(node); -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp
r1185 r1187 61 61 62 62 // test 63 //String chc = "CHC";64 //setOption("RenderMethod", &chc);63 String chc = "CHC"; 64 setOption("RenderMethod", &chc); 65 65 } 66 66 … … 557 557 getRenderQueue()->clear(); 558 558 if (mKdTree) 559 mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, m RenderMethod, mShowBoxes);559 mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, mShowBoxes); 560 560 } 561 561 else … … 578 578 getRenderQueue()->clear(); 579 579 if (mKdTree) 580 mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, m RenderMethod, mShowBoxes);580 mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, mShowBoxes); 581 581 } 582 582 … … 697 697 if (mUseDepthPass) 698 698 { 699 KdRenderableList::const_iterator it, it_end = mVisibleNodes.end(); 700 701 //getRenderQueue()->clear(); 702 for (it = mVisibleNodes.begin(); it != it_end; ++ it) 699 //KdRenderableList::const_iterator it, it_end = mVisibleNodes.end(); 700 701 ////getRenderQueue()->clear(); 702 //for (it = mVisibleNodes.begin(); it != it_end; ++ it) 703 //{ 704 // (*it)->queueObjects(mCameraInProgress, getRenderQueue(), false); 705 //} 706 KdTree::NodeList::const_iterator it, end = mVisibleNodes.end(); 707 for (it = mVisibleNodes.begin(); it != end; it++) 703 708 { 704 (*it)->queueObjects(mCameraInProgress, getRenderQueue(), false); 709 (*it)->queueVisibleObjects(mHierarchyInterface->GetFrameId(), mCameraInProgress, 710 getRenderQueue(), false, mShowBoxes); 705 711 } 706 712 } 707 #endif 713 #endif 708 714 //-- now we can render all remaining queue objects 709 715 //-- used for depth pass, transparents, overlay … … 724 730 } 725 731 726 void KdTreeSceneManager::_renderNodes(const KdRenderableList& nodelist, Camera * cam, 727 bool onlyShadowCasters, int leavePassesInQueue) 728 { 729 #ifdef GTP_VISIBILITY_MODIFIED_OGRE 732 //void KdTreeSceneManager::_renderNodes(const KdRenderableList& nodelist, Camera * cam, 733 // bool onlyShadowCasters, int leavePassesInQueue) 734 void KdTreeSceneManager::_renderNode(KdTree::NodePtr node, Camera * cam, 735 bool onlyShadowCasters, int leavePassesInQueue) 736 { 730 737 RenderQueueGroup *currentGroup = 731 738 getRenderQueue()->getQueueGroup(getRenderQueue()->getDefaultQueueGroup()); 732 739 currentGroup->clear(leavePassesInQueue); 733 #else 734 getRenderQueue()->clear(); 735 #endif 736 KdRenderableList::const_iterator it = nodelist.begin(); 737 KdRenderableList::const_iterator end = nodelist.end(); 738 while (it != end) 739 { 740 if (!(*it)->isQueued(mHierarchyInterface->GetFrameId(), cam)) 741 { 742 mVisibleNodes.push_back(*it); 743 (*it)->queueObjects(cam, getRenderQueue(), onlyShadowCasters); 744 } 745 it++; 746 } 740 741 node->queueVisibleObjects(mHierarchyInterface->GetFrameId(), cam, getRenderQueue(), 742 onlyShadowCasters, mShowBoxes); 743 mVisibleNodes.push_back(node); 744 745 //KdRenderableList::const_iterator it = nodelist.begin(); 746 //KdRenderableList::const_iterator end = nodelist.end(); 747 //while (it != end) 748 //{ 749 // if (!(*it)->isQueued(mHierarchyInterface->GetFrameId(), cam)) 750 // { 751 // mVisibleNodes.push_back(*it); 752 // (*it)->queueObjects(cam, getRenderQueue(), onlyShadowCasters); 753 // } 754 // it++; 755 //} 747 756 748 757 _renderQueueGroupObjects(currentGroup, QueuedRenderableCollection::OM_PASS_GROUP); … … 957 966 nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); 958 967 959 for (Kd RenderableList::iterator it = mVisibleNodes.begin(); it != mVisibleNodes.end(); ++it)968 for (KdTree::NodeList::iterator it = mVisibleNodes.begin(); it != mVisibleNodes.end(); ++it) 960 969 { 961 970 if (mRenderNodesForViz) 962 971 { 963 KdTreeSceneNode * node = static_cast<KdTreeSceneNode *>(*it); 964 // render the leaf nodes 965 if (node->numAttachedObjects() && 966 !node->numChildren() && 967 (node->getAttachedObject(0)->getMovableType() == "Entity") && 968 node->getAttachedObject(0)->isVisible()) 969 { 970 getRenderQueue()->addRenderable(node); 971 } 972 //KdTreeSceneNode * node = static_cast<KdTreeSceneNode *>(*it); 973 //// render the leaf nodes 974 //if (node->numAttachedObjects() && 975 // !node->numChildren() && 976 // (node->getAttachedObject(0)->getMovableType() == "Entity") && 977 // node->getAttachedObject(0)->isVisible()) 978 //{ 979 // //getRenderQueue()->addRenderable(node); 980 // node->_addBoundingBoxToQueue(getRenderQueue()); 981 //} 982 983 /*** TODO: fix this ... maybe revert to original state, not quite happy now! ***/ 972 984 973 985 // addbounding boxes instead of node itself … … 977 989 if (mRenderNodesContentForViz) 978 990 { 979 (*it)->queueObjects(cam, getRenderQueue(), false); 991 //(*it)->queueObjects(cam, getRenderQueue(), false); 992 (*it)->queueVisibleObjects(mHierarchyInterface->GetFrameId(), 993 cam, getRenderQueue(), false, mShowBoxes); 980 994 } 981 995 } -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp
r1183 r1187 108 108 // Tell attached objects about camera position (incase any extra processing they want to do) 109 109 iobj->second->_notifyCurrentCamera(cam); 110 if (!onlyShadowCasters || iobj->second->getCastShadows()) 110 if (iobj->second->isVisible() && 111 (!onlyShadowCasters || iobj->second->getCastShadows())) 111 112 { 112 113 iobj->second->_updateRenderQueue(queue); … … 175 176 } 176 177 178 //void KdTreeSceneNode::getRenderOperation(RenderOperation& op) 179 //{ 180 // if (mWireBoundingBox == NULL) 181 // { 182 // mWireBoundingBox = new WireBoundingBox(); 183 // } 184 185 // mWireBoundingBox->setupBoundingBox(mWorldAABB); 186 // mWireBoundingBox->getRenderOperation(op); 187 //} 188 177 189 // DEBUG 178 190 String KdTreeSceneNode::dumpToString()
Note: See TracChangeset
for help on using the changeset viewer.