source: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h @ 1099

Revision 1099, 42.1 KB checked in by mattausch, 18 years ago (diff)
Line 
1#ifndef _VspOspTree_H__
2#define _VspOspTree_H__
3
4#include <stack>
5
6#include "Mesh.h"
7#include "Containers.h"
8#include "Statistics.h"
9#include "VssRay.h"
10#include "RayInfo.h"
11#include "gzstream.h"
12#include "FlexibleHeap.h"
13
14
15namespace GtpVisibilityPreprocessor {
16
17class ViewCellLeaf;
18//class VspViewCell;
19class Plane3;
20class AxisAlignedBox3;
21class Ray;
22class ViewCellsStatistics;
23class ViewCellsManager;
24class MergeCandidate;
25class Beam;
26class ViewCellsTree;
27class Environment;
28class VspInterior;
29class VspLeaf;
30class VspNode;
31class KdNode;
32class KdInterior;
33class KdLeaf;
34
35class KdTreeStatistics;
36
37template <typename T> class GtPriority
38{
39public:
40        bool operator() (const T c1, const T c2) const
41        {
42                //return false;
43                return c1->GetPriority() < c2->GetPriority();
44        }
45};
46
47
48/** Candidate for a view space / object space split.
49*/
50class SplitCandidate: public Heapable
51
52public:
53
54        enum {OBJECT_SPACE, VIEW_SPACE};
55
56        /// the current split plane
57        AxisAlignedPlane mSplitPlane;
58        /// split axis of this plane (0, 1, 2, or 3 if non-axis-aligned)
59        int mSplitAxis;
60        /// the number of misses of max cost ratio until this split
61        int mMaxCostMisses;
62
63        /// priority of this split
64        //float mPriority;
65       
66        SplitCandidate()
67        {};
68
69        SplitCandidate(const AxisAlignedPlane &plane): mSplitPlane(plane)
70        {}
71
72        virtual void EvalPriority() = 0;
73        virtual int Type() const = 0;
74};
75
76
77/** View space partition statistics.
78*/
79class VspTreeStatistics: public StatisticsBase
80{
81public:
82        // total number of nodes
83        int nodes;
84        // number of splits
85        int splits[3];
86       
87        // totals number of rays
88        int rays;
89        // maximal reached depth
90        int maxDepth;
91        // minimal depth
92        int minDepth;
93       
94        // max depth nodes
95        int maxDepthNodes;
96        // minimum depth nodes
97        int minDepthNodes;
98        // max depth nodes
99        int minPvsNodes;
100        // nodes with minimum PVS
101        int minRaysNodes;
102        // max ray contribution nodes
103        int maxRayContribNodes;
104        // minimum area nodes
105        int minProbabilityNodes;
106        /// nodes termination because of max cost ratio;
107        int maxCostNodes;
108        // max number of rays per node
109        int maxObjectRefs;
110        /// samples contributing to pvs
111        int contributingSamples;
112        /// sample contributions to pvs
113        int sampleContributions;
114        /// largest pvs
115        int maxPvs;
116        /// number of invalid leaves
117        int invalidLeaves;
118        /// accumulated number of rays refs
119        int accumRays;
120        int pvs;
121        // accumulated depth (used to compute average)
122        int accumDepth;
123
124        // Constructor
125        VspTreeStatistics()
126        {
127                Reset();
128        }
129
130        int Nodes() const {return nodes;}
131        int Interior() const { return nodes / 2; }
132        int Leaves() const { return (nodes / 2) + 1; }
133       
134        // TODO: computation wrong
135        double AvgDepth() const { return accumDepth / (double)Leaves();};
136        double AvgRays() const { return accumRays / (double)Leaves();};
137
138        void Reset()
139        {
140                nodes = 0;
141                for (int i = 0; i < 3; ++ i)
142                        splits[i] = 0;
143               
144                maxDepth = 0;
145                minDepth = 99999;
146                accumDepth = 0;
147        pvs = 0;
148                maxDepthNodes = 0;
149                minPvsNodes = 0;
150                minRaysNodes = 0;
151                maxRayContribNodes = 0;
152                minProbabilityNodes = 0;
153                maxCostNodes = 0;
154
155                contributingSamples = 0;
156                sampleContributions = 0;
157
158                maxPvs = 0;
159                invalidLeaves = 0;
160                accumRays = 0;
161        }
162
163        void Print(ostream &app) const;
164
165        friend ostream &operator<<(ostream &s, const VspTreeStatistics &stat)
166        {
167                stat.Print(s);
168                return s;
169        }
170};
171
172
173/** View space partition statistics.
174*/
175class OspTreeStatistics: public StatisticsBase
176{
177public:
178        // total number of nodes
179        int nodes;
180        // number of splits
181        int splits[3];
182       
183        // totals number of rays
184        int rays;
185        // maximal reached depth
186        int maxDepth;
187        // minimal depth
188        int minDepth;
189       
190        // max depth nodes
191        int maxDepthNodes;
192        // minimum depth nodes
193        int minDepthNodes;
194        // max depth nodes
195        int minPvsNodes;
196        // nodes with minimum PVS
197        int minRaysNodes;
198        // max ray contribution nodes
199        int maxRayContribNodes;
200        // minimum area nodes
201        int minProbabilityNodes;
202        /// nodes termination because of max cost ratio;
203        int maxCostNodes;
204        // max number of rays per node
205        int maxObjectRefs;
206        /// samples contributing to pvs
207        int contributingSamples;
208        /// sample contributions to pvs
209        int sampleContributions;
210        /// largest pvs
211        int maxPvs;
212        /// number of invalid leaves
213        int invalidLeaves;
214        /// accumulated number of rays refs
215        int accumRays;
216        int pvs;
217        // accumulated depth (used to compute average)
218        int accumDepth;
219
220        // Constructor
221        OspTreeStatistics()
222        {
223                Reset();
224        }
225
226        int Nodes() const {return nodes;}
227        int Interior() const { return nodes / 2; }
228        int Leaves() const { return (nodes / 2) + 1; }
229       
230        // TODO: computation wrong
231        double AvgDepth() const { return accumDepth / (double)Leaves();};
232        double AvgRays() const { return accumRays / (double)Leaves();};
233
234        void Reset()
235        {
236                nodes = 0;
237                for (int i = 0; i < 3; ++ i)
238                        splits[i] = 0;
239               
240                maxDepth = 0;
241                minDepth = 99999;
242                accumDepth = 0;
243        pvs = 0;
244                maxDepthNodes = 0;
245                minPvsNodes = 0;
246                minRaysNodes = 0;
247                maxRayContribNodes = 0;
248                minProbabilityNodes = 0;
249                maxCostNodes = 0;
250
251                contributingSamples = 0;
252                sampleContributions = 0;
253
254                maxPvs = 0;
255                invalidLeaves = 0;
256                accumRays = 0;
257        }
258
259        void Print(ostream &app) const;
260
261        friend ostream &operator<<(ostream &s, const OspTreeStatistics &stat)
262        {
263                stat.Print(s);
264                return s;
265        }
266};
267
268
269/**
270    VspNode abstract class serving for interior and leaf node implementation
271*/
272class VspNode
273{
274public:
275       
276        // types of vsp nodes
277        enum {Interior, Leaf};
278
279        VspNode();
280        virtual ~VspNode(){};
281        VspNode(VspInterior *parent);
282
283        /** Determines whether this node is a leaf or not
284                @return true if leaf
285        */
286        virtual bool IsLeaf() const = 0;
287
288        virtual int Type() const = 0;
289
290        /** Determines whether this node is a root
291                @return true if root
292        */
293        virtual bool IsRoot() const;
294
295        /** Returns parent node.
296        */
297        VspInterior *GetParent();
298
299        /** Sets parent node.
300        */
301        void SetParent(VspInterior *parent);
302
303        /** Returns true if this node is a sibling of node n.
304        */
305        bool IsSibling(VspNode *n) const;
306
307        /** returns depth of the node.
308        */
309        int GetDepth() const;
310
311        /** returns true if the whole subtree is valid
312        */
313        bool TreeValid() const;
314
315        void SetTreeValid(const bool v);
316
317        //-- mailing options
318
319        void Mail() { mMailbox = sMailId; }
320        static void NewMail() { ++ sMailId; }
321        bool Mailed() const { return mMailbox == sMailId; }
322
323        static int sMailId;
324        int mMailbox;
325
326        int mTimeStamp;
327
328protected:
329
330        /// if this sub tree is a completely valid view space region
331        bool mTreeValid;
332        /// parent of this node
333        VspInterior *mParent;
334};
335
336
337/** BSP interior node implementation
338*/
339class VspInterior: public VspNode
340{
341public:
342        /** Standard contructor taking split plane as argument.
343        */
344        VspInterior(const AxisAlignedPlane &plane);
345
346        ~VspInterior();
347        /** @return false since it is an interior node
348        */
349        bool IsLeaf() const;
350
351        int Type() const;
352
353        VspNode *GetBack();
354        VspNode *GetFront();
355
356        /** Returns split plane.
357        */
358        AxisAlignedPlane GetPlane() const;
359
360        /** Returns position of split plane.
361        */
362        float GetPosition() const;
363
364        /** Returns split axis.
365        */
366        int GetAxis() const;
367
368        /** Replace front or back child with new child.
369        */
370        void ReplaceChildLink(VspNode *oldChild, VspNode *newChild);
371        /** Replace front and back child.
372        */
373        void SetupChildLinks(VspNode *b, VspNode *f);
374
375        friend ostream &operator<<(ostream &s, const VspInterior &A)
376        {
377                return s << A.mPlane.mAxis << " " << A.mPlane.mPosition;
378        }
379
380        AxisAlignedBox3 GetBoundingBox() const;
381        void SetBoundingBox(const AxisAlignedBox3 &box);
382
383        /** Computes intersection of this plane with the ray segment.
384        */
385        int ComputeRayIntersection(const RayInfo &rayData, float &t) const
386        {
387                return rayData.ComputeRayIntersection(mPlane.mAxis, mPlane.mPosition, t);
388        }
389
390
391protected:
392
393        AxisAlignedBox3 mBoundingBox;
394
395        /// Splitting plane corresponding to this node
396        AxisAlignedPlane mPlane;
397
398        /// back node
399        VspNode *mBack;
400        /// front node
401        VspNode *mFront;
402};
403
404
405/** BSP leaf node implementation.
406*/
407class VspLeaf: public VspNode
408{
409
410public:
411        VspLeaf();
412        VspLeaf(ViewCellLeaf *viewCell);
413        VspLeaf(VspInterior *parent);
414        VspLeaf(VspInterior *parent, ViewCellLeaf *viewCell);
415
416        ~VspLeaf();
417
418        /** @return true since it is an interior node
419        */
420        bool IsLeaf() const;
421       
422        int Type() const;
423
424        /** Returns pointer of view cell.
425        */
426        ViewCellLeaf *GetViewCell() const;
427
428        /** Sets pointer to view cell.
429        */
430        void SetViewCell(ViewCellLeaf *viewCell);
431
432        /// Rays piercing this leaf.
433        VssRayContainer mVssRays;
434       
435        /// leaf pvs
436        ObjectPvs *mPvs;
437
438        /// Probability that the view point lies in this leaf
439        float mProbability;
440
441protected:
442       
443        /// if NULL this does not correspond to feasible viewcell
444        ViewCellLeaf *mViewCell;
445};
446
447
448#if 0
449typedef std::priority_queue<SplitCandidate *,
450                                                        std::vector<SplitCandidate *>,
451                                                        GtPriority<std::vector<SplitCandidate *>::value_type> > SplitQueue;
452#endif
453
454typedef FlexibleHeap<SplitCandidate *> SplitQueue;
455
456/** View Space Partitioning tree.
457*/
458class VspTree
459{
460        friend class ViewCellsParseHandlers;
461        friend class HierarchyManager;
462
463public:
464       
465        /** Additional data which is passed down the BSP tree during traversal.
466        */
467        class VspTraversalData
468        { 
469        public:
470                /// the current node
471                VspNode *mNode;
472                /// current depth
473                int mDepth;
474                /// rays piercing this node
475                RayInfoContainer *mRays;
476                /// the probability that this node contains view point
477                float mProbability;
478                /// the bounding box of the node
479                AxisAlignedBox3 mBoundingBox;
480                /// pvs size
481                int mPvs;
482                /// how often this branch has missed the max-cost ratio
483                int mMaxCostMisses;
484                // current priority
485                float mPriority;
486
487               
488                /** Returns average ray contribution.
489                */
490                float GetAvgRayContribution() const
491                {
492                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
493                }
494
495
496                VspTraversalData():
497                mNode(NULL),
498                mDepth(0),
499                mRays(NULL),
500                mPvs(0),
501                mProbability(0.0),
502                mMaxCostMisses(0),
503                mPriority(0)
504                {}
505               
506                VspTraversalData(VspNode *node,
507                                                 const int depth,
508                                                 RayInfoContainer *rays,
509                                                 const int pvs,
510                                                 const float p,
511                                                 const AxisAlignedBox3 &box):
512                mNode(node),
513                mDepth(depth),
514                mRays(rays),
515                mPvs(pvs),
516                mProbability(p),
517                mBoundingBox(box),
518                mMaxCostMisses(0),
519                mPriority(0)
520                {}
521
522                VspTraversalData(const int depth,
523                                                 RayInfoContainer *rays,
524                                                 const AxisAlignedBox3 &box):
525                mNode(NULL),
526                mDepth(depth),
527                mRays(rays),
528                mPvs(0),
529                mProbability(0),
530                mMaxCostMisses(0),
531                mBoundingBox(box)
532                {}
533
534                /** Returns cost of the traversal data.
535                */
536                float GetCost() const
537                {
538                        //cout << mPriority << endl;
539                        return mPriority;
540                }
541
542                // deletes contents and sets them to NULL
543                void Clear()
544                {
545                        DEL_PTR(mRays);
546                }
547
548                friend bool operator<(const VspTraversalData &a, const VspTraversalData &b)
549                {
550                        return a.GetCost() < b.GetCost();
551                }
552    };
553
554        /** Candidate for a view space split.
555        */
556        class VspSplitCandidate: public SplitCandidate
557        { 
558        public:
559                static VspTree* sVspTree;
560                /// parent data
561                VspTraversalData mParentData;
562               
563                VspSplitCandidate(const VspTraversalData &tData): mParentData(tData)
564                {};
565
566                int Type() const { return VIEW_SPACE; }
567
568                void EvalPriority()
569                {
570                        sVspTree->EvalSplitCandidate(*this);   
571                }
572
573                VspSplitCandidate(const AxisAlignedPlane &plane, const VspTraversalData &tData):
574                SplitCandidate(plane), mParentData(tData)
575                {}
576        };
577
578        /** Struct for traversing line segment.
579        */
580        struct LineTraversalData
581        {
582                VspNode *mNode;
583                Vector3 mExitPoint;
584               
585                float mMaxT;
586   
587                LineTraversalData () {}
588                LineTraversalData (VspNode *n, const Vector3 &p, const float maxt):
589                mNode(n), mExitPoint(p), mMaxT(maxt) {}
590        };
591
592        //typedef std::priority_queue<VspTraversalData> VspOspTraversalQueue;
593
594        /** Default constructor creating an empty tree.
595        */
596        VspTree();
597
598        /** Default destructor.
599        */
600        ~VspTree();
601
602        /** Returns BSP Tree statistics.
603        */
604        const VspTreeStatistics &GetStatistics() const;
605 
606        /** Returns bounding box of the specified node.
607        */
608        AxisAlignedBox3 GetBBox(VspNode *node) const;
609
610        /** Returns list of BSP leaves with pvs smaller than
611                a certain threshold.
612                @param onlyUnmailed if only the unmailed leaves should be considered
613                @param maxPvs the maximal pvs of a leaf to be added (-1 means unlimited)
614        */
615        void CollectLeaves(vector<VspLeaf *> &leaves,
616                                           const bool onlyUnmailed = false,
617                                           const int maxPvs = -1) const;
618
619        /** Returns box which bounds the whole tree.
620        */
621        AxisAlignedBox3 GetBoundingBox()const;
622
623        /** Returns root of the view space partitioning tree.
624        */
625        VspNode *GetRoot() const;
626
627        /** Collects the leaf view cells of the tree
628                @param viewCells returns the view cells
629        */
630        void CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const;
631
632        /** A ray is cast possible intersecting the tree.
633                @param the ray that is cast.
634                @returns the number of intersections with objects stored in the tree.
635        */
636        int CastRay(Ray &ray);
637
638
639        /** finds neighbouring leaves of this tree node.
640        */
641        int FindNeighbors(VspLeaf *n,
642                                          vector<VspLeaf *> &neighbors,
643                                          const bool onlyUnmailed) const;
644
645        /** Returns random leaf of BSP tree.
646                @param halfspace defines the halfspace from which the leaf is taken.
647        */
648        VspLeaf *GetRandomLeaf(const Plane3 &halfspace);
649
650        /** Returns random leaf of BSP tree.
651                @param onlyUnmailed if only unmailed leaves should be returned.
652        */
653        VspLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
654
655        /** Returns epsilon of this tree.
656        */
657        float GetEpsilon() const;
658
659        /** Casts line segment into the tree.
660                @param origin the origin of the line segment
661                @param termination the end point of the line segment
662                @returns view cells intersecting the line segment.
663        */
664    int CastLineSegment(const Vector3 &origin,
665                                                const Vector3 &termination,
666                                                ViewCellContainer &viewcells);
667
668               
669        /** Sets pointer to view cells manager.
670        */
671        void SetViewCellsManager(ViewCellsManager *vcm);
672
673        /** Returns view cell the current point is located in.
674                @param point the current view point
675                @param active if currently active view cells should be returned or
676                elementary view cell
677        */
678        ViewCell *GetViewCell(const Vector3 &point, const bool active = false);
679
680
681        /** Returns true if this view point is in a valid view space,
682                false otherwise.
683        */
684        bool ViewPointValid(const Vector3 &viewPoint) const;
685
686        /** Returns view cell corresponding to
687                the invalid view space.
688        */
689        VspViewCell *GetOutOfBoundsCell();
690
691        /** Writes tree to output stream
692        */
693#if ZIPPED_VIEWCELLS
694        bool Export(ogzstream &stream);
695#else
696        bool Export(ofstream &stream);
697#endif
698
699        /** Casts beam, i.e. a 5D frustum of rays, into tree.
700                Tests conservative using the bounding box of the nodes.
701                @returns number of view cells it intersected
702        */
703        int CastBeam(Beam &beam);
704
705
706        /** Checks if tree validity-flags are right
707                with respect to view cell valitiy.
708                If not, marks subtree as invalid.
709        */
710        void ValidateTree();
711
712        /** Invalid view cells are added to the unbounded space
713        */
714        void CollapseViewCells();
715
716        /** Collects rays stored in the leaves.
717        */
718        void CollectRays(VssRayContainer &rays);
719
720        /** Intersects box with the tree and returns the number of intersected boxes.
721                @returns number of view cells found
722        */
723        int ComputeBoxIntersections(const AxisAlignedBox3 &box,
724                                                                ViewCellContainer &viewCells) const;
725
726        /// pointer to the hierarchy of view cells
727        ViewCellsTree *mViewCellsTree;
728
729
730protected:
731
732        // --------------------------------------------------------------
733        // For sorting objects
734        // --------------------------------------------------------------
735        struct SortableEntry
736        {
737                enum EType
738                {
739                        ERayMin,
740                        ERayMax
741                };
742
743                int type;
744                float value;
745                VssRay *ray;
746 
747                SortableEntry() {}
748                SortableEntry(const int t, const float v, VssRay *r):type(t),
749                                          value(v), ray(r)
750                {
751                }
752               
753                friend bool operator<(const SortableEntry &a, const SortableEntry &b)
754                {
755                        return a.value < b.value;
756                }
757        };
758
759        /** faster evaluation of split plane cost for kd axis aligned cells.
760        */
761        float EvalLocalSplitCost(const VspTraversalData &data,
762                                                         const AxisAlignedBox3 &box,
763                                                         const int axis,
764                                                         const float &position,
765                                                         float &pFront,
766                                                         float &pBack) const;
767
768        void PrepareConstruction(const VssRayContainer &sampleRays,
769                                                         AxisAlignedBox3 *forcedBoundingBox);
770
771        /** Evaluates candidate for splitting.
772        */
773        void EvalSplitCandidate(VspSplitCandidate &splitData);
774
775        /** Evaluates render cost decrease of next split.
776        */
777        float EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
778                                                                 const VspTraversalData &data) const;
779
780        /** Collects view cells in the subtree under root.
781        */
782        void CollectViewCells(VspNode *root,
783                                                  bool onlyValid,
784                                                  ViewCellContainer &viewCells,
785                                                  bool onlyUnmailed = false) const;
786
787        /** Returns view cell corresponding to
788                the invalid view space. If it does not exist, it is created.
789        */
790        VspViewCell *GetOrCreateOutOfBoundsCell();
791
792        /** Collapses the tree with respect to the view cell partition,
793                i.e. leaves having the same view cell are collapsed.
794                @param node the root of the subtree to be collapsed
795                @param collapsed returns the number of collapsed nodes
796                @returns node of type leaf if the node could be collapsed,
797                this node otherwise
798        */
799        VspNode *CollapseTree(VspNode *node, int &collapsed);
800
801        /** Helper function revalidating the view cell leaf list after merge.
802        */
803        void RepairViewCellsLeafLists();
804
805        /** Evaluates tree stats in the BSP tree leafs.
806        */
807        void EvaluateLeafStats(const VspTraversalData &data);
808
809        /** Subdivides node using a best split priority queue.
810            @param tQueue the best split priority queue
811                @param splitCandidate the candidate for the next split
812                @param globalCriteriaMet if the global termination criteria were already met
813                @returns new root of the subtree
814        */
815        VspNode *Subdivide(SplitQueue &tQueue,
816                                           VspSplitCandidate &splitCandidate,
817                                           const bool globalCriteriaMet);
818
819        /** Adds stats to subdivision log file.
820        */
821        void AddSubdivisionStats(const int viewCells,
822                                                         const float renderCostDecr,
823                                                         const float splitCandidateCost,
824                                                         const float totalRenderCost,
825                                                         const float avgRenderCost);
826       
827        /** Subdivides leaf.
828                       
829                @param tData data object holding, e.g., a pointer to the leaf
830                @param frontData returns the data (e.g.,  pointer to the leaf) in front of the split plane
831                @param backData returns the data (e.g.,  pointer to the leaf) in the back of the split plane
832               
833                @param rays the polygons to be filtered
834                @param frontRays returns the polygons in front of the split plane
835       
836                @returns the root of the subdivision
837        */
838        VspInterior *SubdivideNode(const AxisAlignedPlane &splitPlane,
839                                                           VspTraversalData &tData,
840                                                           VspTraversalData &frontData,
841                               VspTraversalData &backData);
842
843        /** Selects an axis aligned for the next split.
844                @returns cost for this split
845        */
846        float SelectSplitPlane(const VspTraversalData &tData,
847                                                   AxisAlignedPlane &plane,
848                                                   float &pFront,
849                                                   float &pBack);
850
851        /** Sorts split candidates along the specified axis.
852                The split candidates are generated on possible visibility
853                events (i.e., where ray segments intersect the ray boundaries).
854                The sorted candidates are needed to compute the heuristics.
855
856                @param polys the input for choosing split candidates
857                @param axis the current split axis
858                @param splitCandidates returns sorted list of split candidates
859        */
860        void SortSplitCandidates(const RayInfoContainer &rays,
861                                                         const int axis,
862                                                         float minBand,
863                                                         float maxBand);
864
865        /** Computes pvs increase with respect to the previous pvs for heuristics.
866        */
867        int GetPvsIncr(Intersectable *object, const KdPvsMap &activeNodes);
868
869        /** Returns absolute pvs contribution of this object.
870        */
871        int GetPvsContribution(Intersectable *object) const;
872
873        /** Computes best cost for axis aligned planes.
874        */
875        float EvalLocalCostHeuristics(const RayInfoContainer &rays,
876                                                                  const AxisAlignedBox3 &box,
877                                                                  int pvsSize,
878                                                                  const int axis,
879                                                                  float &position);
880
881        /** Evaluates the influence on the pvs of the visibility event ve.
882                @param ve the visibility event
883                @param pvsLeft updates the left pvs
884                @param rightPvs updates the right pvs
885        */
886        void EvalPvsIncr(const SortableEntry &ve,
887                                          int &pvsLeft,
888                                          int &pvsRight) const;
889
890        void RemoveContriFromPvs(KdLeaf *leaf, int &pvs) const;
891        void AddContriToPvs(KdLeaf *leaf, int &pvs) const;
892
893        /** Prepares objects for the heuristics.
894                @returns pvs size of the ray container
895        */
896        int PrepareHeuristics(const RayInfoContainer &rays);
897
898        int PrepareHeuristics(Intersectable *object);
899
900        /** Subdivides the rays into front and back rays according to the split plane.
901               
902                @param plane the split plane
903                @param rays contains the rays to be split. The rays are
904                           distributed into front and back rays.
905                @param frontRays returns rays on the front side of the plane
906                @param backRays returns rays on the back side of the plane
907               
908                @returns the number of splits
909        */
910        int SplitRays(const AxisAlignedPlane &plane,
911                                  RayInfoContainer &rays,
912                              RayInfoContainer &frontRays,
913                                  RayInfoContainer &backRays) const;
914
915        /** Adds the object to the pvs of the front and back leaf with a given classification.
916
917                @param obj the object to be added
918                @param cf the ray classification regarding the split plane
919                @param frontPvs returns the PVS of the front partition
920                @param backPvs returns the PVS of the back partition
921       
922        */
923        void AddObjToPvs(Intersectable *obj,
924                                         const int cf,
925                                         float &frontPvs,
926                                         float &backPvs,
927                                         float &totalPvs) const;
928       
929        /** Computes PVS size induced by the rays.
930        */
931        int ComputePvsSize(const RayInfoContainer &rays) const;
932       
933        /** Collects pvs from rays.
934        */
935        void CollectPvs(const RayInfoContainer &rays,
936                                        ObjectContainer &objects) const;
937
938        /** Returns true if tree can be terminated.
939        */
940        inline bool LocalTerminationCriteriaMet(const VspTraversalData &data) const;
941
942        /** Returns true if global tree can be terminated.
943        */
944        inline bool GlobalTerminationCriteriaMet(const VspTraversalData &data) const;
945
946        /** Adds ray sample contributions to the PVS.
947                @param sampleContributions the number contributions of the samples
948                @param contributingSampels the number of contributing rays
949               
950        */
951        void AddToPvs(VspLeaf *leaf,
952                                  const RayInfoContainer &rays,
953                                  float &sampleContributions,
954                                  int &contributingSamples);
955
956        /** Propagates valid flag up the tree.
957        */
958        void PropagateUpValidity(VspNode *node);
959
960        /** Writes the node to disk
961                @note: should be implemented as visitor.
962        */
963#if ZIPPED_VIEWCELLS
964        void ExportNode(VspNode *node, ogzstream &stream);
965#else
966        void ExportNode(VspNode *node, ofstream &stream);
967#endif
968
969        /** Returns estimated memory usage of tree.
970        */
971        float GetMemUsage() const;
972
973        void ProcessViewCellObjects(ViewCell *parent, ViewCell *front, ViewCell *back) const;
974
975protected:
976
977        int mPvsCountMethod;
978        enum {PER_OBJECT, PER_KDLEAF};
979
980        ViewCellsManager *mViewCellsManager;
981        vector<SortableEntry> *mSplitCandidates;
982
983        /// Pointer to the root of the tree
984        VspNode *mRoot;
985               
986        VspTreeStatistics mVspStats;
987       
988        /// View cell corresponding to the space outside the valid view space
989        VspViewCell *mOutOfBoundsCell;
990
991        /// box around the whole view domain
992        AxisAlignedBox3 mBoundingBox;
993
994
995
996        //-- local termination
997
998        /// minimal number of rays before subdivision termination
999        int mTermMinRays;
1000        /// maximal possible depth
1001        int mTermMaxDepth;
1002        /// mininum probability
1003        float mTermMinProbability;
1004        /// mininum PVS
1005        int mTermMinPvs;
1006        /// maximal contribution per ray
1007        float mTermMaxRayContribution;
1008        /// maximal acceptable cost ratio
1009        float mTermMaxCostRatio;
1010        /// tolerance value indicating how often the max cost ratio can be failed
1011        int mTermMissTolerance;
1012
1013
1014        //-- global criteria
1015        float mTermMinGlobalCostRatio;
1016        int mTermGlobalCostMissTolerance;
1017        int mGlobalCostMisses;
1018
1019        /// maximal number of view cells
1020        int mMaxViewCells;
1021        /// maximal tree memory
1022        float mMaxMemory;
1023        /// the tree is out of memory
1024        bool mOutOfMemory;
1025
1026
1027
1028        //-- split heuristics based parameters
1029       
1030        bool mUseCostHeuristics;
1031        /// balancing factor for PVS criterium
1032        float mCtDivCi;
1033        /// if only driving axis should be used for split
1034        bool mOnlyDrivingAxis;
1035        /// if random split axis should be used
1036        bool mUseRandomAxis;
1037        /// if vsp bsp tree should simulate octree
1038        bool mCirculatingAxis;
1039        /// minimal relative position where the split axis can be placed
1040        float mMinBand;
1041        /// maximal relative position where the split axis can be placed
1042        float mMaxBand;
1043
1044
1045        /// current time stamp (used for keeping split history)
1046        int mTimeStamp;
1047        // if rays should be stored in leaves
1048        bool mStoreRays;
1049
1050        /// epsilon for geometric comparisons
1051        float mEpsilon;
1052
1053
1054        /// subdivision stats output file
1055        ofstream  mSubdivisionStats;
1056        /// keeps track of cost during subdivision
1057        float mTotalCost;
1058        /// keeps track of overall pvs size during subdivision
1059        int mTotalPvsSize;
1060        /// number of currenly generated view cells
1061        int mCreatedViewCells;
1062
1063private:
1064
1065        /// Generates unique ids for PVS criterium
1066        static void GenerateUniqueIdsForPvs();
1067
1068        //-- unique ids for PVS criterium
1069        static int sFrontId;
1070        static int sBackId;
1071        static int sFrontAndBackId;
1072};
1073
1074
1075/** View Space Partitioning tree.
1076*/
1077class OspTree
1078{
1079        friend class ViewCellsParseHandlers;
1080        friend class HierarchyManager;
1081
1082public:
1083       
1084        /** Additional data which is passed down the BSP tree during traversal.
1085        */
1086        class OspTraversalData
1087        { 
1088        public:
1089                /// the current node
1090                KdNode *mNode;
1091                /// current depth
1092                int mDepth;
1093                /// rays piercing this node
1094                RayInfoContainer *mRays;
1095                /// the probability that this node contains view point
1096                float mProbability;
1097                /// the bounding box of the node
1098                AxisAlignedBox3 mBoundingBox;
1099                /// pvs size
1100                int mPvs;
1101                /// how often this branch has missed the max-cost ratio
1102                int mMaxCostMisses;
1103                // current axis
1104                int mAxis;
1105                // current priority
1106                float mPriority;
1107
1108               
1109                /** Returns average ray contribution.
1110                */
1111                float GetAvgRayContribution() const
1112                {
1113                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
1114                }
1115
1116
1117                OspTraversalData():
1118                mNode(NULL),
1119                mDepth(0),
1120                mRays(NULL),
1121                mPvs(0),
1122                mProbability(0.0),
1123                mMaxCostMisses(0),
1124                mPriority(0),
1125                mAxis(0)
1126                {}
1127               
1128                OspTraversalData(KdNode *node,
1129                                                 const int depth,
1130                                                 RayInfoContainer *rays,
1131                                                 const int pvs,
1132                                                 const float p,
1133                                                 const AxisAlignedBox3 &box):
1134                mNode(node),
1135                mDepth(depth),
1136                mRays(rays),
1137                mPvs(pvs),
1138                mProbability(p),
1139                mBoundingBox(box),
1140                mMaxCostMisses(0),
1141                mPriority(0),
1142                mAxis(0)
1143                {}
1144
1145                OspTraversalData(const int depth,
1146                                                 RayInfoContainer *rays,
1147                                                 const AxisAlignedBox3 &box):
1148                mNode(NULL),
1149                mDepth(depth),
1150                mRays(rays),
1151                mPvs(0),
1152                mProbability(0),
1153                mMaxCostMisses(0),
1154                mAxis(0),
1155                mBoundingBox(box)
1156                {}
1157
1158                /** Returns cost of the traversal data.
1159                */
1160                float GetCost() const
1161                {
1162                        //cout << mPriority << endl;
1163                        return mPriority;
1164                }
1165
1166                // deletes contents and sets them to NULL
1167                void Clear()
1168                {
1169                        DEL_PTR(mRays);
1170                }
1171
1172                friend bool operator<(const OspTraversalData &a, const OspTraversalData &b)
1173                {
1174                        return a.GetCost() < b.GetCost();
1175                }
1176    };
1177
1178        /** Candidate for a view space split.
1179        */
1180        class OspSplitCandidate: public SplitCandidate
1181        { 
1182        public:
1183                static OspTree* sOspTree;
1184
1185                /// parent data
1186                OspTraversalData mParentData;
1187               
1188                OspSplitCandidate(const OspTraversalData &tData): mParentData(tData)
1189                {};
1190
1191                int Type() const { return VIEW_SPACE; }
1192       
1193                void EvalPriority()
1194                {
1195                        sOspTree->EvalSplitCandidate(*this);   
1196                }
1197
1198                OspSplitCandidate(const AxisAlignedPlane &plane, const OspTraversalData &tData):
1199                SplitCandidate(plane), mParentData(tData)
1200                {}
1201        };
1202
1203        /** Struct for traversing line segment.
1204        */
1205        struct LineTraversalData
1206        {
1207                KdNode *mNode;
1208                Vector3 mExitPoint;
1209               
1210                float mMaxT;
1211   
1212                LineTraversalData () {}
1213                LineTraversalData (KdNode *n, const Vector3 &p, const float maxt):
1214                mNode(n), mExitPoint(p), mMaxT(maxt) {}
1215        };
1216
1217        //typedef std::priority_queue<VspTraversalData> VspOspTraversalQueue;
1218
1219        /** Default constructor creating an empty tree.
1220        */
1221        OspTree();
1222
1223        /** Default destructor.
1224        */
1225        ~OspTree();
1226
1227        /** Returns BSP Tree statistics.
1228        */
1229        const KdTreeStatistics &GetStatistics() const;
1230 
1231        /** Returns bounding box of the specified node.
1232        */
1233        AxisAlignedBox3 GetBoundingBox(KdNode *node) const;
1234
1235        /** Returns list of BSP leaves with pvs smaller than
1236                a certain threshold.
1237                @param onlyUnmailed if only the unmailed leaves should be considered
1238                @param maxPvs the maximal pvs of a leaf to be added (-1 means unlimited)
1239        */
1240        void CollectLeaves(vector<VspLeaf *> &leaves,
1241                                           const bool onlyUnmailed = false,
1242                                           const int maxPvs = -1) const;
1243
1244        /** Returns box which bounds the whole tree.
1245        */
1246        AxisAlignedBox3 GetBoundingBox()const;
1247
1248        /** Returns root of the view space partitioning tree.
1249        */
1250        KdNode *GetRoot() const;
1251
1252        /** Collects the leaf view cells of the tree
1253                @param viewCells returns the view cells
1254        */
1255        void CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const;
1256
1257        /** A ray is cast possible intersecting the tree.
1258                @param the ray that is cast.
1259                @returns the number of intersections with objects stored in the tree.
1260        */
1261        int CastRay(Ray &ray);
1262
1263        /** finds neighbouring leaves of this tree node.
1264        */
1265        int FindNeighbors(KdLeaf *n,
1266                                          vector<VspLeaf *> &neighbors,
1267                                          const bool onlyUnmailed) const;
1268
1269        /** Returns random leaf of BSP tree.
1270                @param halfspace defines the halfspace from which the leaf is taken.
1271        */
1272        KdLeaf *GetRandomLeaf(const Plane3 &halfspace);
1273
1274        /** Returns random leaf of BSP tree.
1275                @param onlyUnmailed if only unmailed leaves should be returned.
1276        */
1277        KdLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
1278
1279        /** Returns epsilon of this tree.
1280        */
1281        float GetEpsilon() const;
1282
1283        /** Casts line segment into the tree.
1284                @param origin the origin of the line segment
1285                @param termination the end point of the line segment
1286                @returns view cells intersecting the line segment.
1287        */
1288    int CastLineSegment(const Vector3 &origin,
1289                                                const Vector3 &termination,
1290                                                ViewCellContainer &viewcells);
1291               
1292        /** Sets pointer to view cells manager.
1293        */
1294        void SetViewCellsManager(ViewCellsManager *vcm);
1295
1296        /** Writes tree to output stream
1297        */
1298#if ZIPPED_VIEWCELLS
1299        bool Export(ogzstream &stream);
1300#else
1301        bool Export(ofstream &stream);
1302#endif
1303
1304        /** Collects rays stored in the leaves.
1305        */
1306        void CollectRays(VssRayContainer &rays);
1307
1308        /** Intersects box with the tree and returns the number of intersected boxes.
1309                @returns number of view cells found
1310        */
1311        int ComputeBoxIntersections(const AxisAlignedBox3 &box,
1312                                                                ViewCellContainer &viewCells) const;
1313
1314
1315        /// pointer to the hierarchy of view cells
1316        ViewCellsTree *mViewCellsTree;
1317
1318
1319protected:
1320
1321        // --------------------------------------------------------------
1322        // For sorting objects
1323        // --------------------------------------------------------------
1324        struct  SortableEntry
1325        {
1326                enum
1327                {
1328                        BOX_MIN,
1329                        BOX_MAX
1330                };
1331
1332                int type;
1333                float value;
1334                Intersectable *mObject;
1335
1336                SortableEntry() {}
1337
1338                SortableEntry(const int t, const float v, Intersectable *obj):
1339                type(t), value(v), mObject(obj)
1340                {}
1341
1342                bool operator<(const SortableEntry &b) const
1343                {
1344                        return value < b.value;
1345                }
1346        };
1347
1348 
1349        /** faster evaluation of split plane cost for kd axis aligned cells.
1350        */
1351        float EvalLocalSplitCost(const OspTraversalData &data,
1352                                                         const AxisAlignedBox3 &box,
1353                                                         const int axis,
1354                                                         const float &position,
1355                                                         float &pFront,
1356                                                         float &pBack) const;
1357
1358        /** Evaluates candidate for splitting.
1359        */
1360        void EvalSplitCandidate(OspSplitCandidate &splitData);
1361
1362        /** Computes priority of the traversal data and stores it in tData.
1363        */
1364        void EvalPriority(OspTraversalData &tData) const;
1365
1366        /** Evaluates render cost decrease of next split.
1367        */
1368        float EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
1369                                                                 const OspTraversalData &data) const;
1370
1371        float EvalViewCellPvsIncr(Intersectable *object) const;
1372
1373
1374        /** Collects view cells in the subtree under root.
1375        */
1376        void CollectViewCells(KdNode *root,
1377                                                  bool onlyValid,
1378                                                  ViewCellContainer &viewCells,
1379                                                  bool onlyUnmailed = false) const;
1380
1381        /** Evaluates tree stats in the BSP tree leafs.
1382        */
1383        void EvaluateLeafStats(const OspTraversalData &data);
1384
1385        /** Subdivides node using a best split priority queue.
1386            @param tQueue the best split priority queue
1387                @param splitCandidate the candidate for the next split
1388                @param globalCriteriaMet if the global termination criteria were already met
1389                @returns new root of the subtree
1390        */
1391        KdNode *Subdivide(SplitQueue &tQueue,
1392                                          OspSplitCandidate &splitCandidate,
1393                                          const bool globalCriteriaMet);
1394       
1395        /** Subdivides leaf.
1396                @param leaf the leaf to be subdivided
1397               
1398                @param polys the polygons to be split
1399                @param frontPolys returns the polygons in front of the split plane
1400                @param backPolys returns the polygons in the back of the split plane
1401               
1402                @param rays the polygons to be filtered
1403                @param frontRays returns the polygons in front of the split plane
1404                @param backRays returns the polygons in the back of the split plane
1405
1406                @returns the root of the subdivision
1407        */
1408        void SplitObjects(const AxisAlignedPlane & splitPlane,
1409                                          const ObjectContainer &objects,
1410                                          ObjectContainer &back,
1411                                          ObjectContainer &front);
1412
1413        KdInterior *SubdivideNode(KdLeaf *leaf,
1414                                                          const AxisAlignedPlane &splitPlane,
1415                                                          const AxisAlignedBox3 &box,
1416                                                          AxisAlignedBox3 &backBBox,
1417                                                          AxisAlignedBox3 &frontBBox);
1418
1419        void ProcessLeafObjects(KdLeaf *leaf, KdLeaf *parent) const;
1420
1421        /** Selects an axis aligned for the next split.
1422                @returns cost for this split
1423        */
1424        float SelectPlane(const OspTraversalData &tData,
1425                                          AxisAlignedPlane &plane,
1426                                          float &pFront,
1427                                          float &pBack);
1428
1429        /** Sorts split candidates for cost heuristics using axis aligned splits.
1430                @param node the current node
1431                @param axis the current split axis
1432        */
1433        void SortSplitCandidates(KdLeaf *node, const int axis);
1434
1435        /** Computes best cost for axis aligned planes.
1436        */
1437        float EvalLocalCostHeuristics(KdLeaf *node,
1438                const AxisAlignedBox3 &box,
1439                const int axis,
1440                float &position,
1441                int &objectsBack,
1442                int &objectsFront);
1443
1444        /** Subdivides the rays into front and back rays according to the split plane.
1445               
1446                @param plane the split plane
1447                @param rays contains the rays to be split. The rays are
1448                           distributed into front and back rays.
1449                @param frontRays returns rays on the front side of the plane
1450                @param backRays returns rays on the back side of the plane
1451               
1452                @returns the number of splits
1453        */
1454        int SplitRays(const AxisAlignedPlane &plane,
1455                                  RayInfoContainer &rays,
1456                              RayInfoContainer &frontRays,
1457                                  RayInfoContainer &backRays) const;
1458
1459        /** Adds the object to the pvs of the front and back leaf with a given classification.
1460
1461                @param obj the object to be added
1462                @param cf the ray classification regarding the split plane
1463                @param frontPvs returns the PVS of the front partition
1464                @param backPvs returns the PVS of the back partition
1465       
1466        */
1467        void AddObjToPvs(Intersectable *obj,
1468                                         const int cf,
1469                                         float &frontPvs,
1470                                         float &backPvs,
1471                                         float &totalPvs) const;
1472       
1473        /** Computes PVS size induced by the rays.
1474        */
1475        int ComputePvsSize(const RayInfoContainer &rays) const;
1476
1477        /** Returns true if tree can be terminated.
1478        */
1479        inline bool LocalTerminationCriteriaMet(const OspTraversalData &data) const;
1480
1481        /** Returns true if global tree can be terminated.
1482        */
1483        inline bool GlobalTerminationCriteriaMet(const OspTraversalData &data) const;
1484
1485        float SelectSplitPlane(const OspTraversalData &tData,
1486                AxisAlignedPlane &plane,
1487                float &pFront,
1488                float &pBack);
1489        /** Adds ray sample contributions to the PVS.
1490                @param sampleContributions the number contributions of the samples
1491                @param contributingSampels the number of contributing rays
1492               
1493        */
1494        void AddToPvs(VspLeaf *leaf,
1495                                  const RayInfoContainer &rays,
1496                                  float &sampleContributions,
1497                                  int &contributingSamples);
1498
1499        /** Propagates valid flag up the tree.
1500        */
1501        void PropagateUpValidity(KdNode *node);
1502
1503        /** Writes the node to disk
1504                @note: should be implemented as visitor.
1505        */
1506#if ZIPPED_VIEWCELLS
1507        void ExportNode(KdNode *node, ogzstream &stream);
1508#else
1509        void ExportNode(KdNode *node, ofstream &stream);
1510#endif
1511
1512        /** Returns estimated memory usage of tree.
1513        */
1514        float GetMemUsage() const;
1515
1516        /** Evaluates the influence on the pvs of the visibility event ve.
1517                @param ve the visibility event
1518                @param pvsLeft updates the left pvs
1519                @param rightPvs updates the right pvs
1520        */
1521        void EvalPvsIncr(const SortableEntry &ve,
1522                                          int &pvsLeft,
1523                                          int &pvsRight) const;
1524
1525        void RemoveContriFromPvs(Intersectable *object, int &pvs) const;
1526        void AddContriToPvs(Intersectable *object, int &pvs) const;
1527
1528        /** Prepares objects for the cost heuristics.
1529                @returns pvs size of the node
1530        */
1531        int PrepareHeuristics(const ObjectContainer &objects);
1532
1533        int PrepareHeuristics(Intersectable *object);
1534
1535        void PrepareConstruction(const ObjectContainer &objects,
1536                AxisAlignedBox3 *forcedBoundingBox);
1537
1538
1539protected:
1540
1541        ViewCellsManager *mViewCellsManager;
1542        vector<SortableEntry> *mSplitCandidates;
1543
1544        /// Pointer to the root of the tree
1545        KdNode *mRoot;
1546               
1547        OspTreeStatistics mOspStats;
1548       
1549        /// box around the whole view domain
1550        AxisAlignedBox3 mBoundingBox;
1551
1552
1553        //-- local termination
1554
1555        /// minimal number of rays before subdivision termination
1556        int mTermMinRays;
1557        /// maximal possible depth
1558        int mTermMaxDepth;
1559        /// mininum probability
1560        float mTermMinProbability;
1561        /// mininum PVS
1562        int mTermMinPvs;
1563        /// maximal contribution per ray
1564        float mTermMaxRayContribution;
1565        /// maximal acceptable cost ratio
1566        float mTermMaxCostRatio;
1567        /// tolerance value indicating how often the max cost ratio can be failed
1568        int mTermMissTolerance;
1569
1570
1571        //-- global criteria
1572        float mTermMinGlobalCostRatio;
1573        int mTermGlobalCostMissTolerance;
1574        int mGlobalCostMisses;
1575
1576        /// maximal number of view cells
1577        int mMaxViewCells;
1578        /// maximal tree memory
1579        float mMaxMemory;
1580        /// the tree is out of memory
1581        bool mOutOfMemory;
1582
1583
1584
1585        //-- split heuristics based parameters
1586       
1587        bool mUseCostHeuristics;
1588        /// balancing factor for PVS criterium
1589        float mCtDivCi;
1590        /// if only driving axis should be used for split
1591        bool mOnlyDrivingAxis;
1592        /// if random split axis should be used
1593        bool mUseRandomAxis;
1594        /// if vsp bsp tree should simulate octree
1595        bool mCirculatingAxis;
1596        /// minimal relative position where the split axis can be placed
1597        float mMinBand;
1598        /// maximal relative position where the split axis can be placed
1599        float mMaxBand;
1600
1601
1602        /// current time stamp (used for keeping split history)
1603        int mTimeStamp;
1604        // if rays should be stored in leaves
1605        bool mStoreRays;
1606
1607        /// epsilon for geometric comparisons
1608        float mEpsilon;
1609
1610
1611        /// subdivision stats output file
1612        ofstream  mSubdivisionStats;
1613        /// keeps track of cost during subdivision
1614        float mTotalCost;
1615        /// keeps track of overall pvs size during subdivision
1616        int mTotalPvsSize;
1617        /// number of currenly generated view cells
1618        int mCreatedViewCells;
1619
1620        float mSplitBorder;
1621
1622
1623private:
1624
1625        /// Generates unique ids for PVS criterium
1626        static void GenerateUniqueIdsForPvs();
1627
1628        //-- unique ids for PVS criterium
1629        static int sFrontId;
1630        static int sBackId;
1631        static int sFrontAndBackId;
1632};
1633
1634
1635/** This class implements a structure holding two different hierarchies,
1636        one for object space partitioning and one for view space partitioning.
1637
1638        The object space and the view space are subdivided using a cost heuristics.
1639        If an object space split or a view space split is chosen is also evaluated
1640        based on the heuristics.
1641       
1642        The view space heuristics is evaluated by weighting and adding the pvss of the back and
1643        front node of each specific split. unlike for the standalone method vspbsp tree,
1644        the pvs of an object would not be the pvs of single object but that of all objects
1645        which are contained in the same leaf of the object subdivision. This could be done
1646        by storing the pointer to the object space partition parent, which would allow access to all children.
1647        Another possibility is to include traced kd-cells in the ray casing process.
1648
1649        Accordingly, the object space heuristics is evaluated by storing a pvs of view cells with each object.
1650        the contribution to an object to the pvs is the number of view cells it can be seen from.
1651
1652        @note
1653        There is a potential efficiency problem involved in a sense that once a certain type
1654        of split is chosen for view space / object space, the candidates for the next split of
1655        object space / view space must be reevaluated.
1656       
1657*/
1658class HierarchyManager
1659{
1660public:
1661        /** Constructor taking an object space partition and a view space partition tree.
1662        */
1663        HierarchyManager(VspTree &vspTree, OspTree &ospTree);
1664
1665        /** Constructs the view space and object space subdivision from a given set of rays
1666                and a set of objects.
1667                @param sampleRays the set of sample rays the construction is based on
1668                @param objects the set of objects
1669        */
1670        void Construct(const VssRayContainer &sampleRays,
1671                                   const ObjectContainer &objects,
1672                                   AxisAlignedBox3 *forcedViewSpace);
1673
1674public:
1675        VspTree &mVspTree;
1676        OspTree &mOspTree;
1677
1678protected:
1679
1680        bool GlobalTerminationCriteriaMet(SplitCandidate *candidate) const;
1681
1682        void PrepareConstruction(const VssRayContainer &sampleRays,
1683                                                         const ObjectContainer &objects,
1684                                                         AxisAlignedBox3 *forcedViewSpace,
1685                                                         RayInfoContainer &rays);
1686
1687        bool FinishedConstruction();
1688        SplitCandidate *NextSplitCandidate();
1689
1690        void RepairQueue(const vector<SplitCandidate *> &dirtyList);
1691
1692        AxisAlignedBox3 mBoundingBox;
1693
1694        SplitQueue mTQueue;
1695
1696        //-- global criteria
1697        float mTermMinGlobalCostRatio;
1698        int mTermGlobalCostMissTolerance;
1699        int mGlobalCostMisses;
1700
1701        /// keeps track of cost during subdivision
1702        float mTotalCost;
1703};
1704
1705}
1706
1707#endif
Note: See TracBrowser for help on using the repository browser.