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

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