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

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