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

Revision 1189, 48.7 KB checked in by mattausch, 18 years ago (diff)

changed osp partition to something taking mult references into account

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