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

Revision 1012, 20.3 KB checked in by mattausch, 18 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        */
[1004]279        VspKdNode *GetBack() const;
[420]280        /** Returns front child.
281        */
[1004]282        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 () {}
[1012]594                LineTraversalData (VspKdNode *n, const Vector3 &p, const float maxt):
[468]595                mNode(n), mExitPoint(p), mMaxT(maxt) {}
596        };
597
[405]598public:
599
[410]600        VspKdTree();
601        virtual ~VspKdTree();
[405]602
[440]603        virtual void Construct(const VssRayContainer &rays,
[410]604                                                   AxisAlignedBox3 *forcedBoundingBox = NULL);
[420]605
606        /** Returns bounding box of the specified node.
607        */
[462]608        AxisAlignedBox3 GetBBox(VspKdNode *node) const;
[420]609
610        const VspKdStatistics &GetStatistics() const;
611
612        /** Get the root of the tree.
613        */
[462]614        VspKdNode *GetRoot() const;
[420]615
616        /** Returns average PVS size in tree.
617        */
618        float GetAvgPvsSize();
619
620        /** Returns memory usage in MB.
621        */
622        float GetMemUsage() const;
[485]623        //?
[420]624        float GetRayMemUsage() const;
625
[428]626        /** Collects leaves of this tree.
627        */
[462]628        void CollectLeaves(vector<VspKdLeaf *> &leaves) const;
[428]629
[485]630        /** Merges view cells created with this tree according to
631                some (global) cost heuristics.
[452]632        */
[485]633        int MergeViewCells(const VssRayContainer &rays);
[452]634
635        /** Finds neighbours of this node.
636                @param n the input node
637                @param neighbours the neighbors of the input node
638                @param onlyUnmailed if only unmailed neighbors are collected
639        */
[462]640        int FindNeighbors(VspKdLeaf *n,
641                                          vector<VspKdLeaf *> &neighbors,
[452]642                                          bool onlyUnmailed);
643
[462]644       
645        /** Sets pointer to view cells manager.
646        */
647        void SetViewCellsManager(ViewCellsManager *vcm);
648
[463]649        /** A ray is cast possible intersecting the tree.
650                @param the ray that is cast.
651                @returns the number of intersections with objects stored in the tree.
652        */
[468]653        int CastLineSegment(const Vector3 &origin,
654                                                const Vector3 &termination,
655                                                vector<ViewCell *> &viewcells);
[462]656
657        /** Collects view cells generated by this tree.
658        */
659        void CollectViewCells(ViewCellContainer &viewCells) const;
[486]660       
661        /** Refines view cells using shuffling, i.e., border leaves
662                of two view cells are exchanged if the resulting view cells
663                are tested to be "better" than the old ones.
664                @returns number of refined view cells
[473]665        */
[486]666        int RefineViewCells(const VssRayContainer &rays);
[473]667
[483]668        /** Collects candidates for the merge in the merge queue.
669        */
670        void CollectMergeCandidates();
671
[485]672        /** Collapses the tree with respect to the view cell partition.
[501]673                @returns number of collapsed nodes
[485]674        */
[501]675        int CollapseTree();
[485]676
[420]677protected:
[428]678
[501]679        /** Collapses the tree with respect to the view cell partition,
680                i.e. leaves having the same view cell are collapsed.
681                @param node the root of the subtree to be collapsed
682                @param collapsed returns the number of collapsed nodes
[495]683                @returns node of type leaf if the node could be collapsed,
684                this node otherwise
685        */
[501]686        VspKdNode *CollapseTree(VspKdNode *node, int &collapsed);
687
[420]688        // incremental construction
[410]689        virtual void UpdateRays(VssRayContainer &remove, VssRayContainer &add);
[405]690
[420]691        virtual void AddRays(VssRayContainer &add);
[405]692
[462]693        VspKdNode *Locate(const Vector3 &v);
[408]694       
[462]695        VspKdNode *SubdivideNode(VspKdLeaf *leaf,
[410]696                                                                 const AxisAlignedBox3 &box,
697                                                                 AxisAlignedBox3 &backBox,
698                                                                 AxisAlignedBox3 &frontBox);
[408]699       
[462]700        VspKdNode *Subdivide(const TraversalData &tdata);
[408]701       
[462]702        int SelectPlane(VspKdLeaf *leaf,
[410]703                                        const AxisAlignedBox3 &box,
704                                        float &position,
705                                        int &raysBack,
706                                        int &raysFront,
707                                        int &pvsBack,
708                                        int &pvsFront);
[405]709
[462]710        void SortSplitCandidates(VspKdLeaf *node,
[420]711                                                         const int axis);       
[408]712 
[462]713        float BestCostRatioHeuristic(VspKdLeaf *node,
[480]714                                                                 const AxisAlignedBox3 &box,
[410]715                                                                 int &axis,
716                                                                 float &position,
717                                                                 int &raysBack,
718                                                                 int &raysFront,
719                                                                 int &pvsBack,
720                                                                 int &pvsFront);
[405]721
[480]722        float BestCostRatioRegular(VspKdLeaf *node,
723                                                           const AxisAlignedBox3 &box,
[410]724                                                           int &axis,
725                                                           float &position,
726                                                           int &raysBack,
727                                                           int &raysFront,
728                                                           int &pvsBack,
729                                                           int &pvsFront);
[408]730       
[462]731        float EvalCostRatio(VspKdLeaf *node,
[480]732                                                const AxisAlignedBox3 &box,
[410]733                                                const int axis,
734                                                const float position,
735                                                int &raysBack,
736                                                int &raysFront,
737                                                int &pvsBack,
738                                                int &pvsFront);
[405]739
740
[462]741        VspKdNode * SubdivideLeaf(VspKdLeaf *leaf,
[410]742                                                                  const float SAThreshold);
[405]743
[410]744        void RemoveRay(VssRay *ray,
[462]745                                   vector<VspKdLeaf *> *affectedLeaves,
[410]746                                   const bool removeAllScheduledRays);
[405]747
[410]748        void AddRay(VssRay *ray);
[408]749       
[410]750        void TraverseInternalNode(RayTraversalData &data,
751                                                         stack<RayTraversalData> &tstack);
[408]752
[410]753        void EvaluateLeafStats(const TraversalData &data);
[405]754
755
[418]756        int     GetRootPvsSize() const;
[408]757       
[462]758        int     GetPvsSize(VspKdNode *node, const AxisAlignedBox3 &box) const;
[405]759
[410]760        void GetRayContributionStatistics(float &minRayContribution,
761                                                                          float &maxRayContribution,
762                                                                          float &avgRayContribution);
[405]763
[410]764        int GenerateRays(const float ratioPerLeaf,
765                                         SimpleRayContainer &rays);
[405]766
[425]767        /** Collapses this subtree and releases the memory.
768                @returns number of collapsed rays.
769        */
[462]770        int CollapseSubtree(VspKdNode *sroot, const int time);
[418]771       
[419]772        int ReleaseMemory(const int time);
773
[462]774        bool TerminationCriteriaMet(const VspKdLeaf *leaf,
[421]775                                                                const AxisAlignedBox3 &box) const;
776
[425]777        /** Computes PVS size of this node given a global ray set.
778                @returns PVS size of the intersection of this node bounding box with the rays.
779        */
[462]780        int ComputePvsSize(VspKdNode *node,
781                                           const RayInfoContainer &globalRays) const;
[425]782
[462]783
784        /** Generates view cell for this leaf taking the ray contributions.
785        */
786        void GenerateViewCell(VspKdLeaf *leaf);
787
788        /** Merges view cells of the two leaves.
789        */
790        bool MergeViewCells(VspKdLeaf *l1, VspKdLeaf *l2);
791       
[465]792        /** Helper function revalidating the view cell leaf list after merge.
793        */
[517]794        void RepairViewCellsLeafLists();
[465]795
[486]796        /** Shuffles the leaves, i.e., tests if exchanging
797                the view cells the leaves belong to helps in improving the view cells.
798        */
799        bool ShuffleLeaves(VspKdLeaf *leaf1, VspKdLeaf *leaf2) const;
800
801        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
802                to view cell 2.
803        */
804        void ShuffleLeaf(VspKdLeaf *leaf,
805                                         VspKdViewCell *vc1,
806                                         VspKdViewCell *vc2) const;
[418]807protected:
[452]808       
809
[418]810        /////////////////////////////
811        // The core pointer
[462]812        VspKdNode *mRoot;
[418]813 
814        /////////////////////////////
815        // Basic properties
816
817        // total number of nodes of the tree
[422]818        int mNumNodes;
[418]819       
820        // axis aligned bounding box of the scene
821        AxisAlignedBox3 mBox;
822
823        // epsilon used for the construction
[422]824        float mEpsilon;
[418]825
826        // ratio between traversal and intersection costs
[422]827        float mCtDivCi;
[418]828       
829        // type of the splitting to use for the tree construction
[462]830        enum {ESplitRegular, ESplitHeuristic};
[418]831        int splitType;
832       
833        // maximum alovable memory in MB
[422]834        float mMaxTotalMemory;
[418]835
836        // maximum alovable memory for static kd tree in MB
[422]837        float mMaxStaticMemory;
[418]838
839        // this is used during the construction depending
840        // on the type of the tree and queries...
[422]841        float mMaxMemory;
[418]842
843        // minimal acess time for collapse
[422]844        int mAccessTimeThreshold;
[418]845
846        // minimal depth at which to perform collapse
[422]847        int mMinCollapseDepth;
[418]848       
849        // reusable array of split candidates
[422]850        vector<SortableEntry> *mSplitCandidates;
[418]851       
[462]852        ViewCellsManager *mViewCellsManager;
853
[580]854        priority_queue<VspKdMergeCandidate> mMergeQueue;
[483]855
856
[418]857        /////////////////////////////
[421]858        // Construction parameters
859
860        /// max depth of the tree
861        int mTermMaxDepth;
862        /// minimal ratio of the volume of the cell and the query volume
863        float mTermMinSize;
864        /// minimal pvs per node to still get subdivided
865        int mTermMinPvs;
866        /// minimal ray number per node to still get subdivided
867        int mTermMinRays;
[472]868        /// maximal acceptable cost ratio to continue subdivision
[421]869        float mTermMaxCostRatio;
870        /// maximal contribution per ray to subdivide the node
871        float mTermMaxRayContribution;
[472]872        /// tolerance value indicating how often the max cost ratio can be failed
873        int mTermMissTolerance;
[421]874
[462]875        /// maximal numbers of view cells
876        int mMaxViewCells;
[452]877
[472]878        /// maximal cost ratio of a merge
879        float mMergeMaxCostRatio;
880       
[465]881        /// minimal number of view cells
[472]882        int mMergeMinViewCells;
[465]883
[472]884        /// if only the "driving axis", i.e., the axis with the biggest extent
885        /// should be used for subdivision
886        bool mOnlyDrivingAxis;
887
[421]888        /////////////////////////////
[418]889        VspKdStatistics mStat; 
[405]890};
891
[860]892}
[408]893
[462]894#endif // __VSP_KDTREE_H__
[408]895
Note: See TracBrowser for help on using the repository browser.