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

Revision 2224, 29.2 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, SubdivisionCandidateContainer &dirtyList)
519                {
520                        VspNode *n = sVspTree->Subdivide(splitQueue, this, terminationCriteriaMet);
521                       
522                        // local or global termination criteria failed
523                        const bool success = !n->IsLeaf();     
524
525                        if (success)
526                                CollectDirtyCandidates(dirtyList, true);
527
528                        return success;
529                }
530
531                void CollectDirtyCandidates(SubdivisionCandidateContainer &dirtyList,
532                                                                        const bool onlyUnmailed)
533                {
534                        sVspTree->CollectDirtyCandidates(this, dirtyList, onlyUnmailed);
535                }
536
537                VspSubdivisionCandidate(const AxisAlignedPlane &plane, const VspTraversalData &tData):
538                        mSplitPlane(plane), mParentData(tData)
539                {}
540
541                float GetPriority() const
542                {
543                        return mPriority;
544                }
545
546                ////////////////////
547
548                static VspTree* sVspTree;
549
550                /// the current split plane
551                AxisAlignedPlane mSplitPlane;
552                /// parent node traversal data
553                VspTraversalData mParentData;
554       
555                float mCorrectedFrontPvs;
556                float mCorrectedBackPvs;
557
558                float mFrontPvs;
559                float mBackPvs;
560
561                float mCorrectedFrontRenderCost;
562                float mCorrectedBackRenderCost;
563               
564                float mFrontRenderCost;
565                float mBackRenderCost;
566        };
567
568        /** Struct for traversing line segment.
569        */
570        struct LineTraversalData
571        {
572                VspNode *mNode;
573                Vector3 mExitPoint;
574                float mMaxT;
575   
576                LineTraversalData () {}
577                LineTraversalData (VspNode *n, const Vector3 &p, const float maxt):
578                mNode(n), mExitPoint(p), mMaxT(maxt) {}
579        };
580
581        /** Default constructor creating an empty tree.
582        */
583        VspTree();
584        /** Default destructor.
585        */
586        ~VspTree();
587
588        /** Returns BSP Tree statistics.
589        */
590        const VspTreeStatistics &GetStatistics() const;
591 
592        /** Returns bounding box of the specified node.
593        */
594        AxisAlignedBox3 GetBoundingBox(VspNode *node) const;
595
596        /** Returns list of BSP leaves with pvs smaller than
597                a certain threshold.
598                @param onlyUnmailed if only the unmailed leaves should be considered
599                @param maxPvs the maximal pvs of a leaf to be added (-1 means unlimited)
600        */
601        void CollectLeaves(vector<VspLeaf *> &leaves,
602                                           const bool onlyUnmailed = false,
603                                           const int maxPvs = -1) const;
604
605        /** Returns box which bounds the whole tree.
606        */
607        AxisAlignedBox3 GetBoundingBox() const;
608
609        /** Returns root of the view space partitioning tree.
610        */
611        VspNode *GetRoot() const;
612
613        /** Collects the leaf view cells of the tree
614                @param viewCells returns the view cells
615        */
616        void CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const;
617
618        /** A ray is cast possible intersecting the tree.
619                @param the ray that is cast.
620                @returns the number of intersections with objects stored in the tree.
621        */
622        int CastRay(Ray &ray);
623
624
625        /** finds neighbouring leaves of this tree node.
626        */
627        int FindNeighbors(VspLeaf *n,
628                                          vector<VspLeaf *> &neighbors,
629                                          const bool onlyUnmailed) const;
630
631        /** Returns random leaf of BSP tree.
632                @param halfspace defines the halfspace from which the leaf is taken.
633        */
634        VspLeaf *GetRandomLeaf(const Plane3 &halfspace);
635
636        /** Returns random leaf of BSP tree.
637                @param onlyUnmailed if only unmailed leaves should be returned.
638        */
639        VspLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
640
641        /** Returns epsilon of this tree.
642        */
643        float GetEpsilon() const;
644
645        /** Casts line segment into the tree.
646                @param origin the origin of the line segment
647                @param termination the end point of the line segment
648                @returns view cells intersecting the line segment.
649        */
650    int CastLineSegment(const Vector3 &origin,
651                                                const Vector3 &termination,
652                                                ViewCellContainer &viewcells,
653                                                const bool useMailboxing = true);
654
655               
656        /** Sets pointer to view cells manager.
657        */
658        void SetViewCellsManager(ViewCellsManager *vcm);
659
660        /** Returns view cell the current point is located in.
661                @param point the current view point
662                @param active if currently active view cells should be returned or
663                elementary view cell
664        */
665        ViewCell *GetViewCell(const Vector3 &point, const bool active = false);
666
667
668        /** Returns true if this view point is in a valid view space,
669                false otherwise.
670        */
671        bool ViewPointValid(const Vector3 &viewPoint) const;
672
673        /** Returns view cell corresponding to
674                the invalid view space.
675        */
676        VspViewCell *GetOutOfBoundsCell();
677
678        /** Writes tree to output stream
679        */
680        bool Export(OUT_STREAM &stream);
681
682        /** Casts beam, i.e. a 5D frustum of rays, into tree.
683                Tests conservative using the bounding box of the nodes.
684                @returns number of view cells it intersected
685        */
686        int CastBeam(Beam &beam);
687
688        /** Checks if tree validity-flags are right
689                with respect to view cell valitiy.
690                If not, marks subtree as invalid.
691        */
692        void ValidateTree();
693
694        /** Invalid view cells are added to the unbounded space
695        */
696        void CollapseViewCells();
697
698        /** Collects rays stored in the leaves.
699        */
700        void CollectRays(VssRayContainer &rays);
701
702        /** Intersects box with the tree and returns the number of intersected boxes.
703                @returns number of view cells found
704        */
705        int ComputeBoxIntersections(const AxisAlignedBox3 &box,
706                                                                ViewCellContainer &viewCells) const;
707
708        /** Returns view cells of this ray, either taking precomputed cells
709                or by recomputation.
710        */
711        void GetViewCells(const VssRay &ray, ViewCellContainer &viewCells);
712
713        /** Returns view cells tree.
714        */
715        ViewCellsTree *GetViewCellsTree() const { return mViewCellsTree; }
716
717        /** Sets the view cells tree.
718        */
719        void SetViewCellsTree(ViewCellsTree *vt) { mViewCellsTree = vt; }
720
721#if WORK_WITH_VIEWCELLS
722        /** Remove the references of the parent view cell from the kd nodes associated with
723                the objects.
724        */
725        void RemoveParentViewCellReferences(ViewCell *parent) const;
726
727        /** Adds references to the view cell to the kd nodes associated with the objects.
728        */
729        void AddViewCellReferences(ViewCell *vc) const;
730#endif
731
732        VspNode *SubdivideAndCopy(SplitQueue &tQueue, SubdivisionCandidate *splitCandidate);
733
734        PerfTimer mSortTimer;
735        PerfTimer mSplitTimer;
736        PerfTimer mNodeTimer;
737        PerfTimer mSubdivTimer;
738        PerfTimer mEvalTimer;
739        PerfTimer mPlaneTimer;
740        PerfTimer mViewCellsTimer;
741
742protected:
743
744        // --------------------------------------------------------------
745        // For sorting objects
746        // --------------------------------------------------------------
747        struct SortableEntry
748        {
749                enum EType
750                {
751                        ERayMin,
752                        ERayMax
753                };
754
755                int type;
756                float value;
757                VssRay *ray;
758 
759                SortableEntry() {}
760                SortableEntry(const int t, const float v, VssRay *r):
761                type(t), value(v), ray(r)
762                {
763                }
764               
765                friend inline bool operator<(const SortableEntry &a, const SortableEntry &b)
766                {       // prefer max event
767                        //if (EpsilonEqual(a.value, b.value, 0.0001f))
768                        //      return (a.type == ERayMax);
769
770                        return (a.value < b.value);
771                }
772        };
773
774        /** faster evaluation of split plane cost for kd axis aligned cells.
775        */
776        float EvalLocalSplitCost(const VspTraversalData &data,
777                                                         const AxisAlignedBox3 &box,
778                                                         const int axis,
779                                                         const float &position,
780                                                         float &pFront,
781                                                         float &pBack) const;
782
783        void ComputeBoundingBox(const VssRayContainer &rays,
784                                                        AxisAlignedBox3 *forcedBoundingBox);
785
786        /** Evaluates candidate for splitting.
787        */
788        void EvalSubdivisionCandidate(VspSubdivisionCandidate &splitData,
789                                                                  bool computeSplitPlane = true);
790
791        /** Evaluates render cost decrease of next split.
792        */
793        float EvalRenderCostDecrease(VspSubdivisionCandidate &splitData,
794                                                                 float &normalizedOldRenderCost) const;
795
796        /** Collects view cells in the subtree under root.
797        */
798        void CollectViewCells(VspNode *root,
799                                                  bool onlyValid,
800                                                  ViewCellContainer &viewCells,
801                                                  bool onlyUnmailed = false) const;
802
803        /** Returns view cell corresponding to
804                the invalid view space. If it does not exist, it is created.
805        */
806        VspViewCell *GetOrCreateOutOfBoundsCell();
807
808        /** Collapses the tree with respect to the view cell partition,
809                i.e. leaves having the same view cell are collapsed.
810                @param node the root of the subtree to be collapsed
811                @param collapsed returns the number of collapsed nodes
812                @returns node of type leaf if the node could be collapsed,
813                this node otherwise
814        */
815        VspNode *CollapseTree(VspNode *node, int &collapsed);
816
817        /** Helper function revalidating the view cell leaf list after merge.
818        */
819        void RepairViewCellsLeafLists();
820
821        /** Evaluates tree stats in the BSP tree leafs.
822        */
823        void EvaluateLeafStats(const VspTraversalData &data);
824
825        /** Subdivides node using a best split priority queue.
826            @param tQueue the best split priority queue
827                @param splitCandidate the candidate for the next split
828                @param globalCriteriaMet if the global termination criteria were already met
829                @returns new root of the subtree
830        */
831        VspNode *Subdivide(SplitQueue &tQueue,
832                                           SubdivisionCandidate *splitCandidate,
833                                           const bool globalCriteriaMet);
834
835        /** Adds stats to subdivision log file.
836        */
837        void AddSubdivisionStats(const int viewCells,
838                                                         const float renderCostDecr,
839                                                         const float totalRenderCost,
840                                                         const float avgRenderCost);
841       
842        /** Subdivides leaf.
843                       
844                @param tData data object holding, e.g., a pointer to the leaf
845                @param frontData returns the data (e.g., pointer to the leaf) in front of the split plane
846                @param backData returns the data (e.g., pointer to the leaf) in the back of the split plane
847               
848                @param rays the polygons to be filtered
849                @param frontRays returns the polygons in front of the split plane
850       
851                @returns the root of the subdivision
852        */
853        VspInterior *SubdivideNode(const VspSubdivisionCandidate &sc,
854                                                           VspTraversalData &frontData,
855                               VspTraversalData &backData);
856
857        /** Selects an axis aligned for the next split.
858                @returns cost for this split
859        */
860        float SelectSplitPlane(const VspTraversalData &tData,
861                                                   AxisAlignedPlane &plane,
862                                                   float &pFront,
863                                                   float &pBack);
864
865        /** Sorts split candidates along the specified axis.
866                The split candidates are generated on possible visibility
867                events (i.e., where ray segments intersect the ray boundaries).
868                The sorted candidates are needed to compute the heuristics.
869
870                @param polys the input for choosing split candidates
871                @param axis the current split axis
872                @param splitCandidates returns sorted list of split candidates
873        */
874        void SortSubdivisionCandidates(const RayInfoContainer &rays,
875                                                                   const int axis,
876                                                                   float minBand,
877                                                                   float maxBand);
878
879        /** Evaluate render cost of this pvs.
880        */
881        float EvalPvsCost(const RayInfoContainer &rays) const;
882
883        int EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate) const;
884
885        /** Returns number of effective entries in the pvs.
886        */
887        int EvalPvsEntriesSize(const RayInfoContainer &rays) const;
888
889        int EvalPvsEntriesContribution(const VssRay &ray, const bool isTermination) const;
890
891        /** Computes best cost for axis aligned planes.
892        */
893        float EvalLocalCostHeuristics(const VspTraversalData &tData,
894                                                                  const AxisAlignedBox3 &box,
895                                                                  const int axis,
896                                                                  float &position,
897                                                                  const RayInfoContainer &usedRays);
898
899
900        //////////////////////////////////////////
901        // Helper function for computing heuristics
902
903        /** Evaluates the contribution to left and right pvs at a visibility event ve.
904                @param ve the visibility event
905                @param pvsLeft updates the left pvs
906                @param rightPvs updates the right pvs
907        */
908        inline void EvalHeuristics(const SortableEntry &ve, float &pvsLeft, float &pvsRight) const;
909
910        /** Evaluates contribution of min event to pvs
911        */
912        inline int EvalMinEventContribution(const VssRay &ray, const bool isTermination) const;
913
914        /** Evaluates contribution of max event to pvs
915        */
916        inline int EvalMaxEventContribution(
917                const VssRay &ray, const bool isTermination) const;
918
919        /** Evaluates contribution of kd leaf when encountering a min event
920        */
921        inline int EvalMinEventContribution(KdLeaf *leaf) const;
922        /**  Evaluates contribution of kd leaf when encountering a max event
923        */
924        inline int EvalMaxEventContribution(KdLeaf *leaf) const;
925
926        /** Prepares objects for the heuristics.
927                @returns pvs size as seen by the rays.
928        */
929        float PrepareHeuristics(const RayInfoContainer &rays);
930       
931        /** Prepare a single ray for heuristics.
932        */
933        float PrepareHeuristics(const VssRay &ray, const bool isTermination);
934
935        /** Prepare a single kd leaf for heuristics.
936        */
937        float PrepareHeuristics(KdLeaf *leaf);
938
939        void EvalMinMaxDepth(int &minDepth, int &maxDepth);
940
941        /////////////////////////////////////////////////////////////////////////////
942
943
944        /** Subdivides the rays into front and back rays according to the split plane.
945               
946                @param plane the split plane
947                @param rays contains the rays to be split. The rays are
948                           distributed into front and back rays.
949                @param frontRays returns rays on the front side of the plane
950                @param backRays returns rays on the back side of the plane
951               
952                @returns the number of splits
953        */
954        int SplitRays(const AxisAlignedPlane &plane,
955                                  RayInfoContainer &rays,
956                              RayInfoContainer &frontRays,
957                                  RayInfoContainer &backRays) const;
958
959        inline void UpdatePvsEntriesContribution(
960                const VssRay &ray,
961                const bool isTermination,
962                const int cf,
963                float &frontPvs,
964                float &backPvs,
965                float &totalPvs) const;
966
967        /** Classfifies the object with respect to the
968                pvs of the front and back leaf and updates pvs size
969                accordingly.
970
971                @param obj the object to be added
972                @param cf the ray classification regarding the split plane
973                @param frontPvs returns the PVS of the front partition
974                @param backPvs returns the PVS of the back partition
975       
976        */
977        inline void UpdateContributionsToPvs(
978                const VssRay &ray,
979                const bool isTermination,
980                const int cf,
981                float &frontPvs,
982                float &backPvs,
983                float &totalPvs) const;
984
985        /** Evaluates the contribution for objects.
986        */
987        inline void UpdateContributionsToPvs(
988                Intersectable *obj,
989                const int cf,
990                float &frontPvs,
991                float &backPvs,
992                float &totalPvs) const;
993
994        /** Evaluates the contribution for bounding volume leaves.
995        */
996        inline void UpdateContributionsToPvs(
997                BvhLeaf *leaf,
998                const int cf,
999                float &frontPvs,
1000                float &backPvs,
1001                float &totalPvs,
1002                const bool countEntries) const;
1003
1004        /** Evaluates the contribution for kd leaves.
1005        */
1006        inline void UpdateContributionsToPvs(
1007                KdLeaf *leaf,
1008                const int cf,
1009                float &frontPvs,
1010                float &backPvs,
1011                float &totalPvs) const;
1012
1013        /** Returns true if tree can be terminated.
1014        */
1015        inline bool LocalTerminationCriteriaMet(const VspTraversalData &data) const;
1016
1017        /** Returns true if global tree can be terminated.
1018        */
1019        inline bool GlobalTerminationCriteriaMet(const VspTraversalData &data) const;
1020
1021        /** Adds ray sample contributions to the PVS.
1022                @param sampleContributions the number contributions of the samples
1023                @param contributingSampels the number of contributing rays
1024               
1025        */
1026        void AddSamplesToPvs(VspLeaf *leaf,
1027                                                 const RayInfoContainer &rays,
1028                                                 float &sampleContributions,
1029                                                 int &contributingSamples);
1030
1031        /** Propagates valid flag up the tree.
1032        */
1033        void PropagateUpValidity(VspNode *node);
1034
1035        /** Writes the node to disk
1036                @note: should be implemented as visitor.
1037        */
1038        void ExportNode(VspNode *node, OUT_STREAM &stream);
1039
1040        /** Returns estimated memory usage of tree.
1041        */
1042        float GetMemUsage() const;
1043
1044        /** Updates view cell pvs of objects.
1045        */
1046        void ProcessViewCellObjects(ViewCell *parent,
1047                                                                ViewCell *front,
1048                                                                ViewCell *back) const;
1049
1050        void CreateViewCell(VspTraversalData &tData, const bool updatePvs);
1051
1052        /** Collect split candidates which are affected by the last split
1053                and must be reevaluated.
1054        */
1055        void CollectDirtyCandidates(VspSubdivisionCandidate *sc,
1056                                                                vector<SubdivisionCandidate *> &dirtyList,
1057                                                                const bool onlyUnmailed);
1058
1059        void CollectDirtyCandidate(const VssRay &ray,
1060                                                           const bool isTermination,
1061                                                           vector<SubdivisionCandidate *> &dirtyList,
1062                                                           const bool onlyUnmailed) const;
1063
1064        /** Rays will be clipped to the bounding box.
1065        */
1066        void PreprocessRays(const VssRayContainer &sampleRays, RayInfoContainer &rays);
1067
1068        /** Evaluate subdivision statistics.
1069        */
1070        void EvalSubdivisionStats(const SubdivisionCandidate &tData);
1071
1072        void PrepareConstruction(SplitQueue &tQueue,
1073                                                         const VssRayContainer &sampleRays,
1074                                                         RayInfoContainer &rays);
1075
1076        /** Evaluates pvs contribution of this ray.
1077        */
1078        int EvalContributionToPvs(const VssRay &ray, const bool isTermination) const;
1079
1080        /** Evaluates pvs contribution of a kd node.
1081        */
1082        int EvalContributionToPvs(KdLeaf *leaf) const;
1083
1084        /** Creates new root of hierarchy and computes bounding box.
1085                Has to be called before the preparation of the subdivision.
1086        */
1087        void Initialise(const VssRayContainer &rays,
1088                                        AxisAlignedBox3 *forcedBoundingBox);
1089
1090        int CompressObjects();
1091
1092        int CompressObjects(VspLeaf *leaf);
1093
1094        void TraverseRayPacket();
1095
1096protected:
1097
1098        /// pointer to the hierarchy of view cells
1099        ViewCellsTree *mViewCellsTree;
1100
1101        HierarchyManager *mHierarchyManager;
1102        BvHierarchy *mBvHierarchy;
1103
1104        //OspTree *mOspTree;
1105        //bool mUseKdPvsForHeuristics;
1106       
1107        ViewCellsManager *mViewCellsManager;
1108       
1109        vector<SortableEntry> *mLocalSubdivisionCandidates;
1110
1111        /// Pointer to the root of the tree
1112        VspNode *mRoot;
1113               
1114        VspTreeStatistics mVspStats;
1115       
1116        /// View cell corresponding to the space outside the valid view space
1117        VspViewCell *mOutOfBoundsCell;
1118
1119        /// box around the whole view domain
1120        AxisAlignedBox3 mBoundingBox;
1121
1122
1123        //-- local termination
1124
1125        /// minimal number of rays before subdivision termination
1126        int mTermMinRays;
1127        /// maximal possible depth
1128        int mTermMaxDepth;
1129        /// mininum probability
1130        float mTermMinProbability;
1131        /// mininum PVS
1132        int mTermMinPvs;
1133        /// maximal contribution per ray
1134        float mTermMaxRayContribution;
1135        /// maximal acceptable cost ratio
1136        float mTermMaxCostRatio;
1137        /// tolerance value indicating how often the max cost ratio can be failed
1138        int mTermMissTolerance;
1139
1140
1141        //-- global criteria
1142        float mTermMinGlobalCostRatio;
1143        int mTermGlobalCostMissTolerance;
1144       
1145
1146        /// maximal number of view cells
1147        int mMaxViewCells;
1148        /// maximal tree memory
1149        float mMaxMemory;
1150        /// the tree is out of memory
1151        bool mOutOfMemory;
1152
1153        ////////////
1154        //-- split heuristics based parameters
1155       
1156        bool mUseCostHeuristics;
1157        /// balancing factor for PVS criterium
1158        float mCtDivCi;
1159        /// if only driving axis should be used for split
1160        bool mOnlyDrivingAxis;
1161        /// if random split axis should be used
1162        bool mUseRandomAxis;
1163        /// if vsp bsp tree should simulate octree
1164        bool mCirculatingAxis;
1165        /// minimal relative position where the split axis can be placed
1166        float mMinBand;
1167        /// maximal relative position where the split axis can be placed
1168        float mMaxBand;
1169
1170
1171        /// current time stamp (used for keeping split history)
1172        int mTimeStamp;
1173        // if rays should be stored in leaves
1174        bool mStoreRays;
1175
1176        /// epsilon for geometric comparisons
1177        float mEpsilon;
1178
1179        /// subdivision stats output file
1180        std::ofstream mSubdivisionStats;
1181        /// keeps track of cost during subdivision
1182        float mTotalCost;
1183        int mPvsEntries;
1184        /// keeps track of overall pvs size during subdivision
1185        int mTotalPvsSize;
1186        /// number of currenly generated view cells
1187        int mCreatedViewCells;
1188
1189        /// weight between render cost decrease and node render cost
1190        float mRenderCostDecreaseWeight;
1191
1192        int mMaxTests;
1193
1194        /// constant value for driving the heuristics
1195        float mMemoryConst;
1196};
1197
1198
1199}
1200
1201#endif
Note: See TracBrowser for help on using the repository browser.