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

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