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

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