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

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