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

Revision 1143, 44.8 KB checked in by mattausch, 18 years ago (diff)

worked on vsp osp tree

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