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

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