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

Revision 483, 18.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
[420]205        enum {EInterior, ELeaf};
[405]206
[420]207        /** Constructs new interior node from the parent node.
208        */
[462]209        inline VspKdNode(VspKdInterior *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.
228        */
229        virtual int GetAccessTime(); // NOTE: don't really know how it is used!
[405]230
[420]231        /** Returns parent node.
232        */
[462]233        VspKdInterior *GetParent() const;
[426]234
[420]235        /** Sets parent node.
236        */
[462]237        void SetParent(VspKdInterior *p);
[408]238
[420]239protected:
240        /////////////////////////////////
241        // The actual data goes here
[408]242 
[420]243        /// link to the parent
[462]244        VspKdInterior *mParent;
[405]245
[482]246        enum {SPLIT_X = 0, SPLIT_Y, SPLIT_Z};
[408]247 
[420]248        /// splitting axis
249        char mAxis;
[408]250       
[420]251        /// depth
252        unsigned char mDepth;
[405]253};
[408]254
255// --------------------------------------------------------------
256// KD-tree node - interior node
257// --------------------------------------------------------------
[462]258class VspKdInterior: public VspKdNode
[408]259{
260public:
[419]261        friend class VspKdTree;
262
[420]263        /** Constructs new interior node from parent node.
264        */
[462]265        VspKdInterior(VspKdInterior *p);
[418]266                       
267        virtual int GetAccessTime();
268       
[419]269        virtual int Type() const;
[405]270 
[462]271        virtual ~VspKdInterior();
[418]272   
273        virtual void Print(ostream &s) const;
[408]274
[420]275        /** Returns back child.
276        */
[462]277        inline VspKdNode *GetBack() const;
[420]278        /** Returns front child.
279        */
[462]280        inline VspKdNode *GetFront() const;
[419]281
[418]282protected:
[408]283
[420]284        /** Sets pointers to back child and front child.
285        */
[462]286        void SetupChildLinks(VspKdNode *b, VspKdNode *f);
[420]287
288        /** Replaces the pointer to oldChild with a pointer to newChild.
289        */
[462]290        void ReplaceChildLink(VspKdNode *oldChild, VspKdNode *newChild);
[418]291 
[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
312// --------------------------------------------------------------
313// KD-tree node - leaf node
314// --------------------------------------------------------------
[462]315class VspKdLeaf: public VspKdNode
[408]316{
317public:
[465]318
[419]319        friend class VspKdTree;
320
[420]321        /** Constructs leaf from parent node.
322                @param p the parent node
323                @param nRays preallocates memory to store this number of rays
[472]324                @parma maxMisses how many times the max cost ratio was missed on the path to the leaf
[420]325        */
[472]326        VspKdLeaf(VspKdInterior *p,     const int nRays, const int maxCostMisses = 0);
[408]327       
[462]328        virtual ~VspKdLeaf();
[405]329
[420]330        virtual int Type() const; 
[408]331
[420]332        virtual void Print(ostream &s) const;
[405]333 
[420]334        /** Adds a ray to the leaf ray container.
335        */
336        void AddRay(const RayInfo &data);
337        /** Returns size of the leaf PVS as induced by the rays
338                @note returns precomputed PVS size, which may not be valid
339                anymore. Run UpdatePvsSize to get a valid PVS.
340        */
341        int GetPvsSize() const;
[405]342
[420]343        /** If PVS is not valid, this function recomputes the leaf
344                PVS as induced by the rays.
345        */
[410]346        void UpdatePvsSize();
[408]347
[428]348        /** Returns stored rays.
349        */
[426]350        RayInfoContainer &GetRays();
351
[428]352        /** Returns rays into this ray container.
353        */
354        void GetRays(VssRayContainer &rays);
[420]355        /** Returns average contribution of a ray to the PVS
356        */
357        inline float GetAvgRayContribution() const;
358        /** Returns square of average contribution of a ray.
359        */
360        inline float GetSqrRayContribution() const;
[408]361
[428]362        /** Extracts PVS from ray set.
363        */
364        void ExtractPvs(ObjectContainer &objects) const;
365
[422]366        //-- mailing options
367        void Mail();
368
369        bool Mailed() const;
370 
[462]371        /** Returns true if mail equals the leaf mail box.
372        */
373        bool Mailed(const int mail) const;
[422]374
[462]375        void SetViewCell(VspKdViewCell *viewCell);
[420]376
[462]377        /** Returns mail box of this leaf.
378        */
379        int GetMailbox() const;
[420]380
[462]381        /** Returns view cell associated with this leaf.
[453]382        */
[462]383        VspKdViewCell *GetViewCell();
[453]384
[472]385        /** Returns number of times the max cost ratio was missed until
386                this leaf.
387        */
388        int GetMaxCostMisses();
389
390
[462]391        ////////////////////////////////////////////
392       
393        static void NewMail();
394
395        static int sMailId;
396
[472]397       
[420]398protected:
[426]399
400        /** Manually sets PVS size.
401                @param s the PVS size
402        */
403        void SetPvsSize(const int s);
404
[420]405        int mMailbox;
406 
[472]407        /// rays intersecting this leaf.
[420]408        RayInfoContainer mRays;
[462]409        /// true if mPvsSize is valid => PVS does not have to be updated
[420]410        bool mValidPvs;
[462]411        /// the view cell associated with this leaf
412        VspKdViewCell *mViewCell;
[472]413        /// number of times the max cost ratio was missed on the way to the leaf.
414        int mMaxCostMisses;
[462]415
[419]416private:
[462]417        /// stores PVS size so we have to evaluate PVS size only once
[419]418        int mPvsSize;
[405]419};
420
421
422
[408]423// ---------------------------------------------------------------
424// Main LSDS search class
425// ---------------------------------------------------------------
426class VspKdTree
427{
[411]428        // --------------------------------------------------------------
429        // For sorting rays
430        // -------------------------------------------------------------
431        struct SortableEntry
432        {
433                enum EType
434                {
435                        ERayMin,
436                        ERayMax
437                };
438
439                int type;
440                float value;
[482]441                VssRay *ray;
[411]442 
443                SortableEntry() {}
[482]444                SortableEntry(const int t, const float v, VssRay *r): type(t),
445                                          value(v), ray(r)
[411]446                {
447                }
448               
449                friend bool operator<(const SortableEntry &a, const SortableEntry &b)
450                {
451                        return a.value < b.value;
452                }
453        };
454
[410]455        struct TraversalData
456        { 
[462]457                VspKdNode *mNode;
[419]458                AxisAlignedBox3 mBox;
459                int mDepth;
[423]460                //float mPriority;
[410]461       
462                TraversalData() {}
[405]463
[462]464                TraversalData(VspKdNode *n, const float p):
[423]465                mNode(n)//, mPriority(p)
[410]466                {}
[408]467
[462]468                TraversalData(VspKdNode *n,     const AxisAlignedBox3 &b, const int d):
[419]469                mNode(n), mBox(b), mDepth(d) {}
[405]470   
[423]471                // comparator for the priority queue
472                /*struct less_priority : public binary_function<const TraversalData, const TraversalData, bool>
[410]473                {
[423]474                        bool operator()(const TraversalData a, const TraversalData b) {                 
475                        return a.mPriority < b.mPriority;               }       };*/
[405]476
[410]477                //    ~TraversalData() {}
478                //    TraversalData(const TraversalData &s):node(s.node), bbox(s.bbox), depth(s.depth) {}
[408]479   
[472]480        friend bool operator<(const TraversalData &a, const TraversalData &b)
[410]481                {
482                        // return a.node->queries.size() < b.node->queries.size();
[462]483                        VspKdLeaf *leafa = (VspKdLeaf *) a.mNode;
484                        VspKdLeaf *leafb = (VspKdLeaf *) b.mNode;
[408]485#if 0
486                        return
[474]487                                leafa->rays.size() * a.mBox.GetVolume()
[408]488                                <
[474]489                                leafb->rays.size() * b.mBox.GetVolume();
[408]490#endif
491#if 1
492                        return
[474]493                                leafa->GetPvsSize() * a.mBox.GetVolume()
[408]494                                <
[474]495                                leafb->GetPvsSize() * b.mBox.GetVolume();
[408]496#endif
497#if 0
498                        return
499                                leafa->GetPvsSize()
500                                <
501                                leafb->GetPvsSize();
502#endif
503#if 0
504                        return
[423]505                                leafa->GetPvsSize() / (float)(leafa->rays.size() + Limits::Small())
[408]506                                >
[423]507                                leafb->GetPvsSize() / (float)(leafb->rays.size() + Limits::Small());
[408]508#endif
509#if 0
510                        return
[410]511                                leafa->GetPvsSize() * (float)leafa->rays.size()
[408]512                                <
[410]513                                leafb->GetPvsSize() * (float)leafb->rays.size();
[408]514#endif
[468]515                }
516        };
[405]517 
[468]518        /** Simplified data for ray traversal only.
519        */
520        struct RayTraversalData
521        {
522                RayInfo mRayData;
523                VspKdNode *mNode;
524
525                RayTraversalData() {}
[410]526         
[468]527                RayTraversalData(VspKdNode *n, const RayInfo &data):
528                mRayData(data), mNode(n) {}
529        };
[408]530       
[483]531        struct LineTraversalData
[468]532        {
533                VspKdNode *mNode;
534                Vector3 mExitPoint;
535               
536                float mMaxT;
537   
[483]538                LineTraversalData () {}
539                LineTraversalData (VspKdNode *n,
[468]540                                                                  const Vector3 &p,
541                                                                  const float maxt):
542                mNode(n), mExitPoint(p), mMaxT(maxt) {}
543        };
544
[405]545public:
546
[410]547        VspKdTree();
548        virtual ~VspKdTree();
[405]549
[440]550        virtual void Construct(const VssRayContainer &rays,
[410]551                                                   AxisAlignedBox3 *forcedBoundingBox = NULL);
[420]552
553        /** Returns bounding box of the specified node.
554        */
[462]555        AxisAlignedBox3 GetBBox(VspKdNode *node) const;
[420]556
557        const VspKdStatistics &GetStatistics() const;
558
559        /** Get the root of the tree.
560        */
[462]561        VspKdNode *GetRoot() const;
[420]562
563        /** Returns average PVS size in tree.
564        */
565        float GetAvgPvsSize();
566
567        /** Returns memory usage in MB.
568        */
569        float GetMemUsage() const;
570       
571        float GetRayMemUsage() const;
572
[428]573        /** Collects leaves of this tree.
574        */
[462]575        void CollectLeaves(vector<VspKdLeaf *> &leaves) const;
[428]576
[452]577        /** Merges leaves of this tree according to some criteria.
578        */
[462]579        int MergeLeaves();
[452]580
581        /** Finds neighbours of this node.
582                @param n the input node
583                @param neighbours the neighbors of the input node
584                @param onlyUnmailed if only unmailed neighbors are collected
585        */
[462]586        int FindNeighbors(VspKdLeaf *n,
587                                          vector<VspKdLeaf *> &neighbors,
[452]588                                          bool onlyUnmailed);
589
[462]590       
591        /** Sets pointer to view cells manager.
592        */
593        void SetViewCellsManager(ViewCellsManager *vcm);
594
[463]595        /** A ray is cast possible intersecting the tree.
596                @param the ray that is cast.
597                @returns the number of intersections with objects stored in the tree.
598        */
[468]599        int CastLineSegment(const Vector3 &origin,
600                                                const Vector3 &termination,
601                                                vector<ViewCell *> &viewcells);
[462]602
603        /** Collects view cells generated by this tree.
604        */
605        void CollectViewCells(ViewCellContainer &viewCells) const;
606
[473]607        /** Refines view cells in a post processing step.
608        */
609        void RefineViewCells();
610
[483]611        /** Collects candidates for the merge in the merge queue.
612        */
613        void CollectMergeCandidates();
614
[420]615protected:
[428]616
[420]617        // incremental construction
[410]618        virtual void UpdateRays(VssRayContainer &remove, VssRayContainer &add);
[405]619
[420]620        virtual void AddRays(VssRayContainer &add);
[405]621
[462]622        VspKdNode *Locate(const Vector3 &v);
[408]623       
[462]624        VspKdNode *SubdivideNode(VspKdLeaf *leaf,
[410]625                                                                 const AxisAlignedBox3 &box,
626                                                                 AxisAlignedBox3 &backBox,
627                                                                 AxisAlignedBox3 &frontBox);
[408]628       
[462]629        VspKdNode *Subdivide(const TraversalData &tdata);
[408]630       
[462]631        int SelectPlane(VspKdLeaf *leaf,
[410]632                                        const AxisAlignedBox3 &box,
633                                        float &position,
634                                        int &raysBack,
635                                        int &raysFront,
636                                        int &pvsBack,
637                                        int &pvsFront);
[405]638
[462]639        void SortSplitCandidates(VspKdLeaf *node,
[420]640                                                         const int axis);       
[408]641 
[462]642        float BestCostRatioHeuristic(VspKdLeaf *node,
[480]643                                                                 const AxisAlignedBox3 &box,
[410]644                                                                 int &axis,
645                                                                 float &position,
646                                                                 int &raysBack,
647                                                                 int &raysFront,
648                                                                 int &pvsBack,
649                                                                 int &pvsFront);
[405]650
[480]651        float BestCostRatioRegular(VspKdLeaf *node,
652                                                           const AxisAlignedBox3 &box,
[410]653                                                           int &axis,
654                                                           float &position,
655                                                           int &raysBack,
656                                                           int &raysFront,
657                                                           int &pvsBack,
658                                                           int &pvsFront);
[408]659       
[462]660        float EvalCostRatio(VspKdLeaf *node,
[480]661                                                const AxisAlignedBox3 &box,
[410]662                                                const int axis,
663                                                const float position,
664                                                int &raysBack,
665                                                int &raysFront,
666                                                int &pvsBack,
667                                                int &pvsFront);
[405]668
669
[462]670        VspKdNode * SubdivideLeaf(VspKdLeaf *leaf,
[410]671                                                                  const float SAThreshold);
[405]672
[410]673        void RemoveRay(VssRay *ray,
[462]674                                   vector<VspKdLeaf *> *affectedLeaves,
[410]675                                   const bool removeAllScheduledRays);
[405]676
[410]677        void AddRay(VssRay *ray);
[408]678       
[410]679        void TraverseInternalNode(RayTraversalData &data,
680                                                         stack<RayTraversalData> &tstack);
[408]681
[410]682        void EvaluateLeafStats(const TraversalData &data);
[405]683
684
[418]685        int     GetRootPvsSize() const;
[408]686       
[462]687        int     GetPvsSize(VspKdNode *node, const AxisAlignedBox3 &box) const;
[405]688
[410]689        void GetRayContributionStatistics(float &minRayContribution,
690                                                                          float &maxRayContribution,
691                                                                          float &avgRayContribution);
[405]692
[410]693        int GenerateRays(const float ratioPerLeaf,
694                                         SimpleRayContainer &rays);
[405]695
[425]696        /** Collapses this subtree and releases the memory.
697                @returns number of collapsed rays.
698        */
[462]699        int CollapseSubtree(VspKdNode *sroot, const int time);
[418]700       
[419]701        int ReleaseMemory(const int time);
702
[462]703        bool TerminationCriteriaMet(const VspKdLeaf *leaf,
[421]704                                                                const AxisAlignedBox3 &box) const;
705
[425]706        /** Computes PVS size of this node given a global ray set.
707                @returns PVS size of the intersection of this node bounding box with the rays.
708        */
[462]709        int ComputePvsSize(VspKdNode *node,
710                                           const RayInfoContainer &globalRays) const;
[425]711
[462]712
713        /** Generates view cell for this leaf taking the ray contributions.
714        */
715        void GenerateViewCell(VspKdLeaf *leaf);
716
717        /** Merges view cells of the two leaves.
718        */
719        bool MergeViewCells(VspKdLeaf *l1, VspKdLeaf *l2);
720
[465]721        /** Collapses the tree with respect to the view cell partition.
722                @returns node of type leaf if the node could be collapsed, this node otherwise
723        */
724        VspKdNode *CollapseTree(VspKdNode *node);
[462]725       
[465]726        /** Helper function revalidating the view cell leaf list after merge.
727        */
[479]728        void RepairVcLeafLists();
[465]729
[418]730protected:
[452]731       
732
[418]733        /////////////////////////////
734        // The core pointer
[462]735        VspKdNode *mRoot;
[418]736 
737        /////////////////////////////
738        // Basic properties
739
740        // total number of nodes of the tree
[422]741        int mNumNodes;
[418]742       
743        // axis aligned bounding box of the scene
744        AxisAlignedBox3 mBox;
745
746        // epsilon used for the construction
[422]747        float mEpsilon;
[418]748
749        // ratio between traversal and intersection costs
[422]750        float mCtDivCi;
[418]751       
752        // type of the splitting to use for the tree construction
[462]753        enum {ESplitRegular, ESplitHeuristic};
[418]754        int splitType;
755       
756        // maximum alovable memory in MB
[422]757        float mMaxTotalMemory;
[418]758
759        // maximum alovable memory for static kd tree in MB
[422]760        float mMaxStaticMemory;
[418]761
762        // this is used during the construction depending
763        // on the type of the tree and queries...
[422]764        float mMaxMemory;
[418]765
766        // minimal acess time for collapse
[422]767        int mAccessTimeThreshold;
[418]768
769        // minimal depth at which to perform collapse
[422]770        int mMinCollapseDepth;
[418]771       
772        // reusable array of split candidates
[422]773        vector<SortableEntry> *mSplitCandidates;
[418]774       
[462]775        ViewCellsManager *mViewCellsManager;
776
[483]777        priority_queue<MergeCandidate> mMergeQueue;
778
779
[418]780        /////////////////////////////
[421]781        // Construction parameters
782
783        /// max depth of the tree
784        int mTermMaxDepth;
785        /// minimal ratio of the volume of the cell and the query volume
786        float mTermMinSize;
787        /// minimal pvs per node to still get subdivided
788        int mTermMinPvs;
789        /// minimal ray number per node to still get subdivided
790        int mTermMinRays;
[472]791        /// maximal acceptable cost ratio to continue subdivision
[421]792        float mTermMaxCostRatio;
793        /// maximal contribution per ray to subdivide the node
794        float mTermMaxRayContribution;
[472]795        /// tolerance value indicating how often the max cost ratio can be failed
796        int mTermMissTolerance;
[421]797
[462]798        /// maximal numbers of view cells
799        int mMaxViewCells;
[452]800
[472]801        /// maximal cost ratio of a merge
802        float mMergeMaxCostRatio;
803       
[465]804        /// minimal number of view cells
[472]805        int mMergeMinViewCells;
[465]806
[472]807        /// if only the "driving axis", i.e., the axis with the biggest extent
808        /// should be used for subdivision
809        bool mOnlyDrivingAxis;
810
[421]811        /////////////////////////////
[418]812        VspKdStatistics mStat; 
[405]813};
814
[408]815
[462]816#endif // __VSP_KDTREE_H__
[408]817
Note: See TracBrowser for help on using the repository browser.