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

Revision 1135, 44.0 KB checked in by mattausch, 18 years ago (diff)

uaing rays for osp

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