source: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h @ 578

Revision 578, 23.8 KB checked in by mattausch, 18 years ago (diff)

added upper and lower boundary for pvs penalty in heuristics

Line 
1#ifndef _VspBspTree_H__
2#define _VspBspTree_H__
3
4#include "Mesh.h"
5#include "Containers.h"
6#include "Polygon3.h"
7#include <stack>
8#include "Statistics.h"
9#include "VssRay.h"
10#include "RayInfo.h"
11#include "ViewCellBsp.h"
12
13class ViewCell;
14//class BspViewCell;
15class Plane3;
16class VspBspTree; 
17class BspInterior;
18class BspNode;
19class AxisAlignedBox3;
20class Ray;
21class ViewCellsStatistics;
22class ViewCellsManager;
23class BspMergeCandidate;
24class Beam;
25
26struct BspRay;
27
28
29/**
30        This is a view space partitioning specialised BSPtree. 
31        There are no polygon splits, but we split the sample rays.
32        The candidates for the next split plane are evaluated only
33        by checking the sampled visibility information.
34        The polygons are employed merely as candidates for the next split planes.
35*/
36class VspBspTree
37{
38        friend class ViewCellsParseHandlers;
39        friend class VspBspViewCellsManager;
40public:
41       
42        /** Additional data which is passed down the BSP tree during traversal.
43        */
44        struct VspBspTraversalData
45        { 
46                /// the current node
47                BspNode *mNode;
48                /// polygonal data for splitting
49                PolygonContainer *mPolygons;
50                /// current depth
51                int mDepth;
52                /// rays piercing this node
53                RayInfoContainer *mRays;
54                /// the probability that this node contains view point
55                float mProbability;
56                /// geometry of node as induced by planes
57                BspNodeGeometry *mGeometry;
58                /// pvs size
59                int mPvs;
60                /// how often this branch has missed the max-cost ratio
61                int mMaxCostMisses;
62                /// if this node is a kd-node (i.e., boundaries are axis aligned
63                bool mIsKdNode;
64                /// bounding box of current view space.
65                ///AxisAlignedBox3 mBbox;
66               
67                /** Returns average ray contribution.
68                */
69                float GetAvgRayContribution() const
70                {
71                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
72                }
73
74
75                VspBspTraversalData():
76                mNode(NULL),
77                mPolygons(NULL),
78                mDepth(0),
79                mRays(NULL),
80                mPvs(0),
81                mProbability(0.0),
82                mGeometry(NULL),
83                mMaxCostMisses(0),
84                mIsKdNode(false)
85                {}
86               
87                VspBspTraversalData(BspNode *node,
88                                                        PolygonContainer *polys,
89                                                        const int depth,
90                                                        RayInfoContainer *rays,
91                                                        const int pvs,
92                                                        const float p,
93                                                        BspNodeGeometry *geom):
94                mNode(node),
95                mPolygons(polys),
96                mDepth(depth),
97                mRays(rays),
98                mPvs(pvs),
99                mProbability(p),
100                mGeometry(geom),
101                mMaxCostMisses(0),
102                mIsKdNode(false)
103                {}
104
105                VspBspTraversalData(PolygonContainer *polys,
106                                                        const int depth,
107                                                        RayInfoContainer *rays,
108                                                        BspNodeGeometry *geom):
109                mNode(NULL),
110                mPolygons(polys),
111                mDepth(depth),
112                mRays(rays),
113                mPvs(0),
114                mProbability(0),
115                mGeometry(geom),
116                mMaxCostMisses(0),
117                mIsKdNode(false)
118                {}
119
120                /** Returns cost of the traversal data.
121                */
122                float GetCost() const
123                {
124#if 1
125                        return mPvs * mProbability;
126#endif
127#if 0
128                        return (float)(mPvs * (int)mRays->size());
129#endif
130#if 0
131                        return (float)mPvs;
132#endif
133#if 0
134                        return mProbabiliy * (float)mRays->size();
135#endif
136                }
137
138                // deletes contents and sets them to NULL
139                void Clear()
140                {
141                        DEL_PTR(mPolygons);
142                        DEL_PTR(mRays);
143                        DEL_PTR(mGeometry);
144                }
145
146                friend bool operator<(const VspBspTraversalData &a, const VspBspTraversalData &b)
147                {
148                        return a.GetCost() < b.GetCost();
149                }
150    };
151       
152        typedef std::priority_queue<VspBspTraversalData> VspBspTraversalStack;
153        //typedef std::stack<VspBspTraversalData> VspBspTraversalStack;
154
155        /** Default constructor creating an empty tree.
156        */
157        VspBspTree();
158
159        /** Default destructor.
160        */
161        ~VspBspTree();
162
163        /** Returns BSP Tree statistics.
164        */
165        const BspTreeStatistics &GetStatistics() const;
166 
167
168        /** Constructs the tree from a given set of rays.
169                @param sampleRays the set of sample rays the construction is based on
170                @param viewCells if not NULL, new view cells are
171                created in the leafs and stored in the container
172        */
173        void Construct(const VssRayContainer &sampleRays,
174                                   AxisAlignedBox3 *forcedBoundingBox);
175
176        /** Returns list of BSP leaves with pvs smaller than
177                a certain threshold.
178                @param onlyUnmailed if only the unmailed leaves should be considered
179                @param maxPvs the maximal pvs (-1 means unlimited)
180        */
181        void CollectLeaves(vector<BspLeaf *> &leaves,
182                                           const bool onlyUnmailed = false,
183                                           const int maxPvs = -1) const;
184
185        /** Returns box which bounds the whole tree.
186        */
187        AxisAlignedBox3 GetBoundingBox()const;
188
189        /** Returns root of BSP tree.
190        */
191        BspNode *GetRoot() const;
192
193        /** Collects the leaf view cells of the tree
194                @param viewCells returns the view cells
195        */
196        void CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const;
197
198        /** A ray is cast possible intersecting the tree.
199                @param the ray that is cast.
200                @returns the number of intersections with objects stored in the tree.
201        */
202        int CastRay(Ray &ray);
203
204        /// bsp tree construction types
205        enum {FROM_INPUT_VIEW_CELLS, FROM_SCENE_GEOMETRY, FROM_SAMPLES};
206
207        /** finds neighbouring leaves of this tree node.
208        */
209        int FindNeighbors(BspNode *n,
210                                          vector<BspLeaf *> &neighbors,
211                                          const bool onlyUnmailed) const;
212
213        /** Constructs geometry associated with the half space intersections
214                leading to this node.
215        */
216        void ConstructGeometry(BspNode *n, BspNodeGeometry &geom) const;
217       
218        /** Construct geometry of view cell.
219        */
220        void ConstructGeometry(BspViewCell *vc, BspNodeGeometry &geom) const;
221
222        /** Returns random leaf of BSP tree.
223                @param halfspace defines the halfspace from which the leaf is taken.
224        */
225        BspLeaf *GetRandomLeaf(const Plane3 &halfspace);
226
227        /** Returns random leaf of BSP tree.
228                @param onlyUnmailed if only unmailed leaves should be returned.
229        */
230        BspLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
231
232        /** Returns epsilon of this tree.
233        */
234        float GetEpsilon() const;
235
236        /** Casts line segment into the tree.
237                @param origin the origin of the line segment
238                @param termination the end point of the line segment
239                @returns view cells intersecting the line segment.
240        */
241    int CastLineSegment(const Vector3 &origin,
242                                                const Vector3 &termination,
243                                                ViewCellContainer &viewcells);
244
245               
246        /** Sets pointer to view cells manager.
247        */
248        void SetViewCellsManager(ViewCellsManager *vcm);
249
250        /** Returns distance from node 1 to node 2.
251        */
252        int TreeDistance(BspNode *n1, BspNode *n2) const;
253
254        /** Merges view cells according to some cost heuristics.
255        */
256        int MergeViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
257       
258        /** Refines view cells using shuffling, i.e., border leaves
259                of two view cells are exchanged if the resulting view cells
260                are tested to be "better" than the old ones.
261                @returns number of refined view cells
262        */
263        int RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
264
265        /** Collapses the tree with respect to the view cell partition.
266                @returns number of collapsed nodes
267        */
268        int CollapseTree();
269
270        /** Returns view cell the current point is located in.
271        */
272        ViewCell *GetViewCell(const Vector3 &point);
273
274        /** Constructs bsp rays for post processing and visualization.
275        */
276        void ConstructBspRays(vector<BspRay *> &bspRays,
277                                                  const VssRayContainer &rays);
278       
279        /** Merge view cells of leaves l1 and l2.
280        */
281        bool MergeViewCells(BspLeaf *l1, BspLeaf *l2); //const;
282
283        /** Returns true if this view point is in a valid view space,
284                false otherwise.
285        */
286        bool ViewPointValid(const Vector3 &viewPoint) const;
287
288        /** Returns view cell corresponding to
289                the invalid view space.
290        */
291        BspViewCell *GetOutOfBoundsCell();
292
293        /** Writes tree to output stream
294        */
295        bool Export(ofstream &stream);
296
297        /** Casts beam, i.e. a 5D frustum of rays, into tree.
298                Tests conservative using the bounding box of the nodes.
299                @returns number of view cells it intersected
300        */
301        int CastBeam(Beam &beam);
302
303        void CollectViewCells(BspNode *root,
304                                                  bool onlyValid,
305                                                  ViewCellContainer &viewCells,
306                                                  bool onlyUnmailed = false) const;
307
308       
309        /** Checks if tree validity-flags are right
310                with respect to view cell valitiy.
311                If not, marks subtree as invalid.
312        */
313        void ValidateTree();
314
315        /** Invalid view cells are added to the unbounded space
316        */
317        void CollapseViewCells();
318
319protected:
320
321        // --------------------------------------------------------------
322        // For sorting objects
323        // --------------------------------------------------------------
324        struct SortableEntry
325        {
326                enum EType
327                {
328                        ERayMin,
329                        ERayMax
330                };
331
332                int type;
333                float value;
334                VssRay *ray;
335 
336                SortableEntry() {}
337                SortableEntry(const int t, const float v, VssRay *r):type(t),
338                                          value(v), ray(r)
339                {
340                }
341               
342                friend bool operator<(const SortableEntry &a, const SortableEntry &b)
343                {
344                        return a.value < b.value;
345                }
346        };
347
348        /** faster evaluation of split plane cost for kd axis aligned cells.
349        */
350        float EvalAxisAlignedSplitCost(const VspBspTraversalData &data,
351                                                                   const AxisAlignedBox3 &box,
352                                                                   const int axis,
353                                                                   const float &position,
354                                                                   float &pFront,
355                                                                   float &pBack) const;
356
357        /** Returns view cell corresponding to
358                the invalid view space. If it does not exist, it is created.
359        */
360        BspViewCell *GetOrCreateOutOfBoundsCell();
361
362        /** Collapses the tree with respect to the view cell partition,
363                i.e. leaves having the same view cell are collapsed.
364                @param node the root of the subtree to be collapsed
365                @param collapsed returns the number of collapsed nodes
366                @returns node of type leaf if the node could be collapsed,
367                this node otherwise
368        */
369        BspNode *CollapseTree(BspNode *node, int &collapsed);
370
371        /** Shuffles the leaves, i.e., tests if exchanging
372                the leaves helps in improving the view cells.
373        */
374        bool ShuffleLeaves(BspLeaf *leaf1, BspLeaf *leaf2) const;
375
376        /** Helper function revalidating the view cell leaf list after merge.
377        */
378        void RepairViewCellsLeafLists();
379
380        /** Evaluates tree stats in the BSP tree leafs.
381        */
382        void EvaluateLeafStats(const VspBspTraversalData &data);
383
384        /** Subdivides node with respect to the traversal data.
385            @param tStack current traversal stack
386                @param tData traversal data also holding node to be subdivided
387                @returns new root of the subtree
388        */
389        BspNode *Subdivide(VspBspTraversalStack &tStack,
390                                           VspBspTraversalData &tData);
391
392        /** Constructs the tree from the given traversal data.
393                @param polys stores set of polygons on which subdivision may be based
394                @param rays storesset of rays on which subdivision may be based
395        */
396        void Construct(const PolygonContainer &polys, RayInfoContainer *rays);
397
398        /** Selects the best possible splitting plane.
399                @param plane returns the split plane
400                @param leaf the leaf to be split
401                @param polys the polygon list on which the split decition is based
402                @param rays ray container on which selection may be based
403                @note the polygons can be reordered in the process
404                @returns true if the cost of the split is under maxCostRatio
405
406        */
407        bool SelectPlane(Plane3 &plane,
408                                         BspLeaf *leaf,
409                                         VspBspTraversalData &data,
410                                         VspBspTraversalData &frontData,
411                                         VspBspTraversalData &backData);
412       
413        /** Strategies where the effect of the split plane is tested
414            on all input rays.
415
416                @returns the cost of the candidate split plane
417        */
418        float EvalSplitPlaneCost(const Plane3 &candidatePlane,
419                                                         const VspBspTraversalData &data,
420                                                         BspNodeGeometry &geomFront,
421                                                         BspNodeGeometry &geomBack,
422                                                         float &pFront,
423                                                         float &pBack) const;
424
425        /** Subdivide leaf.
426                @param leaf the leaf to be subdivided
427               
428                @param polys the polygons to be split
429                @param frontPolys returns the polygons in front of the split plane
430                @param backPolys returns the polygons in the back of the split plane
431               
432                @param rays the polygons to be filtered
433                @param frontRays returns the polygons in front of the split plane
434                @param backRays returns the polygons in the back of the split plane
435
436                @returns the root of the subdivision
437        */
438
439        BspNode *SubdivideNode(VspBspTraversalData &tData,
440                                                   VspBspTraversalData &frontData,
441                                                   VspBspTraversalData &backData,
442                                                   PolygonContainer &coincident);
443
444        /** Extracts the meshes of the objects and adds them to polygons.
445                Adds object aabb to the aabb of the tree.
446                @param maxPolys the maximal number of objects to be stored as polygons
447                @returns the number of polygons
448        */
449        int AddToPolygonSoup(const ObjectContainer &objects,
450                                                 PolygonContainer &polys,
451                                                 int maxObjects = 0);
452
453        /** Extracts the meshes of the view cells and and adds them to polygons.
454                Adds view cell aabb to the aabb of the tree.
455                @param maxPolys the maximal number of objects to be stored as polygons
456                @returns the number of polygons
457        */
458        int AddToPolygonSoup(const ViewCellContainer &viewCells,
459                                                 PolygonContainer &polys,
460                                                 int maxObjects = 0);
461
462        /** Extract polygons of this mesh and add to polygon container.
463                @param mesh the mesh that drives the polygon construction
464                @param parent the parent intersectable this polygon is constructed from
465                @returns number of polygons
466        */
467        int AddMeshToPolygons(Mesh *mesh, PolygonContainer &polys, MeshInstance *parent);
468
469        /** Selects an axis aligned for the next split.
470                @returns cost for this split
471        */
472        float SelectAxisAlignedPlane(Plane3 &plane,
473                                                                 const VspBspTraversalData &tData,
474                                                                 int &axis,
475                                                                 BspNodeGeometry **frontGeom,
476                                                                 BspNodeGeometry **backGeom,
477                                                                 float &pFront,
478                                                                 float &pBack,
479                                                                 const bool useKdSplit);
480
481        /** Sorts split candidates for surface area heuristics for axis aligned splits.
482                @param polys the input for choosing split candidates
483                @param axis the current split axis
484                @param splitCandidates returns sorted list of split candidates
485        */
486        void SortSplitCandidates(const RayInfoContainer &rays, const int axis);
487
488        /** Computes best cost for axis aligned planes.
489        */
490        float BestCostRatioHeuristics(const RayInfoContainer &rays,
491                                                                  const AxisAlignedBox3 &box,
492                                                                  const int pvsSize,
493                                                                  const int &axis,
494                                                                  float &position);
495
496        /** Selects an axis aligned split plane.
497                @Returns true if split is valied
498        */
499        bool SelectAxisAlignedPlane(Plane3 &plane, const PolygonContainer &polys) const;
500
501        /** Subdivides the rays into front and back rays according to the split plane.
502               
503                @param plane the split plane
504                @param rays contains the rays to be split. The rays are
505                           distributed into front and back rays.
506                @param frontRays returns rays on the front side of the plane
507                @param backRays returns rays on the back side of the plane
508               
509                @returns the number of splits
510        */
511        int SplitRays(const Plane3 &plane,
512                                  RayInfoContainer &rays,
513                              RayInfoContainer &frontRays,
514                                  RayInfoContainer &backRays);
515
516
517        /** Extracts the split planes representing the space bounded by node n.
518        */
519        void ExtractHalfSpaces(BspNode *n, vector<Plane3> &halfSpaces) const;
520
521        /** Adds the object to the pvs of the front and back leaf with a given classification.
522
523                @param obj the object to be added
524                @param cf the ray classification regarding the split plane
525                @param frontPvs returns the PVS of the front partition
526                @param backPvs returns the PVS of the back partition
527       
528        */
529        void AddObjToPvs(Intersectable *obj,
530                                         const int cf,
531                                         int &frontPvs,
532                                         int &backPvs,
533                                         int &totalPvs) const;
534       
535        /** Computes PVS size induced by the rays.
536        */
537        int ComputePvsSize(const RayInfoContainer &rays) const;
538
539        /** Returns true if tree can be terminated.
540        */
541        inline bool TerminationCriteriaMet(const VspBspTraversalData &data) const;
542
543        /** Computes accumulated ray lenght of this rays.
544        */
545        float AccumulatedRayLength(const RayInfoContainer &rays) const;
546
547        /** Splits polygons with respect to the split plane.
548
549                @param plane the split plane
550                @param polys the polygons to be split. the polygons are consumed and
551                           distributed to the containers frontPolys, backPolys, coincident.
552                @param frontPolys returns the polygons in the front of the split plane
553                @param backPolys returns the polygons in the back of the split plane
554                @param coincident returns the polygons coincident to the split plane
555
556                @returns the number of splits   
557        */
558        int SplitPolygons(const Plane3 &plane,
559                                          PolygonContainer &polys,
560                                          PolygonContainer &frontPolys,
561                                          PolygonContainer &backPolys,
562                                          PolygonContainer &coincident) const;
563
564        /** Adds ray sample contributions to the PVS.
565                @param sampleContributions the number contributions of the samples
566                @param contributingSampels the number of contributing rays
567               
568        */
569        void AddToPvs(BspLeaf *leaf,
570                                  const RayInfoContainer &rays,
571                                  float &sampleContributions,
572                                  int &contributingSamples);
573
574
575        /** Collects candidates for the merge in the merge queue.
576                @param leaves the leaves to be merged
577                @returns number of leaves in queue
578        */
579        int CollectMergeCandidates(const vector<BspLeaf *> leaves);
580        /** Collects candidates for the merge in the merge queue.
581                @returns number of leaves in queue
582        */
583        int CollectMergeCandidates(const VssRayContainer &rays);
584
585        /** Take 3 ray endpoints, where two are minimum and one a maximum
586                point or the other way round.
587        */
588        Plane3 ChooseCandidatePlane(const RayInfoContainer &rays) const;
589
590        /** Take plane normal as plane normal and the midpoint of the ray.
591                PROBLEM: does not resemble any point where visibility is
592                likely to change
593        */
594        Plane3 ChooseCandidatePlane2(const RayInfoContainer &rays) const;
595
596        /** Fit the plane between the two lines so that the plane
597                has equal shortest distance to both lines.
598        */
599        Plane3 ChooseCandidatePlane3(const RayInfoContainer &rays) const;
600 
601        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
602                to view cell 2.
603        */
604        void ShuffleLeaf(BspLeaf *leaf,
605                                         BspViewCell *vc1,
606                                         BspViewCell *vc2) const;
607
608       
609        /** Propagates valid flag up the tree.
610        */
611        void PropagateUpValidity(BspNode *node);
612
613        /** Writes the node to disk
614                @note: should be implemented as visitor
615        */
616        void ExportNode(BspNode *node, ofstream &stream);
617
618        /** Returns memory usage of tree.
619        */
620        float GetMemUsage() const;
621
622        /** Calculates cost for merge of view cell 1 and 2.
623        */
624        float GetShuffledVcCost(BspLeaf *leaf, BspViewCell *vc1, BspViewCell *vc2) const;
625
626        void ExportMergedViewCells(ViewCellContainer &viewCells,
627                                                           const ObjectContainer &objects,
628                                                           const int nViewCells);
629
630        /// Pointer to the root of the tree
631        BspNode *mRoot;
632               
633        BspTreeStatistics mBspStats;
634
635        /// Strategies for choosing next split plane.
636        enum {NO_STRATEGY = 0,
637                  RANDOM_POLYGON = 1,
638                  AXIS_ALIGNED = 2,
639                  LEAST_RAY_SPLITS = 256,
640                  BALANCED_RAYS = 512,
641                  PVS = 1024
642                };
643
644        /// box around the whole view domain
645        AxisAlignedBox3 mBox;
646
647        /// minimal number of rays before subdivision termination
648        int mTermMinRays;
649        /// maximal possible depth
650        int mTermMaxDepth;
651        /// mininum probability
652        float mTermMinProbability;
653        /// mininum PVS
654        int mTermMinPvs;
655        /// maximal contribution per ray
656        float mTermMaxRayContribution;
657        /// minimal accumulated ray length
658        float mTermMinAccRayLength;
659
660        ofstream mStats;
661
662        //-- termination criteria for axis aligned split
663
664        /// minimal number of rays for axis aligned split
665        int mTermMinRaysForAxisAligned;
666        // max ray contribution
667        float mTermMaxRayContriForAxisAligned;
668
669        /// strategy to get the best split plane
670        int mSplitPlaneStrategy;
671        /// number of candidates evaluated for the next split plane
672        int mMaxPolyCandidates;
673        /// number of candidates for split planes evaluated using the rays
674        int mMaxRayCandidates;
675        /// balancing factor for PVS criterium
676        float mCtDivCi;
677
678        //-- axis aligned split criteria
679        float mAxisAlignedCtDivCi;
680        /// spezifies the split border of the axis aligned split
681        float mAxisAlignedSplitBorder;
682
683        /// maximal acceptable cost ratio
684        float mTermMaxCostRatio;
685        /// tolerance value indicating how often the max cost ratio can be failed
686        int mTermMissTolerance;
687
688        //-- factors guiding the split plane heuristics
689        float mLeastRaySplitsFactor;
690        float mBalancedRaysFactor;
691        float mPvsFactor;
692
693        /// if area or volume should be used for PVS heuristics
694        bool mUseAreaForPvs;
695        /// tolerance for polygon split
696        float mEpsilon;
697        /// maximal number of test rays used to evaluate candidate split plane
698        int mMaxTests;
699        /// normalizes different bsp split plane criteria
700        float mCostNormalizer;
701        /// maximal number of view cells
702        int mMaxViewCells;
703        /// minimal number of view cells
704        int mMergeMinViewCells;
705        /// maximal cost ratio for the merge
706        float mMergeMaxCostRatio;
707
708        // if rays should be stored in leaves
709        bool mStoreRays;
710       
711        /// if only driving axis should be used for split
712        bool mOnlyDrivingAxis;
713
714        ViewCellsManager *mViewCellsManager;
715
716        vector<SortableEntry> *mSplitCandidates;
717
718
719        typedef priority_queue<BspMergeCandidate> MergeQueue;
720
721        MergeQueue mMergeQueue;
722
723        /// if rays should be used to collect merge candidates
724        bool mUseRaysForMerge;
725       
726        /// View cell corresponding to the space outside the valid view space
727        BspViewCell *mOutOfBoundsCell;
728
729        int mCurrentViewCellsId;
730
731        /// maximal tree memory
732        float mMaxMemory;
733        /// the tree is out of memory
734        bool mOutOfMemory;
735        /// if merge visualization should be shown
736        bool mExportMergedViewCells;
737        /// if merge statistics should be exported
738        bool mExportMergeStats;
739
740private:
741       
742        ViewCellContainer mOldViewCells;
743        ViewCellContainer mNewViewCells;
744
745        static const float sLeastRaySplitsTable[5];
746        /** Evaluates split plane classification with respect to the plane's
747                contribution for balanced rays.
748        */
749        static const float sBalancedRaysTable[5];
750
751        /// Generates unique ids for PVS criterium
752        static void GenerateUniqueIdsForPvs();
753
754        //-- unique ids for PVS criterium
755        static int sFrontId;
756        static int sBackId;
757        static int sFrontAndBackId;
758};
759
760/**
761        Candidate for leaf merging based on priority.
762*/
763class BspMergeCandidate
764
765        friend class VspBspTree;
766
767public:
768
769        BspMergeCandidate(BspLeaf *l1, BspLeaf *l2);
770
771        /** If this merge pair is still valid.
772        */
773        bool Valid() const;
774
775        /** Sets this merge candidate to be valid.
776        */
777        void SetValid();
778
779        friend bool operator<(const BspMergeCandidate &leafa, const BspMergeCandidate &leafb)
780        {
781                return leafb.GetMergeCost() < leafa.GetMergeCost();
782        }
783
784        void SetLeaf1(BspLeaf *l);
785        void SetLeaf2(BspLeaf *l);
786
787        BspLeaf *GetLeaf1();
788        BspLeaf *GetLeaf2();
789
790        /** Merge cost of this candidate pair.
791        */
792        float GetMergeCost() const;
793
794        /** Returns cost of leaf 1.
795        */
796        float GetLeaf1Cost() const;
797        /** Returns cost of leaf 2.
798        */
799        float GetLeaf2Cost() const;
800
801        /// maximal pvs size
802        static int sMaxPvsSize;
803        /// minimal pvs size
804        //static int sMinPvsSize;
805
806        /// overall cost used to normalize cost ratio
807        static float sOverallCost;
808        // if area or volume should be used for the merge heuristics
809        static bool sUseArea;
810
811        static int sUpperPvsLimit;
812        static int sLowerPvsLimit;
813
814protected:
815
816       
817        /** Evaluates the merge costs of the leaves.
818        */
819        void EvalMergeCost();
820
821        /** penalty for a given pvs size.
822        */
823        inline float EvalPvsPenalty(int pvs) const;
824
825        /** Cost of a view cell.
826        */
827        float GetCost(ViewCell *vc) const;
828       
829        int mLeaf1Id;
830        int mLeaf2Id;
831
832        float mMergeCost;
833       
834        BspLeaf *mLeaf1;
835        BspLeaf *mLeaf2;
836};
837
838
839class MergeStatistics: public StatisticsBase
840{
841public:
842       
843        int merged;
844        int siblings;
845        int candidates;
846        int nodes;
847
848        int accTreeDist;
849        int maxTreeDist;
850       
851        Real collectTime;
852        Real mergeTime;
853
854        Real overallCost;
855
856        // Constructor
857        MergeStatistics()
858        {
859                Reset();
860        }
861       
862        double AvgTreeDist() const {return (double)accTreeDist / (double)merged;};
863
864        void Reset()
865        {
866                nodes = 0;
867                merged = 0;
868                siblings = 0;
869                candidates = 0;
870       
871                accTreeDist = 0;
872                maxTreeDist = 0;
873
874                collectTime = 0;
875                mergeTime = 0;
876                overallCost = 0;
877        }
878
879        void Print(ostream &app) const;
880
881        friend ostream &operator<<(ostream &s, const MergeStatistics &stat)
882        {
883                stat.Print(s);
884                return s;
885        }
886};
887
888#endif
Note: See TracBrowser for help on using the repository browser.