source: trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h @ 517

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