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

Revision 2210, 29.1 KB checked in by mattausch, 17 years ago (diff)

improved performance of osp

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