source: GTP/trunk/Lib/Vis/Preprocessing/src/VspKdTree.h @ 860

Revision 860, 20.4 KB checked in by mattausch, 19 years ago (diff)
RevLine 
[408]1// ================================================================
2// $Id$
3// ****************************************************************
4//
5// Initial coding by
6/**
7   @author Jiri Bittner
8*/
[405]9
[408]10#ifndef __VSPKDTREE_H__
11#define __VSPKDTREE_H__
12
13// Standard headers
14#include <iomanip>
15#include <vector>
[405]16#include <functional>
[408]17#include <stack>
[405]18
[408]19
20// User headers
21#include "VssRay.h"
[405]22#include "AxisAlignedBox3.h"
23
24
[408]25#define USE_KDNODE_VECTORS 1
26#define _RSS_STATISTICS
27#define _RSS_TRAVERSAL_STATISTICS
[405]28
[408]29
30#include "Statistics.h"
31#include "Ray.h"
32
[420]33#include "RayInfo.h"
[428]34#include "Containers.h"
[469]35#include "ViewCell.h"
[420]36
[462]37class VspKdLeaf;
38class ViewCellsManager;
39class ViewCellsStatistics;
[452]40
[860]41namespace GtpVisibilityPreprocessor {
[462]42
[420]43/**
[452]44        Candidate for leaf merging based on priority.
45*/
[580]46class VspKdMergeCandidate
[452]47
48public:
49
[580]50        VspKdMergeCandidate(VspKdLeaf *l1, VspKdLeaf *l2);
[452]51
52        /** Computes PVS difference between the leaves.
53        */
[453]54        //int ComputePvsDifference() const;
[452]55
[462]56        /** If this merge pair is still valid.
[452]57        */
[462]58        bool Valid() const;
[452]59
[462]60        /** Sets this merge candidate to be valid.
61        */
62        void SetValid();
63
[580]64        friend bool operator<(const VspKdMergeCandidate &leafa, const VspKdMergeCandidate &leafb)
[452]65        {
[462]66                return leafb.GetMergeCost() < leafa.GetMergeCost();
[452]67        }
[462]68
69        void SetLeaf1(VspKdLeaf *l);
70        void SetLeaf2(VspKdLeaf *l);
71
72        VspKdLeaf *GetLeaf1();
73        VspKdLeaf *GetLeaf2();
74
75        /** Merge cost of this candidate pair.
76        */
77        float GetMergeCost() const;
78
[472]79        /** Returns cost of leaf 1.
80        */
81        float GetLeaf1Cost() const;
82        /** Returns cost of leaf 2.
83        */
84        float GetLeaf2Cost() const;
85
[462]86        /// maximal pvs size
87        static int sMaxPvsSize;
[472]88        /// overall cost used to normalize cost ratio
89        static float sOverallCost;
[462]90
91protected:
92       
93        /** Evaluates the merge costs of the leaves.
94        */
95        void EvalMergeCost();
96
97        int mLeaf1Id;
98        int mLeaf2Id;
99
100        float mMergeCost;
101       
102        VspKdLeaf *mLeaf1;
103        VspKdLeaf *mLeaf2;
[452]104};
105
106
107
108/**
[420]109        Static statistics for vsp kd-tree search
110*/
[408]111class VspKdStatistics:  public StatisticsBase
[405]112{
113public: 
[420]114        // total number of nodes
115        int nodes;
116        // number of splits along each of the axes
[454]117        int splits[3];
[420]118        // totals number of rays
119        int rays;
[408]120        // initial size of the pvs
[420]121        int initialPvsSize;
[408]122        // total number of query domains
[420]123        int queryDomains;
124        // total number of ray references
125        int rayRefs;
[408]126
127        // max depth nodes
[420]128        int maxDepthNodes;
129        // max depth nodes
130        int minPvsNodes;
[426]131        // nodes with minimum PVS
[420]132        int minRaysNodes;
[408]133        // max ray contribution nodes
[420]134        int maxRayContribNodes;
[408]135        // max depth nodes
[420]136        int minSizeNodes;
[408]137       
[420]138        // max number of rays per node
139        int maxRayRefs;
[426]140        // maximal PVS size / leaf
141        int maxPvsSize;
142
[482]143        // max cost ratio
144        int maxCostNodes;
145
[420]146        // number of dynamically added ray refs
147        int addedRayRefs;
148        // number of dynamically removed ray refs
149        int removedRayRefs;
[405]150 
[482]151        /// for average pvs
152        int accPvsSize;
153
[420]154        /** Default constructor.
155        */
156        VspKdStatistics() {     Reset(); }
157        int Nodes() const { return nodes; }
158        int Interior() const { return nodes / 2; }
159        int Leaves() const { return (nodes / 2) + 1; }
[405]160
[420]161        void Reset()
162        {
163                nodes = 0;
[405]164
[454]165                for (int i=0; i<3; i++)
[420]166                        splits[i] = 0;
[405]167
[420]168                rays = queryDomains = 0;
169                rayRefs = 0;
[426]170               
[420]171                maxDepthNodes = 0;
172                minPvsNodes = 0;
[426]173                minRaysNodes = 0;
174                maxRayContribNodes = 0;
175                minSizeNodes = 0;
[482]176                maxCostNodes = 0;
[426]177
[420]178                maxRayRefs = 0;
179                addedRayRefs = removedRayRefs = 0;
[426]180               
[420]181                initialPvsSize = 0;
[426]182                maxPvsSize = 0;
[482]183                accPvsSize = 0;
[420]184        }
185
186        void Print(ostream &app) const;
187        friend ostream &operator<<(ostream &s, const VspKdStatistics &stat)
188        {
189            stat.Print(s);
190            return s;
191        } 
[405]192};
193
[408]194
[462]195class VspKdInterior;
[408]196
197
[420]198/** Abstract superclass of Vsp-Kd-Tree nodes.
199*/
[462]200class VspKdNode
[408]201{
[405]202public:
[408]203
[419]204        friend class VspKdTree;
[408]205
[500]206        enum {EInterior, EIntermediate, ELeaf};
[405]207
[420]208        /** Constructs new interior node from the parent node.
209        */
[500]210        inline VspKdNode(VspKdNode *p);
[405]211
[420]212        /** Destroys this node and the subtree.
213        */
[462]214        virtual ~VspKdNode();
[405]215
[420]216        /** Type of the node (Einterior or ELeaf)
217        */
218        virtual int Type() const = 0;
219 
220        /** Returns true if this node is a leaf.
221        */
222        bool IsLeaf() const;
223       
224        /** Prints node stats.
225        */
226        virtual void Print(ostream &s) const = 0;
[405]227
[420]228        /** Returns time needed to access this node.
[500]229                @NOTE: don't really know how it is used!
[420]230        */
[500]231        virtual int GetAccessTime();
[405]232
[420]233        /** Returns parent node.
234        */
[500]235        VspKdNode *GetParent() const;
[426]236
[420]237        /** Sets parent node.
238        */
[500]239        void SetParent(VspKdNode *p);
[408]240
[420]241protected:
242        /////////////////////////////////
243        // The actual data goes here
[408]244 
[420]245        /// link to the parent
[500]246        VspKdNode *mParent;
[405]247
[482]248        enum {SPLIT_X = 0, SPLIT_Y, SPLIT_Z};
[408]249 
[420]250        /// splitting axis
251        char mAxis;
[408]252       
[420]253        /// depth
254        unsigned char mDepth;
[405]255};
[408]256
257// --------------------------------------------------------------
258// KD-tree node - interior node
259// --------------------------------------------------------------
[462]260class VspKdInterior: public VspKdNode
[408]261{
262public:
[419]263        friend class VspKdTree;
264
[420]265        /** Constructs new interior node from parent node.
266        */
[462]267        VspKdInterior(VspKdInterior *p);
[418]268                       
269        virtual int GetAccessTime();
270       
[419]271        virtual int Type() const;
[405]272 
[462]273        virtual ~VspKdInterior();
[418]274   
275        virtual void Print(ostream &s) const;
[408]276
[420]277        /** Returns back child.
278        */
[462]279        inline VspKdNode *GetBack() const;
[420]280        /** Returns front child.
281        */
[462]282        inline VspKdNode *GetFront() const;
[419]283
[418]284protected:
[408]285
[420]286        /** Sets pointers to back child and front child.
287        */
[462]288        void SetupChildLinks(VspKdNode *b, VspKdNode *f);
[420]289        /** Replaces the pointer to oldChild with a pointer to newChild.
290        */
[462]291        void ReplaceChildLink(VspKdNode *oldChild, VspKdNode *newChild);
[420]292        /** Computes intersection of the ray with the node boundaries.
293        */
[418]294        int ComputeRayIntersection(const RayInfo &rayData, float &t);
[408]295
[418]296        // plane in local modelling coordinates
297        float mPosition;
[408]298
[418]299        // pointers to children
[462]300        VspKdNode *mBack;
301        VspKdNode *mFront;
[405]302
[418]303        // the bbox of the node
[419]304        AxisAlignedBox3 mBox;
[418]305
306        // data for caching
307        long mAccesses;
308        long mLastAccessTime;
[408]309};
310
311
[500]312/**
313        Node type just before leaf holding abitrary split plane
314*/
315class VspKdIntermediate: public VspKdNode
316{
317public:
318        friend class VspKdTree;
319
320        /** Constructs new interior node from parent node.
321        */
322        VspKdIntermediate(VspKdInterior *p);
323                       
324        //virtual int GetAccessTime();
325       
326        virtual int Type() const;
327 
328        virtual ~VspKdIntermediate();
329   
330        virtual void Print(ostream &s) const;
331
332        /** Returns back child.
333        */
334        inline VspKdLeaf *GetBack() const;
335        /** Returns front child.
336        */
337        inline VspKdLeaf *GetFront() const;
338
339protected:
340
341        /** Sets pointers to back child and front child.
342        */
343        void SetupChildLinks(VspKdLeaf *b, VspKdLeaf *f);
344        /** Computes intersection of the ray with the node boundaries.
345        */
346        int ComputeRayIntersection(const RayInfo &rayData, float &t);
347
348        // plane in local modelling coordinates
349        Plane3 mSplitPlane;
350
351        // pointers to children
352        VspKdLeaf *mBack;
353        VspKdLeaf *mFront;
354
355        // the bbox of the node
356        AxisAlignedBox3 mBox;
357
358        // data for caching
359        long mAccesses;
360        long mLastAccessTime;
361};
362
[408]363// --------------------------------------------------------------
364// KD-tree node - leaf node
365// --------------------------------------------------------------
[462]366class VspKdLeaf: public VspKdNode
[408]367{
368public:
[465]369
[419]370        friend class VspKdTree;
371
[420]372        /** Constructs leaf from parent node.
373                @param p the parent node
374                @param nRays preallocates memory to store this number of rays
[472]375                @parma maxMisses how many times the max cost ratio was missed on the path to the leaf
[420]376        */
[500]377        VspKdLeaf(VspKdNode *p, const int nRays, const int maxCostMisses = 0);
[408]378       
[462]379        virtual ~VspKdLeaf();
[405]380
[420]381        virtual int Type() const; 
[408]382
[420]383        virtual void Print(ostream &s) const;
[405]384 
[420]385        /** Adds a ray to the leaf ray container.
386        */
387        void AddRay(const RayInfo &data);
388        /** Returns size of the leaf PVS as induced by the rays
389                @note returns precomputed PVS size, which may not be valid
390                anymore. Run UpdatePvsSize to get a valid PVS.
391        */
392        int GetPvsSize() const;
[405]393
[420]394        /** If PVS is not valid, this function recomputes the leaf
395                PVS as induced by the rays.
396        */
[410]397        void UpdatePvsSize();
[408]398
[428]399        /** Returns stored rays.
400        */
[426]401        RayInfoContainer &GetRays();
402
[428]403        /** Returns rays into this ray container.
404        */
405        void GetRays(VssRayContainer &rays);
[420]406        /** Returns average contribution of a ray to the PVS
407        */
408        inline float GetAvgRayContribution() const;
409        /** Returns square of average contribution of a ray.
410        */
411        inline float GetSqrRayContribution() const;
[408]412
[428]413        /** Extracts PVS from ray set.
414        */
415        void ExtractPvs(ObjectContainer &objects) const;
416
[422]417        //-- mailing options
418        void Mail();
419
420        bool Mailed() const;
421 
[462]422        /** Returns true if mail equals the leaf mail box.
423        */
424        bool Mailed(const int mail) const;
[422]425
[462]426        void SetViewCell(VspKdViewCell *viewCell);
[420]427
[462]428        /** Returns mail box of this leaf.
429        */
430        int GetMailbox() const;
[420]431
[462]432        /** Returns view cell associated with this leaf.
[453]433        */
[462]434        VspKdViewCell *GetViewCell();
[453]435
[472]436        /** Returns number of times the max cost ratio was missed until
437                this leaf.
438        */
439        int GetMaxCostMisses();
440
[462]441        ////////////////////////////////////////////
442       
443        static void NewMail();
444        static int sMailId;
445
[495]446        ObjectPvs *mPvs;
447        float mVolume;
448
[420]449protected:
[426]450
451        /** Manually sets PVS size.
452                @param s the PVS size
453        */
454        void SetPvsSize(const int s);
455
[420]456        int mMailbox;
457 
[472]458        /// rays intersecting this leaf.
[420]459        RayInfoContainer mRays;
[462]460        /// true if mPvsSize is valid => PVS does not have to be updated
[420]461        bool mValidPvs;
[462]462        /// the view cell associated with this leaf
463        VspKdViewCell *mViewCell;
[472]464        /// number of times the max cost ratio was missed on the way to the leaf.
465        int mMaxCostMisses;
[462]466
[500]467//private:
[462]468        /// stores PVS size so we have to evaluate PVS size only once
[419]469        int mPvsSize;
[405]470};
471
472
[408]473// ---------------------------------------------------------------
474// Main LSDS search class
475// ---------------------------------------------------------------
476class VspKdTree
477{
[411]478        // --------------------------------------------------------------
479        // For sorting rays
480        // -------------------------------------------------------------
481        struct SortableEntry
482        {
483                enum EType
484                {
485                        ERayMin,
486                        ERayMax
487                };
488
489                int type;
490                float value;
[482]491                VssRay *ray;
[411]492 
493                SortableEntry() {}
[482]494                SortableEntry(const int t, const float v, VssRay *r): type(t),
495                                          value(v), ray(r)
[411]496                {
497                }
498               
499                friend bool operator<(const SortableEntry &a, const SortableEntry &b)
500                {
501                        return a.value < b.value;
502                }
503        };
504
[410]505        struct TraversalData
506        { 
[462]507                VspKdNode *mNode;
[419]508                AxisAlignedBox3 mBox;
[500]509                //TODO PolygonContainer *mPolys;
510
[419]511                int mDepth;
[423]512                //float mPriority;
[410]513       
514                TraversalData() {}
[405]515
[462]516                TraversalData(VspKdNode *n, const float p):
[423]517                mNode(n)//, mPriority(p)
[410]518                {}
[408]519
[462]520                TraversalData(VspKdNode *n,     const AxisAlignedBox3 &b, const int d):
[419]521                mNode(n), mBox(b), mDepth(d) {}
[405]522   
[423]523                // comparator for the priority queue
524                /*struct less_priority : public binary_function<const TraversalData, const TraversalData, bool>
[410]525                {
[423]526                        bool operator()(const TraversalData a, const TraversalData b) {                 
527                        return a.mPriority < b.mPriority;               }       };*/
[405]528
[410]529                //    ~TraversalData() {}
530                //    TraversalData(const TraversalData &s):node(s.node), bbox(s.bbox), depth(s.depth) {}
[408]531   
[472]532        friend bool operator<(const TraversalData &a, const TraversalData &b)
[410]533                {
534                        // return a.node->queries.size() < b.node->queries.size();
[500]535                        VspKdLeaf *leafa = dynamic_cast<VspKdLeaf *>(a.mNode);
536                        VspKdLeaf *leafb = dynamic_cast<VspKdLeaf *>(b.mNode);
[408]537#if 0
538                        return
[474]539                                leafa->rays.size() * a.mBox.GetVolume()
[408]540                                <
[474]541                                leafb->rays.size() * b.mBox.GetVolume();
[408]542#endif
[587]543#if 0
[408]544                        return
[474]545                                leafa->GetPvsSize() * a.mBox.GetVolume()
[408]546                                <
[474]547                                leafb->GetPvsSize() * b.mBox.GetVolume();
[408]548#endif
549#if 0
550                        return
551                                leafa->GetPvsSize()
552                                <
553                                leafb->GetPvsSize();
554#endif
555#if 0
556                        return
[423]557                                leafa->GetPvsSize() / (float)(leafa->rays.size() + Limits::Small())
[408]558                                >
[423]559                                leafb->GetPvsSize() / (float)(leafb->rays.size() + Limits::Small());
[408]560#endif
561#if 0
562                        return
[410]563                                leafa->GetPvsSize() * (float)leafa->rays.size()
[408]564                                <
[410]565                                leafb->GetPvsSize() * (float)leafb->rays.size();
[408]566#endif
[587]567#if 1
568                        return a.mDepth > b.mDepth;
569#endif
[468]570                }
571        };
[405]572 
[468]573        /** Simplified data for ray traversal only.
574        */
575        struct RayTraversalData
576        {
577                RayInfo mRayData;
578                VspKdNode *mNode;
579
580                RayTraversalData() {}
[410]581         
[468]582                RayTraversalData(VspKdNode *n, const RayInfo &data):
583                mRayData(data), mNode(n) {}
584        };
[408]585       
[483]586        struct LineTraversalData
[468]587        {
588                VspKdNode *mNode;
589                Vector3 mExitPoint;
590               
591                float mMaxT;
592   
[483]593                LineTraversalData () {}
594                LineTraversalData (VspKdNode *n,
[468]595                                                                  const Vector3 &p,
596                                                                  const float maxt):
597                mNode(n), mExitPoint(p), mMaxT(maxt) {}
598        };
599
[405]600public:
601
[410]602        VspKdTree();
603        virtual ~VspKdTree();
[405]604
[440]605        virtual void Construct(const VssRayContainer &rays,
[410]606                                                   AxisAlignedBox3 *forcedBoundingBox = NULL);
[420]607
608        /** Returns bounding box of the specified node.
609        */
[462]610        AxisAlignedBox3 GetBBox(VspKdNode *node) const;
[420]611
612        const VspKdStatistics &GetStatistics() const;
613
614        /** Get the root of the tree.
615        */
[462]616        VspKdNode *GetRoot() const;
[420]617
618        /** Returns average PVS size in tree.
619        */
620        float GetAvgPvsSize();
621
622        /** Returns memory usage in MB.
623        */
624        float GetMemUsage() const;
[485]625        //?
[420]626        float GetRayMemUsage() const;
627
[428]628        /** Collects leaves of this tree.
629        */
[462]630        void CollectLeaves(vector<VspKdLeaf *> &leaves) const;
[428]631
[485]632        /** Merges view cells created with this tree according to
633                some (global) cost heuristics.
[452]634        */
[485]635        int MergeViewCells(const VssRayContainer &rays);
[452]636
637        /** Finds neighbours of this node.
638                @param n the input node
639                @param neighbours the neighbors of the input node
640                @param onlyUnmailed if only unmailed neighbors are collected
641        */
[462]642        int FindNeighbors(VspKdLeaf *n,
643                                          vector<VspKdLeaf *> &neighbors,
[452]644                                          bool onlyUnmailed);
645
[462]646       
647        /** Sets pointer to view cells manager.
648        */
649        void SetViewCellsManager(ViewCellsManager *vcm);
650
[463]651        /** A ray is cast possible intersecting the tree.
652                @param the ray that is cast.
653                @returns the number of intersections with objects stored in the tree.
654        */
[468]655        int CastLineSegment(const Vector3 &origin,
656                                                const Vector3 &termination,
657                                                vector<ViewCell *> &viewcells);
[462]658
659        /** Collects view cells generated by this tree.
660        */
661        void CollectViewCells(ViewCellContainer &viewCells) const;
[486]662       
663        /** Refines view cells using shuffling, i.e., border leaves
664                of two view cells are exchanged if the resulting view cells
665                are tested to be "better" than the old ones.
666                @returns number of refined view cells
[473]667        */
[486]668        int RefineViewCells(const VssRayContainer &rays);
[473]669
[483]670        /** Collects candidates for the merge in the merge queue.
671        */
672        void CollectMergeCandidates();
673
[485]674        /** Collapses the tree with respect to the view cell partition.
[501]675                @returns number of collapsed nodes
[485]676        */
[501]677        int CollapseTree();
[485]678
[420]679protected:
[428]680
[501]681        /** Collapses the tree with respect to the view cell partition,
682                i.e. leaves having the same view cell are collapsed.
683                @param node the root of the subtree to be collapsed
684                @param collapsed returns the number of collapsed nodes
[495]685                @returns node of type leaf if the node could be collapsed,
686                this node otherwise
687        */
[501]688        VspKdNode *CollapseTree(VspKdNode *node, int &collapsed);
689
[420]690        // incremental construction
[410]691        virtual void UpdateRays(VssRayContainer &remove, VssRayContainer &add);
[405]692
[420]693        virtual void AddRays(VssRayContainer &add);
[405]694
[462]695        VspKdNode *Locate(const Vector3 &v);
[408]696       
[462]697        VspKdNode *SubdivideNode(VspKdLeaf *leaf,
[410]698                                                                 const AxisAlignedBox3 &box,
699                                                                 AxisAlignedBox3 &backBox,
700                                                                 AxisAlignedBox3 &frontBox);
[408]701       
[462]702        VspKdNode *Subdivide(const TraversalData &tdata);
[408]703       
[462]704        int SelectPlane(VspKdLeaf *leaf,
[410]705                                        const AxisAlignedBox3 &box,
706                                        float &position,
707                                        int &raysBack,
708                                        int &raysFront,
709                                        int &pvsBack,
710                                        int &pvsFront);
[405]711
[462]712        void SortSplitCandidates(VspKdLeaf *node,
[420]713                                                         const int axis);       
[408]714 
[462]715        float BestCostRatioHeuristic(VspKdLeaf *node,
[480]716                                                                 const AxisAlignedBox3 &box,
[410]717                                                                 int &axis,
718                                                                 float &position,
719                                                                 int &raysBack,
720                                                                 int &raysFront,
721                                                                 int &pvsBack,
722                                                                 int &pvsFront);
[405]723
[480]724        float BestCostRatioRegular(VspKdLeaf *node,
725                                                           const AxisAlignedBox3 &box,
[410]726                                                           int &axis,
727                                                           float &position,
728                                                           int &raysBack,
729                                                           int &raysFront,
730                                                           int &pvsBack,
731                                                           int &pvsFront);
[408]732       
[462]733        float EvalCostRatio(VspKdLeaf *node,
[480]734                                                const AxisAlignedBox3 &box,
[410]735                                                const int axis,
736                                                const float position,
737                                                int &raysBack,
738                                                int &raysFront,
739                                                int &pvsBack,
740                                                int &pvsFront);
[405]741
742
[462]743        VspKdNode * SubdivideLeaf(VspKdLeaf *leaf,
[410]744                                                                  const float SAThreshold);
[405]745
[410]746        void RemoveRay(VssRay *ray,
[462]747                                   vector<VspKdLeaf *> *affectedLeaves,
[410]748                                   const bool removeAllScheduledRays);
[405]749
[410]750        void AddRay(VssRay *ray);
[408]751       
[410]752        void TraverseInternalNode(RayTraversalData &data,
753                                                         stack<RayTraversalData> &tstack);
[408]754
[410]755        void EvaluateLeafStats(const TraversalData &data);
[405]756
757
[418]758        int     GetRootPvsSize() const;
[408]759       
[462]760        int     GetPvsSize(VspKdNode *node, const AxisAlignedBox3 &box) const;
[405]761
[410]762        void GetRayContributionStatistics(float &minRayContribution,
763                                                                          float &maxRayContribution,
764                                                                          float &avgRayContribution);
[405]765
[410]766        int GenerateRays(const float ratioPerLeaf,
767                                         SimpleRayContainer &rays);
[405]768
[425]769        /** Collapses this subtree and releases the memory.
770                @returns number of collapsed rays.
771        */
[462]772        int CollapseSubtree(VspKdNode *sroot, const int time);
[418]773       
[419]774        int ReleaseMemory(const int time);
775
[462]776        bool TerminationCriteriaMet(const VspKdLeaf *leaf,
[421]777                                                                const AxisAlignedBox3 &box) const;
778
[425]779        /** Computes PVS size of this node given a global ray set.
780                @returns PVS size of the intersection of this node bounding box with the rays.
781        */
[462]782        int ComputePvsSize(VspKdNode *node,
783                                           const RayInfoContainer &globalRays) const;
[425]784
[462]785
786        /** Generates view cell for this leaf taking the ray contributions.
787        */
788        void GenerateViewCell(VspKdLeaf *leaf);
789
790        /** Merges view cells of the two leaves.
791        */
792        bool MergeViewCells(VspKdLeaf *l1, VspKdLeaf *l2);
793       
[465]794        /** Helper function revalidating the view cell leaf list after merge.
795        */
[517]796        void RepairViewCellsLeafLists();
[465]797
[486]798        /** Shuffles the leaves, i.e., tests if exchanging
799                the view cells the leaves belong to helps in improving the view cells.
800        */
801        bool ShuffleLeaves(VspKdLeaf *leaf1, VspKdLeaf *leaf2) const;
802
803        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
804                to view cell 2.
805        */
806        void ShuffleLeaf(VspKdLeaf *leaf,
807                                         VspKdViewCell *vc1,
808                                         VspKdViewCell *vc2) const;
[418]809protected:
[452]810       
811
[418]812        /////////////////////////////
813        // The core pointer
[462]814        VspKdNode *mRoot;
[418]815 
816        /////////////////////////////
817        // Basic properties
818
819        // total number of nodes of the tree
[422]820        int mNumNodes;
[418]821       
822        // axis aligned bounding box of the scene
823        AxisAlignedBox3 mBox;
824
825        // epsilon used for the construction
[422]826        float mEpsilon;
[418]827
828        // ratio between traversal and intersection costs
[422]829        float mCtDivCi;
[418]830       
831        // type of the splitting to use for the tree construction
[462]832        enum {ESplitRegular, ESplitHeuristic};
[418]833        int splitType;
834       
835        // maximum alovable memory in MB
[422]836        float mMaxTotalMemory;
[418]837
838        // maximum alovable memory for static kd tree in MB
[422]839        float mMaxStaticMemory;
[418]840
841        // this is used during the construction depending
842        // on the type of the tree and queries...
[422]843        float mMaxMemory;
[418]844
845        // minimal acess time for collapse
[422]846        int mAccessTimeThreshold;
[418]847
848        // minimal depth at which to perform collapse
[422]849        int mMinCollapseDepth;
[418]850       
851        // reusable array of split candidates
[422]852        vector<SortableEntry> *mSplitCandidates;
[418]853       
[462]854        ViewCellsManager *mViewCellsManager;
855
[580]856        priority_queue<VspKdMergeCandidate> mMergeQueue;
[483]857
858
[418]859        /////////////////////////////
[421]860        // Construction parameters
861
862        /// max depth of the tree
863        int mTermMaxDepth;
864        /// minimal ratio of the volume of the cell and the query volume
865        float mTermMinSize;
866        /// minimal pvs per node to still get subdivided
867        int mTermMinPvs;
868        /// minimal ray number per node to still get subdivided
869        int mTermMinRays;
[472]870        /// maximal acceptable cost ratio to continue subdivision
[421]871        float mTermMaxCostRatio;
872        /// maximal contribution per ray to subdivide the node
873        float mTermMaxRayContribution;
[472]874        /// tolerance value indicating how often the max cost ratio can be failed
875        int mTermMissTolerance;
[421]876
[462]877        /// maximal numbers of view cells
878        int mMaxViewCells;
[452]879
[472]880        /// maximal cost ratio of a merge
881        float mMergeMaxCostRatio;
882       
[465]883        /// minimal number of view cells
[472]884        int mMergeMinViewCells;
[465]885
[472]886        /// if only the "driving axis", i.e., the axis with the biggest extent
887        /// should be used for subdivision
888        bool mOnlyDrivingAxis;
889
[421]890        /////////////////////////////
[418]891        VspKdStatistics mStat; 
[405]892};
893
[860]894}
[408]895
[462]896#endif // __VSP_KDTREE_H__
[408]897
Note: See TracBrowser for help on using the repository browser.