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

Revision 1129, 43.3 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        /** Remove the references of the parent view cell from the kd nodes associated with
741                the objects.
742        */
743        void RemoveParentViewCellReferences(ViewCell *parent) const;
744
745        /** Adds references to the view cell to the kd nodes associated with the objects.
746        */
747        void AddViewCellReferences(ViewCell *vc) const;
748
749
750
751        /// pointer to the hierarchy of view cells
752        ViewCellsTree *mViewCellsTree;
753
754protected:
755
756        // --------------------------------------------------------------
757        // For sorting objects
758        // --------------------------------------------------------------
759        struct SortableEntry
760        {
761                enum EType
762                {
763                        ERayMin,
764                        ERayMax
765                };
766
767                int type;
768                float value;
769                VssRay *ray;
770 
771                SortableEntry() {}
772                SortableEntry(const int t, const float v, VssRay *r):
773                type(t), value(v), ray(r)
774                {
775                }
776               
777                friend bool operator<(const SortableEntry &a, const SortableEntry &b)
778                {
779                        return a.value < b.value;
780                }
781        };
782
783        /** faster evaluation of split plane cost for kd axis aligned cells.
784        */
785        float EvalLocalSplitCost(const VspTraversalData &data,
786                                                         const AxisAlignedBox3 &box,
787                                                         const int axis,
788                                                         const float &position,
789                                                         float &pFront,
790                                                         float &pBack) const;
791
792        void PrepareConstruction(const VssRayContainer &sampleRays,
793                                                         AxisAlignedBox3 *forcedBoundingBox);
794
795        /** Evaluates candidate for splitting.
796        */
797        void EvalSplitCandidate(VspSplitCandidate &splitData);
798
799        /** Evaluates render cost decrease of next split.
800        */
801        float EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
802                                                                 const VspTraversalData &data) const;
803
804        /** Collects view cells in the subtree under root.
805        */
806        void CollectViewCells(VspNode *root,
807                                                  bool onlyValid,
808                                                  ViewCellContainer &viewCells,
809                                                  bool onlyUnmailed = false) const;
810
811        /** Returns view cell corresponding to
812                the invalid view space. If it does not exist, it is created.
813        */
814        VspViewCell *GetOrCreateOutOfBoundsCell();
815
816        /** Collapses the tree with respect to the view cell partition,
817                i.e. leaves having the same view cell are collapsed.
818                @param node the root of the subtree to be collapsed
819                @param collapsed returns the number of collapsed nodes
820                @returns node of type leaf if the node could be collapsed,
821                this node otherwise
822        */
823        VspNode *CollapseTree(VspNode *node, int &collapsed);
824
825        /** Helper function revalidating the view cell leaf list after merge.
826        */
827        void RepairViewCellsLeafLists();
828
829        /** Evaluates tree stats in the BSP tree leafs.
830        */
831        void EvaluateLeafStats(const VspTraversalData &data);
832
833        /** Subdivides node using a best split priority queue.
834            @param tQueue the best split priority queue
835                @param splitCandidate the candidate for the next split
836                @param globalCriteriaMet if the global termination criteria were already met
837                @returns new root of the subtree
838        */
839        VspNode *Subdivide(SplitQueue &tQueue,
840                                           VspSplitCandidate &splitCandidate,
841                                           const bool globalCriteriaMet);
842
843        /** Adds stats to subdivision log file.
844        */
845        void AddSubdivisionStats(const int viewCells,
846                                                         const float renderCostDecr,
847                                                         const float splitCandidateCost,
848                                                         const float totalRenderCost,
849                                                         const float avgRenderCost);
850       
851        /** Subdivides leaf.
852                       
853                @param tData data object holding, e.g., a pointer to the leaf
854                @param frontData returns the data (e.g.,  pointer to the leaf) in front of the split plane
855                @param backData returns the data (e.g.,  pointer to the leaf) in the back of the split plane
856               
857                @param rays the polygons to be filtered
858                @param frontRays returns the polygons in front of the split plane
859       
860                @returns the root of the subdivision
861        */
862        VspInterior *SubdivideNode(const AxisAlignedPlane &splitPlane,
863                                                           VspTraversalData &tData,
864                                                           VspTraversalData &frontData,
865                               VspTraversalData &backData);
866
867        /** Selects an axis aligned for the next split.
868                @returns cost for this split
869        */
870        float SelectSplitPlane(const VspTraversalData &tData,
871                                                   AxisAlignedPlane &plane,
872                                                   float &pFront,
873                                                   float &pBack);
874
875        /** Sorts split candidates along the specified axis.
876                The split candidates are generated on possible visibility
877                events (i.e., where ray segments intersect the ray boundaries).
878                The sorted candidates are needed to compute the heuristics.
879
880                @param polys the input for choosing split candidates
881                @param axis the current split axis
882                @param splitCandidates returns sorted list of split candidates
883        */
884        void SortSplitCandidates(const RayInfoContainer &rays,
885                                                         const int axis,
886                                                         float minBand,
887                                                         float maxBand);
888
889        /** Computes pvs increase with respect to the previous pvs for heuristics.
890        */
891        int GetPvsIncr(Intersectable *object, const KdPvsMap &activeNodes);
892
893        /** Returns absolute pvs contribution of this object.
894        */
895        int GetPvsContribution(Intersectable *object) const;
896
897        /** Computes best cost for axis aligned planes.
898        */
899        float EvalLocalCostHeuristics(const RayInfoContainer &rays,
900                                                                  const AxisAlignedBox3 &box,
901                                                                  int pvsSize,
902                                                                  const int axis,
903                                                                  float &position);
904
905        /** Evaluates the influence on the pvs of the visibility event ve.
906                @param ve the visibility event
907                @param pvsLeft updates the left pvs
908                @param rightPvs updates the right pvs
909        */
910        void EvalPvsIncr(const SortableEntry &ve,
911                                          int &pvsLeft,
912                                          int &pvsRight) const;
913
914        void RemoveContriFromPvs(KdLeaf *leaf, int &pvs) const;
915        void AddContriToPvs(KdLeaf *leaf, int &pvs) const;
916
917        /** Prepares objects for the heuristics.
918                @returns pvs size of the ray container
919        */
920        int PrepareHeuristics(const RayInfoContainer &rays);
921
922        int PrepareHeuristics(Intersectable *object);
923
924        /** Subdivides the rays into front and back rays according to the split plane.
925               
926                @param plane the split plane
927                @param rays contains the rays to be split. The rays are
928                           distributed into front and back rays.
929                @param frontRays returns rays on the front side of the plane
930                @param backRays returns rays on the back side of the plane
931               
932                @returns the number of splits
933        */
934        int SplitRays(const AxisAlignedPlane &plane,
935                                  RayInfoContainer &rays,
936                              RayInfoContainer &frontRays,
937                                  RayInfoContainer &backRays) const;
938
939        /** Adds the object to the pvs of the front and back leaf with a given classification.
940
941                @param obj the object to be added
942                @param cf the ray classification regarding the split plane
943                @param frontPvs returns the PVS of the front partition
944                @param backPvs returns the PVS of the back partition
945       
946        */
947        void AddObjToPvs(Intersectable *obj,
948                                         const int cf,
949                                         float &frontPvs,
950                                         float &backPvs,
951                                         float &totalPvs) const;
952       
953        /** Computes PVS size induced by the rays.
954        */
955        int ComputePvsSize(const RayInfoContainer &rays) const;
956       
957        /** Collects pvs from rays.
958        */
959        void CollectPvs(const RayInfoContainer &rays,
960                                        ObjectContainer &objects) const;
961
962        /** Returns true if tree can be terminated.
963        */
964        inline bool LocalTerminationCriteriaMet(const VspTraversalData &data) const;
965
966        /** Returns true if global tree can be terminated.
967        */
968        inline bool GlobalTerminationCriteriaMet(const VspTraversalData &data) const;
969
970        /** Adds ray sample contributions to the PVS.
971                @param sampleContributions the number contributions of the samples
972                @param contributingSampels the number of contributing rays
973               
974        */
975        void AddToPvs(VspLeaf *leaf,
976                                  const RayInfoContainer &rays,
977                                  float &sampleContributions,
978                                  int &contributingSamples);
979
980        /** Propagates valid flag up the tree.
981        */
982        void PropagateUpValidity(VspNode *node);
983
984        /** Writes the node to disk
985                @note: should be implemented as visitor.
986        */
987#if ZIPPED_VIEWCELLS
988        void ExportNode(VspNode *node, ogzstream &stream);
989#else
990        void ExportNode(VspNode *node, ofstream &stream);
991#endif
992
993        /** Returns estimated memory usage of tree.
994        */
995        float GetMemUsage() const;
996
997        void ProcessViewCellObjects(ViewCell *parent,
998                ViewCell *front,
999                ViewCell *back) const;
1000
1001        void CreateViewCell(VspTraversalData &tData);
1002
1003        void CollectDirtyCandidates(VspSplitCandidate *sc,
1004                vector<SplitCandidate *> &dirtyList);
1005
1006protected:
1007
1008        int mPvsCountMethod;
1009        enum {PER_OBJECT, PER_KDLEAF};
1010
1011        ViewCellsManager *mViewCellsManager;
1012        vector<SortableEntry> *mSplitCandidates;
1013
1014        /// Pointer to the root of the tree
1015        VspNode *mRoot;
1016               
1017        VspTreeStatistics mVspStats;
1018       
1019        /// View cell corresponding to the space outside the valid view space
1020        VspViewCell *mOutOfBoundsCell;
1021
1022        /// box around the whole view domain
1023        AxisAlignedBox3 mBoundingBox;
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        float PrepareHeuristics(const ObjectContainer &objects);
1552
1553        /** Evaluates contribution for one object
1554                to heuristics preparation.
1555        */
1556        float PrepareHeuristics(Intersectable *object);
1557
1558        /** Prepares construction for vsp and osp trees.
1559        */
1560        void PrepareConstruction(const ObjectContainer &objects,
1561                AxisAlignedBox3 *forcedBoundingBox);
1562
1563        void CollectDirtyCandidates(OspSplitCandidate *sc,
1564                vector<SplitCandidate *> &dirtyList);
1565
1566        /** Collect view cells which see this kd leaf.
1567        */
1568        void CollectViewCells(KdLeaf *leaf,
1569                ViewCellContainer &viewCells);
1570
1571
1572protected:
1573
1574        /// The view cells manager
1575        ViewCellsManager *mViewCellsManager;
1576
1577        /// candidates for placing split planes during cost heuristics
1578        vector<SortableEntry> *mSplitCandidates;
1579
1580        /// Pointer to the root of the tree
1581        KdNode *mRoot;
1582               
1583        /// Statistics for the object space partition
1584        OspTreeStatistics mOspStats;
1585       
1586        /// box around the whole view domain
1587        AxisAlignedBox3 mBoundingBox;
1588
1589
1590        //-- local termination
1591
1592        /// maximal possible depth
1593        int mTermMaxDepth;
1594        /// mininum probability
1595        float mTermMinProbability;
1596        /// minimal number of objects
1597        int mTermMinObjects;
1598        /// maximal contribution per ray
1599        float mTermMaxRayContribution;
1600        /// maximal acceptable cost ratio
1601        float mTermMaxCostRatio;
1602        /// tolerance value indicating how often the max cost ratio can be failed
1603        int mTermMissTolerance;
1604
1605
1606        //-- global criteria
1607
1608        float mTermMinGlobalCostRatio;
1609        int mTermGlobalCostMissTolerance;
1610        int mGlobalCostMisses;
1611
1612        /// maximal number of view cells
1613        int mTermMaxLeaves;
1614        /// maximal tree memory
1615        float mMaxMemory;
1616        /// the tree is out of memory
1617        bool mOutOfMemory;
1618
1619
1620
1621        //-- split heuristics based parameters
1622       
1623        bool mUseCostHeuristics;
1624        /// balancing factor for PVS criterium
1625        float mCtDivCi;
1626        /// if only driving axis should be used for split
1627        bool mOnlyDrivingAxis;
1628       
1629        /// current time stamp (used for keeping split history)
1630        int mTimeStamp;
1631        // if rays should be stored in leaves
1632        bool mStoreRays;
1633
1634        /// epsilon for geometric comparisons
1635        float mEpsilon;
1636
1637
1638        bool mUseEqualWeightForHeuristics;
1639
1640        /// subdivision stats output file
1641        ofstream  mSubdivisionStats;
1642        /// keeps track of cost during subdivision
1643        float mTotalCost;
1644        /// keeps track of overall pvs size during subdivision
1645        int mTotalPvsSize;
1646        /// number of currenly generated view cells
1647        int mCreatedLeaves;
1648
1649        /// represents min and max band for sweep
1650        float mSplitBorder;
1651
1652        /// weight between  render cost decrease and node render cost
1653        float mRenderCostDecreaseWeight;
1654};
1655
1656
1657/** This class implements a structure holding two different hierarchies,
1658        one for object space partitioning and one for view space partitioning.
1659
1660        The object space and the view space are subdivided using a cost heuristics.
1661        If an object space split or a view space split is chosen is also evaluated
1662        based on the heuristics.
1663       
1664        The view space heuristics is evaluated by weighting and adding the pvss of the back and
1665        front node of each specific split. unlike for the standalone method vspbsp tree,
1666        the pvs of an object would not be the pvs of single object but that of all objects
1667        which are contained in the same leaf of the object subdivision. This could be done
1668        by storing the pointer to the object space partition parent, which would allow access to all children.
1669        Another possibility is to include traced kd-cells in the ray casing process.
1670
1671        Accordingly, the object space heuristics is evaluated by storing a pvs of view cells with each object.
1672        the contribution to an object to the pvs is the number of view cells it can be seen from.
1673
1674        @note
1675        There is a potential efficiency problem involved in a sense that once a certain type
1676        of split is chosen for view space / object space, the candidates for the next split of
1677        object space / view space must be reevaluated.
1678       
1679*/
1680class HierarchyManager
1681{
1682public:
1683        /** Constructor taking an object space partition and a view space partition tree.
1684        */
1685        HierarchyManager(VspTree &vspTree, OspTree &ospTree);
1686
1687        /** Constructs the view space and object space subdivision from a given set of rays
1688                and a set of objects.
1689                @param sampleRays the set of sample rays the construction is based on
1690                @param objects the set of objects
1691        */
1692        void Construct(const VssRayContainer &sampleRays,
1693                                   const ObjectContainer &objects,
1694                                   AxisAlignedBox3 *forcedViewSpace);
1695
1696        /** Constructs first view cells, then object space partition.
1697        */
1698        void Construct2(const VssRayContainer &sampleRays,
1699                                        const ObjectContainer &objects,
1700                                        AxisAlignedBox3 *forcedViewSpace);
1701
1702public:
1703        VspTree &mVspTree;
1704        OspTree &mOspTree;
1705
1706protected:
1707
1708        bool GlobalTerminationCriteriaMet(SplitCandidate *candidate) const;
1709
1710        void PrepareConstruction(const VssRayContainer &sampleRays,
1711                                                         const ObjectContainer &objects,
1712                                                         AxisAlignedBox3 *forcedViewSpace,
1713                                                         RayInfoContainer &rays);
1714
1715        bool FinishedConstruction();
1716
1717        SplitCandidate *NextSplitCandidate();
1718
1719        void RepairQueue();
1720
1721        void CollectDirtyCandidates(vector<SplitCandidate *> &dirtyList);
1722
1723        void PrepareVsp(const VssRayContainer &sampleRays,
1724                AxisAlignedBox3 *forcedViewSpace,
1725                RayInfoContainer &rays);
1726
1727        void PrepareOsp(const ObjectContainer &objects, AxisAlignedBox3 *forcedViewSpace);
1728
1729        void ProcessRays(const VssRayContainer &sampleRays,
1730                RayInfoContainer &rays,
1731                ObjectContainer &sampledObjects);
1732
1733
1734protected:
1735
1736        AxisAlignedBox3 mBoundingBox;
1737
1738        SplitQueue mTQueue;
1739
1740        SplitCandidate *mCurrentCandidate;
1741
1742        //-- global criteria
1743        float mTermMinGlobalCostRatio;
1744        int mTermGlobalCostMissTolerance;
1745        int mGlobalCostMisses;
1746
1747        /// keeps track of cost during subdivision
1748        float mTotalCost;
1749};
1750
1751}
1752
1753#endif
Note: See TracBrowser for help on using the repository browser.