source: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h @ 2015

Revision 2015, 28.8 KB checked in by bittner, 17 years ago (diff)

pvs efficiency tuning

Line 
1#ifndef _VspTree_H__
2#define _VspTree_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 "SubdivisionCandidate.h"
13#include "HierarchyManager.h"
14
15
16namespace GtpVisibilityPreprocessor {
17
18class ViewCellLeaf;
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 HierarchyManager;
35class KdIntersectable;
36class KdTree;
37class VspTree;
38class KdTreeStatistics;
39
40
41#define WORK_WITH_VIEWCELLS 0
42
43/** View space partition statistics.
44*/
45class VspTreeStatistics: public StatisticsBase
46{
47public:
48        // total number of nodes
49        int nodes;
50        // number of splits
51        int splits[3];
52       
53        // totals number of rays
54        int rays;
55        // maximal reached depth
56        int maxDepth;
57        // minimal depth
58        int minDepth;
59       
60        // max depth nodes
61        int maxDepthNodes;
62        // minimum depth nodes
63        int minDepthNodes;
64        // max depth nodes
65        int minPvsNodes;
66        // nodes with minimum PVS
67        int minRaysNodes;
68        // max ray contribution nodes
69        int maxRayContribNodes;
70        // minimum area nodes
71        int minProbabilityNodes;
72        /// nodes termination because of max cost ratio;
73        int maxCostNodes;
74        // max number of rays per node
75        int maxObjectRefs;
76        /// samples contributing to pvs
77        int contributingSamples;
78        /// sample contributions to pvs
79        int sampleContributions;
80        /// largest pvs
81        int maxPvs;
82        /// number of invalid leaves
83        int invalidLeaves;
84        /// number of rays refs
85        int rayRefs;
86        /// overall pvs size
87        int pvs;
88        // accumulated depth (used to compute average)
89        int accumDepth;
90        // global cost ratio violations
91        int mGlobalCostMisses;
92
93        // Constructor
94        VspTreeStatistics()
95        {
96                Reset();
97        }
98
99        int Nodes() const {return nodes;}
100        int Interior() const { return nodes / 2; }
101        int Leaves() const { return (nodes / 2) + 1; }
102       
103        // TODO: computation wrong
104        double AvgDepth() const { return accumDepth / (double)Leaves();};
105        double AvgRays() const { return rayRefs / (double)Leaves();};
106
107        void Reset()
108        {
109                nodes = 0;
110                for (int i = 0; i < 3; ++ i)
111                        splits[i] = 0;
112               
113                maxDepth = 0;
114                minDepth = 99999;
115                accumDepth = 0;
116        pvs = 0;
117                maxDepthNodes = 0;
118                minPvsNodes = 0;
119                minRaysNodes = 0;
120                maxRayContribNodes = 0;
121                minProbabilityNodes = 0;
122                maxCostNodes = 0;
123
124                contributingSamples = 0;
125                sampleContributions = 0;
126
127                maxPvs = 0;
128                invalidLeaves = 0;
129                rayRefs = 0;
130                maxObjectRefs = 0;
131                mGlobalCostMisses = 0;
132        }
133
134        void Print(ostream &app) const;
135
136        friend ostream &operator<<(ostream &s, const VspTreeStatistics &stat)
137        {
138                stat.Print(s);
139                return s;
140        }
141};
142
143
144/**
145    VspNode abstract class serving for interior and leaf node implementation
146*/
147class VspNode
148{
149public:
150       
151        /// types of vsp nodes
152        enum {Interior, Leaf};
153
154        VspNode();
155        virtual ~VspNode(){};
156        VspNode(VspInterior *parent);
157
158        /** Determines whether this node is a leaf or not
159                @return true if leaf
160        */
161        virtual bool IsLeaf() const = 0;
162
163        virtual int Type() const = 0;
164
165        /** Determines whether this node is a root
166                @return true if root
167        */
168        virtual bool IsRoot() const;
169       
170        /** Returns parent node.
171        */
172        VspInterior *GetParent();
173       
174        /** Sets parent node.
175        */
176        void SetParent(VspInterior *parent);
177
178        /** Returns true if this node is a sibling of node n.
179        */
180        bool IsSibling(VspNode *n) const;
181       
182        /** returns depth of the node.
183        */
184        int GetDepth() const;
185       
186        /** returns true if the whole subtree is valid
187        */
188        bool TreeValid() const;
189
190        void SetTreeValid(const bool v);
191       
192        /** Cost of mergin this node.
193        */
194        float GetMergeCost() {return (float)-mTimeStamp; }
195
196        int mTimeStamp;
197
198        /////////
199        //-- mailing options
200
201        void Mail() { mMailbox = sMailId; }
202        static void NewMail() { ++ sMailId; }
203        bool Mailed() const { return mMailbox == sMailId; }
204
205
206        static int sMailId;
207        int mMailbox;
208
209        //int mPvsEntriesIncr;
210        //float mMemoryIncr;
211        //float mRenderCostDecr;
212
213protected:
214
215        /// if this sub tree is a completely valid view space region
216        bool mTreeValid;
217       
218        /// parent of this node
219        VspInterior *mParent;
220};
221
222
223/** BSP interior node implementation
224*/
225class VspInterior: public VspNode
226{
227public:
228
229        /** Standard contructor taking split plane as argument.
230        */
231        VspInterior(const AxisAlignedPlane &plane);
232
233        ~VspInterior();
234       
235        /** @return false since it is an interior node
236        */
237  bool IsLeaf() const {
238        return false;
239  }
240
241
242        int Type() const;
243
244  VspNode *GetBack() {
245        return mBack;
246  }
247
248
249  VspNode *GetFront() {
250        return mFront;
251  }
252
253        /** Returns split plane.
254        */
255  AxisAlignedPlane GetPlane() const {
256        return mPlane;
257  }
258 
259
260        /** Returns position of split plane.
261        */
262  float GetPosition() const {
263        return mPlane.mPosition;
264  }
265
266        /** Returns split axis.
267        */
268  int GetAxis() const {
269        return mPlane.mAxis;
270  }
271
272        /** Replace front or back child with new child.
273        */
274        void ReplaceChildLink(VspNode *oldChild, VspNode *newChild);
275
276        /** Replace front and back child.
277        */
278        void SetupChildLinks(VspNode *front, VspNode *back);
279
280        friend ostream &operator<<(ostream &s, const VspInterior &A)
281        {
282                return s << A.mPlane.mAxis << " " << A.mPlane.mPosition;
283        }
284
285        AxisAlignedBox3 GetBoundingBox() const;
286        void SetBoundingBox(const AxisAlignedBox3 &box);
287
288        /** Computes intersection of this plane with the ray segment.
289        */
290        int ComputeRayIntersection(const RayInfo &rayData, float &t) const
291        {
292                return rayData.ComputeRayIntersection(mPlane.mAxis, mPlane.mPosition, t);
293        }
294
295
296protected:
297        /// bounding box for this interior node: should we really store this?
298        AxisAlignedBox3 mBoundingBox;
299
300        /// Splitting plane corresponding to this node
301        AxisAlignedPlane mPlane;
302
303        /// back node
304        VspNode *mBack;
305        /// front node
306        VspNode *mFront;
307};
308
309
310/** BSP leaf node implementation.
311*/
312class VspLeaf: public VspNode
313{
314        friend VspTree;
315
316public:
317        VspLeaf();
318        VspLeaf(ViewCellLeaf *viewCell);
319        VspLeaf(VspInterior *parent);
320        VspLeaf(VspInterior *parent, ViewCellLeaf *viewCell);
321
322        ~VspLeaf();
323
324        /** @return true since it is an interior node
325        */
326  bool IsLeaf() const {
327        return true;
328  }
329       
330        int Type() const;
331
332        /** Returns pointer of view cell.
333        */
334  ViewCellLeaf *GetViewCell() const {
335        return mViewCell;
336  }
337
338        /** Sets pointer to view cell.
339        */
340        void SetViewCell(ViewCellLeaf *viewCell);
341
342        SubdivisionCandidate *GetSubdivisionCandidate()
343        {
344                return mSubdivisionCandidate;
345        }
346
347        void SetSubdivisionCandidate(SubdivisionCandidate *candidate)
348        {
349                mSubdivisionCandidate = candidate;
350        }
351
352
353public:
354
355        /// Rays piercing this leaf.
356        VssRayContainer mVssRays;
357       
358        /// Probability that the view point lies in this leaf
359        float mProbability;
360
361protected:
362
363        /// pointer to a split plane candidate splitting this leaf
364        SubdivisionCandidate *mSubdivisionCandidate;
365       
366        /// if NULL this does not correspond to feasible viewcell
367        ViewCellLeaf *mViewCell;
368};
369
370
371/** View Space Partitioning tree.
372*/
373class VspTree
374{
375        friend class ViewCellsParseHandlers;
376        friend class HierarchyManager;
377
378public:
379       
380        /** Additional data which is passed down the BSP tree during traversal.
381        */
382        class VspTraversalData
383        { 
384        public:
385               
386                /** Returns average ray contribution.
387                */
388                float GetAvgRayContribution() const
389                {
390                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
391                }
392
393
394                VspTraversalData():
395                        mNode(NULL),
396                        mDepth(0),
397                        mRays(NULL),
398                        mPvs(0),
399                        mProbability(0.0),
400                        mMaxCostMisses(0),
401                        mPriority(0),
402                        mCorrectedPvs(0)
403                {}
404               
405                VspTraversalData(VspLeaf *node,
406                                                 const int depth,
407                                                 RayInfoContainer *rays,
408                                                 const float pvs,
409                                                 const float p,
410                                                 const AxisAlignedBox3 &box):
411                        mNode(node),
412                        mDepth(depth),
413                        mRays(rays),
414                        mProbability(p),
415                        mBoundingBox(box),
416                        mMaxCostMisses(0),
417                        mPriority(0),
418                        mCorrectedPvs(0),
419                        mPvs(pvs),
420                        mRenderCost(0),
421                        mCorrectedRenderCost(0)
422                {}
423
424                VspTraversalData(const int depth,
425                                                 RayInfoContainer *rays,
426                                                 const AxisAlignedBox3 &box):
427                        mNode(NULL),
428                        mDepth(depth),
429                        mRays(rays),
430                        mProbability(0),
431                        mMaxCostMisses(0),
432                        mBoundingBox(box),
433                        mCorrectedPvs(0),
434                        mPvs(0) ,
435                        mRenderCost(0),
436                        mCorrectedRenderCost(0)
437                {}
438
439                /** Returns cost of the traversal data.
440                */
441                float GetCost() const
442                {
443                        return mPriority;
444                }
445
446                /// deletes contents and sets them to NULL
447                void Clear()
448                {
449                        DEL_PTR(mRays);
450
451                        if (mNode)
452                        {
453                                // delete old view cell
454                                delete mNode->GetViewCell();
455
456                                delete mNode;
457                                mNode = NULL;
458                        }
459                }
460
461                /// the current node
462                VspLeaf *mNode;
463                /// current depth
464                int mDepth;
465                /// rays piercing this node
466                RayInfoContainer *mRays;
467                /// the probability that this node contains view point
468                float mProbability;
469                /// the bounding box of the node
470                AxisAlignedBox3 mBoundingBox;
471                /// how often this branch has missed the max-cost ratio
472                int mMaxCostMisses;
473                // current priority
474                float mPriority;
475                /// pvs size
476                float mPvs;
477                /// the correction factor for this pvs
478                float mCorrectedPvs;
479                /// pvs size
480                float mRenderCost;
481                /// the correction factor for this pvs
482                float mCorrectedRenderCost;
483
484                friend bool operator<(const VspTraversalData &a, const VspTraversalData &b)
485                {
486                        return a.GetCost() < b.GetCost();
487                }
488    };
489
490        /** Candidate for a view space split.
491        */
492        class VspSubdivisionCandidate: public SubdivisionCandidate
493        { 
494        public:
495
496                VspSubdivisionCandidate(const VspTraversalData &tData): mParentData(tData)
497                {};
498
499                ~VspSubdivisionCandidate()
500                {
501                        mParentData.Clear();
502                }
503
504                int Type() const { return VIEW_SPACE; }
505
506                void EvalCandidate(bool computeSplitplane = true)
507                {
508                        mDirty = false;
509                        sVspTree->EvalSubdivisionCandidate(*this, computeSplitplane);
510                }
511
512                bool GlobalTerminationCriteriaMet() const
513                {
514                        return sVspTree->GlobalTerminationCriteriaMet(mParentData);
515                }
516
517                bool Apply(SplitQueue &splitQueue, bool terminationCriteriaMet)
518                {
519                        VspNode *n = sVspTree->Subdivide(splitQueue, this, terminationCriteriaMet);
520                       
521                        // local or global termination criteria failed
522                        return !n->IsLeaf();           
523                }
524
525                void CollectDirtyCandidates(SubdivisionCandidateContainer &dirtyList,
526                                                                        const bool onlyUnmailed)
527                {
528                        sVspTree->CollectDirtyCandidates(this, dirtyList, onlyUnmailed);
529                }
530
531                VspSubdivisionCandidate(const AxisAlignedPlane &plane, const VspTraversalData &tData):
532                        mSplitPlane(plane), mParentData(tData)
533                {}
534
535                float GetPriority() const
536                {
537                        return (float)-mParentData.mDepth;
538                        //return mPriority;
539                }
540
541                ////////////////////
542
543                static VspTree* sVspTree;
544
545                /// the current split plane
546                AxisAlignedPlane mSplitPlane;
547                /// parent node traversal data
548                VspTraversalData mParentData;
549       
550                float mCorrectedFrontPvs;
551                float mCorrectedBackPvs;
552
553                float mCorrectedFrontRenderCost;
554                float mCorrectedBackRenderCost;
555                float mCorrectedFrontVolume;
556                float mCorrectedBackVolume;
557        };
558
559        /** Struct for traversing line segment.
560        */
561        struct LineTraversalData
562        {
563                VspNode *mNode;
564                Vector3 mExitPoint;
565                float mMaxT;
566   
567                LineTraversalData () {}
568                LineTraversalData (VspNode *n, const Vector3 &p, const float maxt):
569                mNode(n), mExitPoint(p), mMaxT(maxt) {}
570        };
571
572        /** Default constructor creating an empty tree.
573        */
574        VspTree();
575        /** Default destructor.
576        */
577        ~VspTree();
578
579        /** Returns BSP Tree statistics.
580        */
581        const VspTreeStatistics &GetStatistics() const;
582 
583        /** Returns bounding box of the specified node.
584        */
585        AxisAlignedBox3 GetBoundingBox(VspNode *node) const;
586
587        /** Returns list of BSP leaves with pvs smaller than
588                a certain threshold.
589                @param onlyUnmailed if only the unmailed leaves should be considered
590                @param maxPvs the maximal pvs of a leaf to be added (-1 means unlimited)
591        */
592        void CollectLeaves(vector<VspLeaf *> &leaves,
593                                           const bool onlyUnmailed = false,
594                                           const int maxPvs = -1) const;
595
596        /** Returns box which bounds the whole tree.
597        */
598        AxisAlignedBox3 GetBoundingBox() const;
599
600        /** Returns root of the view space partitioning tree.
601        */
602        VspNode *GetRoot() const;
603
604        /** Collects the leaf view cells of the tree
605                @param viewCells returns the view cells
606        */
607        void CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const;
608
609        /** A ray is cast possible intersecting the tree.
610                @param the ray that is cast.
611                @returns the number of intersections with objects stored in the tree.
612        */
613        int CastRay(Ray &ray);
614
615
616        /** finds neighbouring leaves of this tree node.
617        */
618        int FindNeighbors(VspLeaf *n,
619                                          vector<VspLeaf *> &neighbors,
620                                          const bool onlyUnmailed) const;
621
622        /** Returns random leaf of BSP tree.
623                @param halfspace defines the halfspace from which the leaf is taken.
624        */
625        VspLeaf *GetRandomLeaf(const Plane3 &halfspace);
626
627        /** Returns random leaf of BSP tree.
628                @param onlyUnmailed if only unmailed leaves should be returned.
629        */
630        VspLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
631
632        /** Returns epsilon of this tree.
633        */
634        float GetEpsilon() const;
635
636        /** Casts line segment into the tree.
637                @param origin the origin of the line segment
638                @param termination the end point of the line segment
639                @returns view cells intersecting the line segment.
640        */
641    int CastLineSegment(const Vector3 &origin,
642                                                const Vector3 &termination,
643                                                ViewCellContainer &viewcells,
644                                                const bool useMailboxing = true);
645
646               
647        /** Sets pointer to view cells manager.
648        */
649        void SetViewCellsManager(ViewCellsManager *vcm);
650
651        /** Returns view cell the current point is located in.
652                @param point the current view point
653                @param active if currently active view cells should be returned or
654                elementary view cell
655        */
656        ViewCell *GetViewCell(const Vector3 &point, const bool active = false);
657
658
659        /** Returns true if this view point is in a valid view space,
660                false otherwise.
661        */
662        bool ViewPointValid(const Vector3 &viewPoint) const;
663
664        /** Returns view cell corresponding to
665                the invalid view space.
666        */
667        VspViewCell *GetOutOfBoundsCell();
668
669        /** Writes tree to output stream
670        */
671        bool Export(OUT_STREAM &stream);
672
673        /** Casts beam, i.e. a 5D frustum of rays, into tree.
674                Tests conservative using the bounding box of the nodes.
675                @returns number of view cells it intersected
676        */
677        int CastBeam(Beam &beam);
678
679        /** Checks if tree validity-flags are right
680                with respect to view cell valitiy.
681                If not, marks subtree as invalid.
682        */
683        void ValidateTree();
684
685        /** Invalid view cells are added to the unbounded space
686        */
687        void CollapseViewCells();
688
689        /** Collects rays stored in the leaves.
690        */
691        void CollectRays(VssRayContainer &rays);
692
693        /** Intersects box with the tree and returns the number of intersected boxes.
694                @returns number of view cells found
695        */
696        int ComputeBoxIntersections(const AxisAlignedBox3 &box,
697                                                                ViewCellContainer &viewCells) const;
698
699        /** Returns view cells of this ray, either taking precomputed cells
700                or by recomputation.
701        */
702        void GetViewCells(const VssRay &ray, ViewCellContainer &viewCells);
703
704        /** Returns view cells tree.
705        */
706        ViewCellsTree *GetViewCellsTree() const { return mViewCellsTree; }
707
708        /** Sets the view cells tree.
709        */
710        void SetViewCellsTree(ViewCellsTree *vt) { mViewCellsTree = vt; }
711
712#if WORK_WITH_VIEWCELLS
713        /** Remove the references of the parent view cell from the kd nodes associated with
714                the objects.
715        */
716        void RemoveParentViewCellReferences(ViewCell *parent) const;
717
718        /** Adds references to the view cell to the kd nodes associated with the objects.
719        */
720        void AddViewCellReferences(ViewCell *vc) const;
721#endif
722
723        VspNode *SubdivideAndCopy(SplitQueue &tQueue, SubdivisionCandidate *splitCandidate);
724
725        bool LineSegmentIntersects(const Vector3 &origin,
726                                                           const Vector3 &termination,
727                                                           ViewCell *viewCell);
728protected:
729
730        // --------------------------------------------------------------
731        // For sorting objects
732        // --------------------------------------------------------------
733        struct SortableEntry
734        {
735                enum EType
736                {
737                        ERayMin,
738                        ERayMax
739                };
740
741                int type;
742                float value;
743                VssRay *ray;
744 
745                SortableEntry() {}
746                SortableEntry(const int t, const float v, VssRay *r):
747                type(t), value(v), ray(r)
748                {
749                }
750               
751                friend inline bool operator<(const SortableEntry &a, const SortableEntry &b)
752                {       // prefer max event
753                        //if (EpsilonEqual(a.value, b.value, 0.0001f))
754                        //      return (a.type == ERayMax);
755
756                        return (a.value < b.value);
757                }
758        };
759
760        /** faster evaluation of split plane cost for kd axis aligned cells.
761        */
762        float EvalLocalSplitCost(const VspTraversalData &data,
763                                                         const AxisAlignedBox3 &box,
764                                                         const int axis,
765                                                         const float &position,
766                                                         float &pFront,
767                                                         float &pBack) const;
768
769        void ComputeBoundingBox(const VssRayContainer &rays,
770                                                        AxisAlignedBox3 *forcedBoundingBox);
771
772        /** Evaluates candidate for splitting.
773        */
774        void EvalSubdivisionCandidate(VspSubdivisionCandidate &splitData,
775                                                                  bool computeSplitPlane = true);
776
777        /** Evaluates render cost decrease of next split.
778        */
779        float EvalRenderCostDecrease(VspSubdivisionCandidate &splitData,
780                                                                 float &normalizedOldRenderCost) const;
781
782        /** Collects view cells in the subtree under root.
783        */
784        void CollectViewCells(VspNode *root,
785                                                  bool onlyValid,
786                                                  ViewCellContainer &viewCells,
787                                                  bool onlyUnmailed = false) const;
788
789        /** Returns view cell corresponding to
790                the invalid view space. If it does not exist, it is created.
791        */
792        VspViewCell *GetOrCreateOutOfBoundsCell();
793
794        /** Collapses the tree with respect to the view cell partition,
795                i.e. leaves having the same view cell are collapsed.
796                @param node the root of the subtree to be collapsed
797                @param collapsed returns the number of collapsed nodes
798                @returns node of type leaf if the node could be collapsed,
799                this node otherwise
800        */
801        VspNode *CollapseTree(VspNode *node, int &collapsed);
802
803        /** Helper function revalidating the view cell leaf list after merge.
804        */
805        void RepairViewCellsLeafLists();
806
807        /** Evaluates tree stats in the BSP tree leafs.
808        */
809        void EvaluateLeafStats(const VspTraversalData &data);
810
811        /** Subdivides node using a best split priority queue.
812            @param tQueue the best split priority queue
813                @param splitCandidate the candidate for the next split
814                @param globalCriteriaMet if the global termination criteria were already met
815                @returns new root of the subtree
816        */
817        VspNode *Subdivide(SplitQueue &tQueue,
818                                           SubdivisionCandidate *splitCandidate,
819                                           const bool globalCriteriaMet);
820
821        /** Adds stats to subdivision log file.
822        */
823        void AddSubdivisionStats(const int viewCells,
824                                                         const float renderCostDecr,
825                                                         const float totalRenderCost,
826                                                         const float avgRenderCost);
827       
828        /** Subdivides leaf.
829                       
830                @param tData data object holding, e.g., a pointer to the leaf
831                @param frontData returns the data (e.g.,  pointer to the leaf) in front of the split plane
832                @param backData returns the data (e.g.,  pointer to the leaf) in the back of the split plane
833               
834                @param rays the polygons to be filtered
835                @param frontRays returns the polygons in front of the split plane
836       
837                @returns the root of the subdivision
838        */
839        VspInterior *SubdivideNode(const VspSubdivisionCandidate &sc,
840                                                           VspTraversalData &frontData,
841                               VspTraversalData &backData);
842
843        /** Selects an axis aligned for the next split.
844                @returns cost for this split
845        */
846        float SelectSplitPlane(const VspTraversalData &tData,
847                                                   AxisAlignedPlane &plane,
848                                                   float &pFront,
849                                                   float &pBack);
850
851        /** Sorts split candidates along the specified axis.
852                The split candidates are generated on possible visibility
853                events (i.e., where ray segments intersect the ray boundaries).
854                The sorted candidates are needed to compute the heuristics.
855
856                @param polys the input for choosing split candidates
857                @param axis the current split axis
858                @param splitCandidates returns sorted list of split candidates
859        */
860        void SortSubdivisionCandidates(const RayInfoContainer &rays,
861                                                                   const int axis,
862                                                                   float minBand,
863                                                                   float maxBand);
864
865        /** Evaluate render cost of this pvs.
866        */
867        float EvalPvsCost(const RayInfoContainer &rays) const;
868
869        int EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate) const;
870
871        /** Returns number of effective entries in the pvs.
872        */
873        int EvalPvsEntriesSize(const RayInfoContainer &rays) const;
874
875        int EvalPvsEntriesContribution(const VssRay &ray, const bool isTermination) const;
876
877        /** Computes best cost for axis aligned planes.
878        */
879        float EvalLocalCostHeuristics(const VspTraversalData &tData,
880                                                                  const AxisAlignedBox3 &box,
881                                                                  const int axis,
882                                                                  float &position,
883                                                                  const RayInfoContainer &usedRays);
884
885
886        //////////////////////////////////////////
887        // Helper function for computing heuristics
888
889        /** Evaluates the contribution to left and right pvs at a visibility event ve.
890                @param ve the visibility event
891                @param pvsLeft updates the left pvs
892                @param rightPvs updates the right pvs
893        */
894        void EvalHeuristics(const SortableEntry &ve, float &pvsLeft, float &pvsRight) const;
895
896        /** Evaluates contribution of min event to pvs
897        */
898        int EvalMinEventContribution(
899                const VssRay &ray, const bool isTermination) const;
900
901        /** Evaluates contribution of max event to pvs
902        */
903        int EvalMaxEventContribution(
904                const VssRay &ray, const bool isTermination) const;
905
906        /** Evaluates contribution of kd leaf when encountering a min event
907        */
908        int EvalMinEventContribution(KdLeaf *leaf) const;
909        /**  Evaluates contribution of kd leaf when encountering a max event
910        */
911        int EvalMaxEventContribution(KdLeaf *leaf) const;
912
913        /** Prepares objects for the heuristics.
914                @returns pvs size as seen by the rays.
915        */
916        float PrepareHeuristics(const RayInfoContainer &rays);
917       
918        /** Prepare a single ray for heuristics.
919        */
920        float PrepareHeuristics(const VssRay &ray, const bool isTermination);
921
922        /** Prepare a single kd leaf for heuristics.
923        */
924        float PrepareHeuristics(KdLeaf *leaf);
925
926       
927        /////////////////////////////////////////////////////////////////////////////
928
929
930        /** Subdivides the rays into front and back rays according to the split plane.
931               
932                @param plane the split plane
933                @param rays contains the rays to be split. The rays are
934                           distributed into front and back rays.
935                @param frontRays returns rays on the front side of the plane
936                @param backRays returns rays on the back side of the plane
937               
938                @returns the number of splits
939        */
940        int SplitRays(const AxisAlignedPlane &plane,
941                                  RayInfoContainer &rays,
942                              RayInfoContainer &frontRays,
943                                  RayInfoContainer &backRays) const;
944
945        void UpdatePvsEntriesContribution(
946                const VssRay &ray,
947                const bool isTermination,
948                const int cf,
949                float &frontPvs,
950                float &backPvs,
951                float &totalPvs) const;
952
953        /** Classfifies the object with respect to the
954                pvs of the front and back leaf and updates pvs size
955                accordingly.
956
957                @param obj the object to be added
958                @param cf the ray classification regarding the split plane
959                @param frontPvs returns the PVS of the front partition
960                @param backPvs returns the PVS of the back partition
961       
962        */
963        void UpdateContributionsToPvs(
964                const VssRay &ray,
965                const bool isTermination,
966                const int cf,
967                float &frontPvs,
968                float &backPvs,
969                float &totalPvs) const;
970
971        /** Evaluates the contribution for objects.
972        */
973        void UpdateContributionsToPvs(
974                Intersectable *obj,
975                const int cf,
976                float &frontPvs,
977                float &backPvs,
978                float &totalPvs) const;
979
980        /** Evaluates the contribution for bounding volume leaves.
981        */
982        void UpdateContributionsToPvs(
983                BvhLeaf *leaf,
984                const int cf,
985                float &frontPvs,
986                float &backPvs,
987                float &totalPvsm,
988                const bool countEntries = false) const;
989
990        /** Evaluates the contribution for kd leaves.
991        */
992        void UpdateContributionsToPvs(
993                KdLeaf *leaf,
994                const int cf,
995                float &frontPvs,
996                float &backPvs,
997                float &totalPvs) const;
998
999        /** Returns true if tree can be terminated.
1000        */
1001        bool LocalTerminationCriteriaMet(const VspTraversalData &data) const;
1002
1003        /** Returns true if global tree can be terminated.
1004        */
1005        bool GlobalTerminationCriteriaMet(const VspTraversalData &data) const;
1006
1007        /** Adds ray sample contributions to the PVS.
1008                @param sampleContributions the number contributions of the samples
1009                @param contributingSampels the number of contributing rays
1010               
1011        */
1012        void AddSamplesToPvs(VspLeaf *leaf,
1013                                                 const RayInfoContainer &rays,
1014                                                 float &sampleContributions,
1015                                                 int &contributingSamples);
1016
1017        /** Propagates valid flag up the tree.
1018        */
1019        void PropagateUpValidity(VspNode *node);
1020
1021        /** Writes the node to disk
1022                @note: should be implemented as visitor.
1023        */
1024        void ExportNode(VspNode *node, OUT_STREAM &stream);
1025
1026        /** Returns estimated memory usage of tree.
1027        */
1028        float GetMemUsage() const;
1029
1030        /** Updates view cell pvs of objects.
1031        */
1032        void ProcessViewCellObjects(ViewCell *parent,
1033                                                                ViewCell *front,
1034                                                                ViewCell *back) const;
1035
1036        void CreateViewCell(VspTraversalData &tData, const bool updatePvs);
1037
1038        /** Collect split candidates which are affected by the last split
1039                and must be reevaluated.
1040        */
1041        void CollectDirtyCandidates(VspSubdivisionCandidate *sc,
1042                                                                vector<SubdivisionCandidate *> &dirtyList,
1043                                                                const bool onlyUnmailed);
1044
1045        void CollectDirtyCandidate(const VssRay &ray,
1046                                                           const bool isTermination,
1047                                                           vector<SubdivisionCandidate *> &dirtyList,
1048                                                           const bool onlyUnmailed) const;
1049
1050        /** Rays will be clipped to the bounding box.
1051        */
1052        void PreprocessRays(const VssRayContainer &sampleRays, RayInfoContainer &rays);
1053
1054        /** Evaluate subdivision statistics.
1055        */
1056        void EvalSubdivisionStats(const SubdivisionCandidate &tData);
1057
1058        void PrepareConstruction(SplitQueue &tQueue,
1059                                                         const VssRayContainer &sampleRays,
1060                                                         RayInfoContainer &rays);
1061
1062        /** Evaluates pvs contribution of this ray.
1063        */
1064        int EvalContributionToPvs(const VssRay &ray, const bool isTermination) const;
1065
1066        /** Evaluates pvs contribution of a kd node.
1067        */
1068        int EvalContributionToPvs(KdLeaf *leaf) const;
1069
1070        /** Creates new root of hierarchy and computes bounding box.
1071                Has to be called before the preparation of the subdivision.
1072        */
1073        void Initialise(const VssRayContainer &rays,
1074                                        AxisAlignedBox3 *forcedBoundingBox);
1075
1076        int CompressObjects();
1077
1078        int CompressObjects(VspLeaf *leaf);
1079
1080protected:
1081
1082        /// pointer to the hierarchy of view cells
1083        ViewCellsTree *mViewCellsTree;
1084
1085        HierarchyManager *mHierarchyManager;
1086        //OspTree *mOspTree;
1087        //bool mUseKdPvsForHeuristics;
1088       
1089        ViewCellsManager *mViewCellsManager;
1090       
1091        vector<SortableEntry> *mLocalSubdivisionCandidates;
1092
1093        /// Pointer to the root of the tree
1094        VspNode *mRoot;
1095               
1096        VspTreeStatistics mVspStats;
1097       
1098        /// View cell corresponding to the space outside the valid view space
1099        VspViewCell *mOutOfBoundsCell;
1100
1101        /// box around the whole view domain
1102        AxisAlignedBox3 mBoundingBox;
1103
1104
1105        //-- local termination
1106
1107        /// minimal number of rays before subdivision termination
1108        int mTermMinRays;
1109        /// maximal possible depth
1110        int mTermMaxDepth;
1111        /// mininum probability
1112        float mTermMinProbability;
1113        /// mininum PVS
1114        int mTermMinPvs;
1115        /// maximal contribution per ray
1116        float mTermMaxRayContribution;
1117        /// maximal acceptable cost ratio
1118        float mTermMaxCostRatio;
1119        /// tolerance value indicating how often the max cost ratio can be failed
1120        int mTermMissTolerance;
1121
1122
1123        //-- global criteria
1124        float mTermMinGlobalCostRatio;
1125        int mTermGlobalCostMissTolerance;
1126       
1127
1128        /// maximal number of view cells
1129        int mMaxViewCells;
1130        /// maximal tree memory
1131        float mMaxMemory;
1132        /// the tree is out of memory
1133        bool mOutOfMemory;
1134
1135        ////////////
1136        //-- split heuristics based parameters
1137       
1138        bool mUseCostHeuristics;
1139        /// balancing factor for PVS criterium
1140        float mCtDivCi;
1141        /// if only driving axis should be used for split
1142        bool mOnlyDrivingAxis;
1143        /// if random split axis should be used
1144        bool mUseRandomAxis;
1145        /// if vsp bsp tree should simulate octree
1146        bool mCirculatingAxis;
1147        /// minimal relative position where the split axis can be placed
1148        float mMinBand;
1149        /// maximal relative position where the split axis can be placed
1150        float mMaxBand;
1151
1152
1153        /// current time stamp (used for keeping split history)
1154        int mTimeStamp;
1155        // if rays should be stored in leaves
1156        bool mStoreRays;
1157
1158        /// epsilon for geometric comparisons
1159        float mEpsilon;
1160
1161        /// subdivision stats output file
1162        ofstream  mSubdivisionStats;
1163        /// keeps track of cost during subdivision
1164        float mTotalCost;
1165        int mPvsEntries;
1166        /// keeps track of overall pvs size during subdivision
1167        int mTotalPvsSize;
1168        /// number of currenly generated view cells
1169        int mCreatedViewCells;
1170
1171        /// weight between render cost decrease and node render cost
1172        float mRenderCostDecreaseWeight;
1173
1174        int mMaxTests;
1175
1176        /// constant value for driving the heuristics
1177        float mMemoryConst;
1178};
1179
1180
1181}
1182
1183#endif
Note: See TracBrowser for help on using the repository browser.