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

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