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

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