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

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