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

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