Changeset 420 for trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h
- Timestamp:
- 11/17/05 18:47:53 (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h
r419 r420 31 31 #include "Ray.h" 32 32 33 // -------------------------------------------------------------- 34 // Static statistics for kd-tree search 35 // -------------------------------------------------------------- 33 #include "RayInfo.h" 34 35 36 /** 37 Static statistics for vsp kd-tree search 38 */ 36 39 class VspKdStatistics: public StatisticsBase 37 40 { 38 41 public: 39 40 41 42 43 44 42 // total number of nodes 43 int nodes; 44 // number of splits along each of the axes 45 int splits[7]; 46 // totals number of rays 47 int rays; 45 48 // initial size of the pvs 46 49 int initialPvsSize; 47 50 // total number of query domains 48 49 50 51 int queryDomains; 52 // total number of ray references 53 int rayRefs; 51 54 52 55 // max depth nodes 53 54 55 56 56 int maxDepthNodes; 57 // max depth nodes 58 int minPvsNodes; 59 int minRaysNodes; 57 60 // max ray contribution nodes 58 61 int maxRayContribNodes; 59 62 // max depth nodes 60 int minSizeNodes; 61 62 // max number of rays per node 63 int maxRayRefs; 64 // number of dynamically added ray refs 65 int addedRayRefs; 66 // number of dynamically removed ray refs 67 int removedRayRefs; 68 69 // Constructor 70 VspKdStatistics() 71 { 72 Reset(); 73 } 74 75 int Nodes() const {return nodes;} 76 int Interior() const { return nodes/2; } 77 int Leaves() const { return (nodes/2) + 1; } 78 79 void Reset() 80 { 81 nodes = 0; 82 for (int i=0; i<7; i++) 83 splits[i] = 0; 84 rays = queryDomains = 0; 85 rayRefs = 0; 86 maxDepthNodes = 0; 87 minPvsNodes = 0; 88 minRaysNodes = 0; 89 maxRayRefs = 0; 90 addedRayRefs = removedRayRefs = 0; 91 initialPvsSize = 0; 92 maxRayContribNodes = 0; 93 minSizeNodes = 0; 94 } 95 96 void 97 Print(ostream &app) const; 98 99 friend ostream &operator<<(ostream &s, const VspKdStatistics &stat) { 100 stat.Print(s); 101 return s; 102 } 103 63 int minSizeNodes; 64 65 // max number of rays per node 66 int maxRayRefs; 67 // number of dynamically added ray refs 68 int addedRayRefs; 69 // number of dynamically removed ray refs 70 int removedRayRefs; 71 72 /** Default constructor. 73 */ 74 VspKdStatistics() { Reset(); } 75 int Nodes() const { return nodes; } 76 int Interior() const { return nodes / 2; } 77 int Leaves() const { return (nodes / 2) + 1; } 78 79 void Reset() 80 { 81 nodes = 0; 82 83 for (int i=0; i<7; i++) 84 splits[i] = 0; 85 86 rays = queryDomains = 0; 87 rayRefs = 0; 88 maxDepthNodes = 0; 89 minPvsNodes = 0; 90 minRaysNodes = 0; 91 maxRayRefs = 0; 92 addedRayRefs = removedRayRefs = 0; 93 initialPvsSize = 0; 94 maxRayContribNodes = 0; 95 minSizeNodes = 0; 96 } 97 98 void Print(ostream &app) const; 99 friend ostream &operator<<(ostream &s, const VspKdStatistics &stat) 100 { 101 stat.Print(s); 102 return s; 103 } 104 104 }; 105 105 … … 108 108 109 109 110 // -------------------------------------------------------------- 111 // KD-tree node - abstract class 112 // -------------------------------------------------------------- 110 /** Abstract superclass of Vsp-Kd-Tree nodes. 111 */ 113 112 class VspKdTreeNode 114 113 { … … 118 117 #define USE_FIXEDPOINT_T 1 119 118 120 struct RayInfo 121 { 122 // pointer to the actual ray 123 VssRay *mRay; 124 125 // endpoints - do we need them? 126 #if USE_FIXEDPOINT_T 127 short mMinT, mMaxT; 128 #else 129 float mMinT, mMaxT; 130 #endif 131 132 RayInfo():mRay(NULL) {} 133 134 RayInfo(VssRay *r):mRay(r), mMinT(0), 135 #if USE_FIXEDPOINT_T 136 #define FIXEDPOINT_ONE 0x7FFE 137 // mMaxT(0xFFFF) 138 mMaxT(FIXEDPOINT_ONE) 139 #else 140 mMaxT(1.0f) 141 #endif 142 {} 143 144 RayInfo(VssRay *r, 145 const float _min, 146 const float _max 147 ):mRay(r) 148 { 149 SetMinT(_min); 150 SetMaxT(_max); 151 } 152 153 RayInfo(VssRay *r, 154 const short _min, 155 const float _max):mRay(r), mMinT(_min) 156 { 157 SetMaxT(_max); 158 } 159 160 RayInfo(VssRay *r, 161 const float _min, 162 const short _max): 163 mRay(r), mMaxT(_max) 164 { 165 SetMinT(_min); 166 } 167 168 friend bool operator<(const RayInfo &a, const RayInfo &b) { 169 return a.mRay < b.mRay; 170 } 171 172 173 float ExtrapOrigin(const int axis) const { 174 return mRay->GetOrigin(axis) + GetMinT()*mRay->GetDir(axis); 175 } 176 177 float ExtrapTermination(const int axis) const { 178 return mRay->GetOrigin(axis) + GetMaxT()*mRay->GetDir(axis); 179 } 180 181 #if USE_FIXEDPOINT_T 182 float GetMinT () const { return mMinT/(float)(FIXEDPOINT_ONE); } 183 float GetMaxT () const { return mMaxT/(float)(FIXEDPOINT_ONE); } 184 185 void SetMinT (const float t) { 186 mMinT = (short) (t*(float)(FIXEDPOINT_ONE)); 187 } 188 189 void SetMaxT (const float t) { 190 mMaxT = (short) (t*(float)(FIXEDPOINT_ONE)); 191 mMaxT++; 192 // if (mMaxT!=0xFFFF) 193 // mMaxT++; 194 } 195 #else 196 float GetMinT () const { return mMinT; } 197 float GetMaxT () const { return mMaxT; } 198 199 void SetMinT (const float t) { mMinT = t; } 200 void SetMaxT (const float t) { mMaxT = t; } 201 #endif 202 203 204 int ComputeRayIntersection(const int axis, const float position, float &t) const 205 { 206 // intersect the ray with the plane 207 float denom = mRay->GetDir(axis); 208 209 if (fabs(denom) < 1e-20) 210 //if (denom == 0.0f) 211 return (mRay->GetOrigin(axis) > position) ? 1 : -1; 212 213 t = (position - mRay->GetOrigin(axis))/denom; 214 215 if (t < GetMinT()) 216 return (denom > 0) ? 1 : -1; 217 218 if (t > GetMaxT()) 219 return (denom > 0) ? -1 : 1; 220 221 return 0; 222 } 223 224 225 }; 226 227 228 typedef vector<RayInfo> RayInfoContainer; 229 230 enum {EInterior, ELeaf}; 231 232 ///////////////////////////////// 233 // The actual data goes here 234 235 // link to the parent 236 VspKdTreeInterior *mParent; 237 238 enum {SPLIT_X=0, SPLIT_Y, SPLIT_Z, SPLIT_DIRX, SPLIT_DIRY, SPLIT_DIRZ}; 239 240 // splitting axis 241 char mAxis; 242 243 // depth 244 unsigned char mDepth; 245 246 // short depth; 247 // 248 ///////////////////////////////// 249 250 inline VspKdTreeNode(VspKdTreeInterior *p); 251 252 253 virtual ~VspKdTreeNode() {}; 254 virtual int Type() const = 0; 255 256 257 bool IsLeaf() const { return mAxis == -1; } 258 259 virtual void Print(ostream &s) const = 0; 260 261 virtual int GetAccessTime() 262 { 263 return 0x7FFFFFF; 264 } 265 266 267 119 enum {EInterior, ELeaf}; 120 121 /** Constructs new interior node from the parent node. 122 */ 123 inline VspKdTreeNode(VspKdTreeInterior *p); 124 125 /** Destroys this node and the subtree. 126 */ 127 virtual ~VspKdTreeNode(); 128 129 /** Type of the node (Einterior or ELeaf) 130 */ 131 virtual int Type() const = 0; 132 133 /** Returns true if this node is a leaf. 134 */ 135 bool IsLeaf() const; 136 137 /** Prints node stats. 138 */ 139 virtual void Print(ostream &s) const = 0; 140 141 /** Returns time needed to access this node. 142 */ 143 virtual int GetAccessTime(); // NOTE: don't really know how it is used! 144 145 /** Returns parent node. 146 */ 147 VspKdTreeInterior *GetParent() const; 148 /** Sets parent node. 149 */ 150 void SetParent(VspKdTreeInterior *p); 151 152 protected: 153 ///////////////////////////////// 154 // The actual data goes here 155 156 /// link to the parent 157 VspKdTreeInterior *mParent; 158 159 enum {SPLIT_X = 0, SPLIT_Y, SPLIT_Z, SPLIT_DIRX, SPLIT_DIRY, SPLIT_DIRZ}; 160 161 /// splitting axis 162 char mAxis; 163 164 /// depth 165 unsigned char mDepth; 268 166 }; 269 167 … … 276 174 friend class VspKdTree; 277 175 176 /** Constructs new interior node from parent node. 177 */ 278 178 VspKdTreeInterior(VspKdTreeInterior *p); 279 179 … … 286 186 virtual void Print(ostream &s) const; 287 187 188 /** Returns back child. 189 */ 288 190 inline VspKdTreeNode *GetBack() const; 191 /** Returns front child. 192 */ 289 193 inline VspKdTreeNode *GetFront() const; 290 194 291 195 protected: 292 196 197 /** Sets pointers to back child and front child. 198 */ 293 199 void SetupChildLinks(VspKdTreeNode *b, VspKdTreeNode *f); 294 200 201 /** Replaces the pointer to oldChild with a pointer to newChild. 202 */ 295 203 void ReplaceChildLink(VspKdTreeNode *oldChild, VspKdTreeNode *newChild); 296 204 205 /** Computes intersection of the ray with the node boundaries. 206 */ 297 207 int ComputeRayIntersection(const RayInfo &rayData, float &t); 298 208 … … 321 231 friend class VspKdTree; 322 232 233 /** Constructs leaf from parent node. 234 @param p the parent node 235 @param nRays preallocates memory to store this number of rays 236 */ 237 VspKdTreeLeaf(VspKdTreeInterior *p, const int nRays); 238 239 virtual ~VspKdTreeLeaf(); 240 241 virtual int Type() const; 242 243 virtual void Print(ostream &s) const; 244 245 /** Adds a ray to the leaf ray container. 246 */ 247 void AddRay(const RayInfo &data); 248 /** Returns size of the leaf PVS as induced by the rays 249 @note returns precomputed PVS size, which may not be valid 250 anymore. Run UpdatePvsSize to get a valid PVS. 251 */ 252 int GetPvsSize() const; 253 void SetPvsSize(const int s); 254 255 /** If PVS is not valid, this function recomputes the leaf 256 PVS as induced by the rays. 257 */ 258 void UpdatePvsSize(); 259 260 void Mail(); 261 262 bool Mailed() const; 263 264 bool Mailed(const int mail); 265 266 /** Returns average contribution of a ray to the PVS 267 */ 268 inline float GetAvgRayContribution() const; 269 /** Returns square of average contribution of a ray. 270 */ 271 inline float GetSqrRayContribution() const; 272 273 static void NewMail(); 274 323 275 static int mailID; 324 int mailbox; 325 326 RayInfoContainer rays; 276 277 protected: 278 279 int mMailbox; 280 281 RayInfoContainer mRays; 327 282 bool mValidPvs; 328 283 329 VspKdTreeLeaf(VspKdTreeInterior *p, const int nRays):330 VspKdTreeNode(p), rays(), mPvsSize(0), mValidPvs(false)331 {332 rays.reserve(nRays);333 }334 335 virtual ~VspKdTreeLeaf() { }336 337 virtual int Type() const338 {339 return ELeaf;340 }341 342 virtual void Print(ostream &s) const343 {344 s << endl << "L: r = " << (int)rays.size() << endl;345 };346 347 void AddRay(const RayInfo &data)348 {349 mValidPvs = false;350 rays.push_back(data);351 data.mRay->Ref();352 }353 354 int GetPvsSize() const355 {356 return mPvsSize;357 }358 void SetPvsSize(const int s)359 {360 mPvsSize = s;361 }362 363 void UpdatePvsSize();364 365 void Mail()366 {367 mailbox = mailID;368 }369 370 static void NewMail()371 {372 ++ mailID;373 }374 375 bool Mailed() const376 {377 return mailbox == mailID;378 }379 380 bool Mailed(const int mail)381 {382 return mailbox >= mailID + mail;383 }384 385 float GetAvgRayContribution() const386 {387 return GetPvsSize()/((float)rays.size() + Limits::Small);388 }389 390 float GetSqrRayContribution() const391 {392 return sqr(GetPvsSize()/((float)rays.size() + Limits::Small));393 }394 284 private: 395 285 int mPvsSize; 396 286 }; 397 398 // Inline functions399 inline VspKdTreeNode::VspKdTreeNode(VspKdTreeInterior *p):400 mParent(p), mAxis(-1), mDepth(p ? p->mDepth + 1 : 0)401 {}402 287 403 288 … … 501 386 }; 502 387 503 / / simplified data for ray traversal only...504 388 /** Simplified data for ray traversal only. 389 */ 505 390 struct RayTraversalData 506 391 { 507 VspKdTreeNode::RayInfo mRayData;392 RayInfo mRayData; 508 393 VspKdTreeNode *mNode; 509 394 510 395 RayTraversalData() {} 511 396 512 RayTraversalData(VspKdTreeNode *n, const VspKdTreeNode::RayInfo &data):397 RayTraversalData(VspKdTreeNode *n, const RayInfo &data): 513 398 mRayData(data), mNode(n) {} 514 399 }; … … 521 406 virtual void Construct(VssRayContainer &rays, 522 407 AxisAlignedBox3 *forcedBoundingBox = NULL); 523 524 // incemental construction 408 409 /** Returns bounding box of the specified node. 410 */ 411 AxisAlignedBox3 GetBBox(VspKdTreeNode *node) const; 412 413 const VspKdStatistics &GetStatistics() const; 414 415 /** Get the root of the tree. 416 */ 417 VspKdTreeNode *GetRoot() const; 418 419 /** Returns average PVS size in tree. 420 */ 421 float GetAvgPvsSize(); 422 423 /** Parses the environment and stores the global VspKd tree parameters 424 */ 425 static void ParseEnvironment(); 426 427 ///////////////////////////// 428 // Construction parameters 429 430 /// max depth of the tree 431 static int sTermMaxDepth; 432 433 /// minimal ratio of the volume of the cell and the query volume 434 static float sTermMinSize; 435 436 /// minimal pvs per node to still get subdivided 437 static int sTermMinPvs; 438 439 /// minimal ray number per node to still get subdivided 440 static int sTermMinRays; 441 442 /// maximal cost ration to subdivide a node 443 static float sTermMaxCostRatio; 444 445 /// maximal contribution per ray to subdivide the node 446 static float sTermMaxRayContribution; 447 448 /** Returns memory usage in MB. 449 */ 450 float GetMemUsage() const; 451 452 float GetRayMemUsage() const; 453 454 protected: 455 // incremental construction 525 456 virtual void UpdateRays(VssRayContainer &remove, VssRayContainer &add); 526 457 527 virtual void AddRays(VssRayContainer &add) 528 { 529 VssRayContainer remove; 530 UpdateRays(remove, add); 531 } 458 virtual void AddRays(VssRayContainer &add); 532 459 533 460 VspKdTreeNode *Locate(const Vector3 &v); … … 549 476 550 477 void SortSplitCandidates(VspKdTreeLeaf *node, 551 const int axis); 552 553 554 // return memory usage in MB 555 float GetMemUsage() const 556 { 557 return 558 (sizeof(VspKdTree) + 559 mStat.Leaves() * sizeof(VspKdTreeLeaf) + 560 mStat.Interior() * sizeof(VspKdTreeInterior) + 561 mStat.rayRefs * sizeof(VspKdTreeNode::RayInfo)) / (1024.0f*1024.0f); 562 } 563 564 float GetRayMemUsage() const 565 { 566 return mStat.rays * (sizeof(VssRay))/(1024.0f * 1024.0f); 567 } 478 const int axis); 568 479 569 480 float BestCostRatioHeuristic(VspKdTreeLeaf *node, … … 591 502 int &pvsFront); 592 503 593 AxisAlignedBox3 GetBBox(VspKdTreeNode *node) const;594 504 595 505 VspKdTreeNode * SubdivideLeaf(VspKdTreeLeaf *leaf, … … 619 529 SimpleRayContainer &rays); 620 530 621 float GetAvgPvsSize();622 623 /** Get the root of the tree.624 */625 VspKdTreeNode *GetRoot() const;626 627 531 int CollapseSubtree(VspKdTreeNode *sroot, const int time); 628 629 const VspKdStatistics &GetStatistics() const;630 532 631 533 int ReleaseMemory(const int time); 632 633 /** Parses the environment and stores the global BSP tree parameters634 */635 static void ParseEnvironment();636 637 /////////////////////////////638 // Construction parameters639 640 // max depth of the tree641 static int sTermMaxDepth;642 643 // minimal ratio of the volume of the cell and the query volume644 static float sTermMinSize;645 646 // minimal pvs per node to still get subdivided647 static int sTermMinPvs;648 649 // minimal ray number per node to still get subdivided650 static int sTermMinRays;651 652 // maximal cost ration to subdivide a node653 static float sTermMaxCostRatio;654 655 // maximal contribution per ray to subdivide the node656 static float sTermMaxRayContribution;657 534 658 535 protected:
Note: See TracChangeset
for help on using the changeset viewer.