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

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