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

Revision 483, 17.9 KB checked in by mattausch, 18 years ago (diff)
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;
23
24
25/**
26        This is a view space partitioning specialised BSPtree. 
27        There are no polygon splits, but we split the sample rays.
28        The candidates for the next split plane are evaluated only
29        by checking the sampled visibility information.
30        The polygons are employed merely as candidates for the next split planes.
31*/
32class VspBspTree
33{
34public:
35       
36        /** Additional data which is passed down the BSP tree during traversal.
37        */
38        struct VspBspTraversalData
39        { 
40                /// the current node
41                BspNode *mNode;
42                /// polygonal data for splitting
43                PolygonContainer *mPolygons;
44                /// current depth
45                int mDepth;
46                /// rays piercing this node
47                RayInfoContainer *mRays;
48                /// area of current node
49                float mArea;
50                /// geometry of node as induced by planes
51                BspNodeGeometry *mGeometry;
52                /// pvs size
53                int mPvs;
54                /// how often this branch has missed the max-cost ratio
55                int mMaxCostMisses;
56
57
58                /** Returns average ray contribution.
59                */
60                float GetAvgRayContribution() const
61                {
62                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
63                }
64
65
66                VspBspTraversalData():
67                mNode(NULL),
68                mPolygons(NULL),
69                mDepth(0),
70                mRays(NULL),
71                mPvs(0),
72                mArea(0.0),
73                mGeometry(NULL),
74                mMaxCostMisses(0)
75                {}
76               
77                VspBspTraversalData(BspNode *node,
78                                                        PolygonContainer *polys,
79                                                        const int depth,
80                                                        RayInfoContainer *rays,
81                                                        int pvs,
82                                                        float area,
83                                                        BspNodeGeometry *geom):
84                mNode(node),
85                mPolygons(polys),
86                mDepth(depth),
87                mRays(rays),
88                mPvs(pvs),
89                mArea(area),
90                mGeometry(geom),
91                mMaxCostMisses(0)
92                {}
93
94                VspBspTraversalData(PolygonContainer *polys,
95                                                        const int depth,
96                                                        RayInfoContainer *rays,
97                                                        BspNodeGeometry *geom):
98                mNode(NULL),
99                mPolygons(polys),
100                mDepth(depth),
101                mRays(rays),
102                mPvs(0),
103                mArea(0),
104                mGeometry(geom),
105                mMaxCostMisses(0)
106                {}
107
108                /** Returns cost of the traversal data.
109                */
110                float GetCost() const
111                {
112#if 1
113                        return mPvs * mArea;
114#endif
115#if 0
116                        return (float)(mPvs * (int)mRays->size());
117#endif
118#if 0
119                        return (float)mPvs;
120#endif
121#if 0
122                        return mArea * (float)mRays->size();
123#endif
124                }
125
126                // deletes contents and sets them to NULL
127                void Clear()
128                {
129                        DEL_PTR(mPolygons);
130                        DEL_PTR(mRays);
131                        DEL_PTR(mGeometry);
132                }
133
134                friend bool operator<(const VspBspTraversalData &a, const VspBspTraversalData &b)
135                {
136                        return a.GetCost() < b.GetCost();
137                }
138    };
139       
140        typedef std::priority_queue<VspBspTraversalData> VspBspTraversalStack;
141        //typedef std::stack<VspBspTraversalData> VspBspTraversalStack;
142
143        /** Default constructor creating an empty tree.
144        */
145        VspBspTree();
146
147        /** Default destructor.
148        */
149        ~VspBspTree();
150
151        /** Returns BSP Tree statistics.
152        */
153        const BspTreeStatistics &GetStatistics() const;
154 
155
156        /** Constructs the tree from a given set of rays.
157                @param sampleRays the set of sample rays the construction is based on
158                @param viewCells if not NULL, new view cells are
159                created in the leafs and stored in the container
160        */
161        void Construct(const VssRayContainer &sampleRays,
162                                   AxisAlignedBox3 *forcedBoundingBox);
163
164        /** Returns list of BSP leaves.
165        */
166        void CollectLeaves(vector<BspLeaf *> &leaves) const;
167
168        /** Returns box which bounds the whole tree.
169        */
170        AxisAlignedBox3 GetBoundingBox()const;
171
172        /** Returns root of BSP tree.
173        */
174        BspNode *GetRoot() const;
175
176        /** Exports VspBsp tree to file.
177        */
178        bool Export(const string filename);
179
180        /** Collects the leaf view cells of the tree
181                @param viewCells returns the view cells
182        */
183        void CollectViewCells(ViewCellContainer &viewCells) const;
184
185        /** A ray is cast possible intersecting the tree.
186                @param the ray that is cast.
187                @returns the number of intersections with objects stored in the tree.
188        */
189        int CastRay(Ray &ray);
190
191        /// bsp tree construction types
192        enum {FROM_INPUT_VIEW_CELLS, FROM_SCENE_GEOMETRY, FROM_SAMPLES};
193
194        /** finds neighbouring leaves of this tree node.
195        */
196        int FindNeighbors(BspNode *n,
197                                          vector<BspLeaf *> &neighbors,
198                                          const bool onlyUnmailed) const;
199
200        /** Constructs geometry associated with the half space intersections
201                leading to this node.
202        */
203        void ConstructGeometry(BspNode *n, PolygonContainer &cell) const;
204
205        /** Constructs geometry associated with the half space intersections
206                leading to this node.
207        */
208        void ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const;
209
210        /** Construct geometry and stores it in a geometry node container.
211        */
212        void ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const;
213
214        /** Returns random leaf of BSP tree.
215                @param halfspace defines the halfspace from which the leaf is taken.
216        */
217        BspLeaf *GetRandomLeaf(const Plane3 &halfspace);
218
219        /** Returns random leaf of BSP tree.
220                @param onlyUnmailed if only unmailed leaves should be returned.
221        */
222        BspLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
223
224        /** Returns view cell corresponding to unbounded space.
225        */
226        BspViewCell *GetRootCell() const;
227
228        /** Returns epsilon of this tree.
229        */
230        float GetEpsilon() const;
231
232
233    int CastLineSegment(const Vector3 &origin,
234                                                const Vector3 &termination,
235                                                ViewCellContainer &viewcells);
236
237        /** Merges leaves with similar PVS.
238        */
239        int MergeLeaves();
240               
241        /** Sets pointer to view cells manager.
242        */
243        void SetViewCellsManager(ViewCellsManager *vcm);
244
245        /** Helper function revalidating the view cell leaf list after merge.
246        */
247        void RepairVcLeafLists();
248
249        /** Collapses the tree with respect to the view cell partition.
250                @returns node of type leaf if the node could be collapsed, this node otherwise
251        */
252        BspNode *CollapseTree(BspNode *node);
253       
254
255        /** Returns distance from node 1 to node 2.
256        */
257        int TreeDistance(BspNode *n1, BspNode *n2);
258
259protected:
260
261        // --------------------------------------------------------------
262        // For sorting objects
263        // --------------------------------------------------------------
264        struct SortableEntry
265        {
266                enum EType
267                {
268                        ERayMin,
269                        ERayMax
270                };
271
272                int type;
273                float value;
274                VssRay *ray;
275 
276                SortableEntry() {}
277                SortableEntry(const int t, const float v, VssRay *r):type(t),
278                                          value(v), ray(r)
279                {
280                }
281               
282                friend bool operator<(const SortableEntry &a, const SortableEntry &b)
283                {
284                        return a.value < b.value;
285                }
286        };
287
288        /** Evaluates tree stats in the BSP tree leafs.
289        */
290        void EvaluateLeafStats(const VspBspTraversalData &data);
291
292        /** Subdivides node with respect to the traversal data.
293            @param tStack current traversal stack
294                @param tData traversal data also holding node to be subdivided
295                @returns new root of the subtree
296        */
297        BspNode *Subdivide(VspBspTraversalStack &tStack,
298                                           VspBspTraversalData &tData);
299
300        /** Constructs the tree from the given traversal data.
301                @param polys stores set of polygons on which subdivision may be based
302                @param rays storesset of rays on which subdivision may be based
303        */
304        void Construct(const PolygonContainer &polys, RayInfoContainer *rays);
305
306        /** Selects the best possible splitting plane.
307                @param plane returns the split plane
308                @param leaf the leaf to be split
309                @param polys the polygon list on which the split decition is based
310                @param rays ray container on which selection may be based
311                @note the polygons can be reordered in the process
312                @returns true if the cost of the split is under maxCostRatio
313
314        */
315        bool SelectPlane(Plane3 &plane,
316                                         BspLeaf *leaf,
317                                         VspBspTraversalData &data);
318       
319        /** Strategies where the effect of the split plane is tested
320            on all input rays.
321
322                @returns the cost of the candidate split plane
323        */
324        float SplitPlaneCost(const Plane3 &candidatePlane,
325                                                 const VspBspTraversalData &data) const;
326
327
328        /** Subdivide leaf.
329                @param leaf the leaf to be subdivided
330               
331                @param polys the polygons to be split
332                @param frontPolys returns the polygons in front of the split plane
333                @param backPolys returns the polygons in the back of the split plane
334               
335                @param rays the polygons to be filtered
336                @param frontRays returns the polygons in front of the split plane
337                @param backRays returns the polygons in the back of the split plane
338
339                @returns the root of the subdivision
340        */
341
342        BspNode *SubdivideNode(VspBspTraversalData &tData,
343                                                   VspBspTraversalData &frontData,
344                                                   VspBspTraversalData &backData,
345                                                   PolygonContainer &coincident);
346
347        /** Selects the split plane in order to construct a tree with
348                certain characteristics (e.g., balanced tree, least splits,
349                2.5d aligned)
350                @param bestPlane returns the split plane
351                @param polygons container of polygons
352                @param rays bundle of rays on which the split can be based
353
354                @returns true if the overall cost is under maxCostRatio
355        */
356        bool SelectPlaneHeuristics(Plane3 &bestPlane,
357                                                           BspLeaf *leaf,
358                                                           VspBspTraversalData &data);
359
360        /** Extracts the meshes of the objects and adds them to polygons.
361                Adds object aabb to the aabb of the tree.
362                @param maxPolys the maximal number of objects to be stored as polygons
363                @returns the number of polygons
364        */
365        int AddToPolygonSoup(const ObjectContainer &objects,
366                                                 PolygonContainer &polys,
367                                                 int maxObjects = 0);
368
369        /** Extracts the meshes of the view cells and and adds them to polygons.
370                Adds view cell aabb to the aabb of the tree.
371                @param maxPolys the maximal number of objects to be stored as polygons
372                @returns the number of polygons
373        */
374        int AddToPolygonSoup(const ViewCellContainer &viewCells,
375                                                 PolygonContainer &polys,
376                                                 int maxObjects = 0);
377
378        /** Extract polygons of this mesh and add to polygon container.
379                @param mesh the mesh that drives the polygon construction
380                @param parent the parent intersectable this polygon is constructed from
381                @returns number of polygons
382        */
383        int AddMeshToPolygons(Mesh *mesh, PolygonContainer &polys, MeshInstance *parent);
384
385        /** Selects a plane axis aligned.
386        */
387        float SelectAxisAlignedPlane(Plane3 &plane,
388                                                                 const VspBspTraversalData &tData);
389
390        /** Sorts split candidates for surface area heuristics for axis aligned splits.
391                @param polys the input for choosing split candidates
392                @param axis the current split axis
393                @param splitCandidates returns sorted list of split candidates
394        */
395        void SortSplitCandidates(const RayInfoContainer &rays, const int axis);
396
397        /** Computes best cost for axis aligned planes.
398        */
399        float BestCostRatioHeuristics(const RayInfoContainer &rays,
400                                                                  const AxisAlignedBox3 &box,
401                                                                  const int pvsSize,
402                                                                  const int &axis,
403                                                                  float &position);
404
405        /** Selects an axis aligned split plane.
406                Returns true if split is valied
407        */
408        bool SelectAxisAlignedPlane(Plane3 &plane, const PolygonContainer &polys) const;
409
410        /** Subdivides the rays into front and back rays according to the split plane.
411               
412                @param plane the split plane
413                @param rays contains the rays to be split. The rays are
414                           distributed into front and back rays.
415                @param frontRays returns rays on the front side of the plane
416                @param backRays returns rays on the back side of the plane
417               
418                @returns the number of splits
419        */
420        int SplitRays(const Plane3 &plane,
421                                  RayInfoContainer &rays,
422                              RayInfoContainer &frontRays,
423                                  RayInfoContainer &backRays);
424
425
426        /** Extracts the split planes representing the space bounded by node n.
427        */
428        void ExtractHalfSpaces(BspNode *n, vector<Plane3> &halfSpaces) const;
429
430        /** Adds the object to the pvs of the front and back leaf with a given classification.
431
432                @param obj the object to be added
433                @param cf the ray classification regarding the split plane
434                @param frontPvs returns the PVS of the front partition
435                @param backPvs returns the PVS of the back partition
436       
437        */
438        void AddObjToPvs(Intersectable *obj, const int cf, int &frontPvs, int &backPvs) const;
439       
440        /** Computes PVS size induced by the rays.
441        */
442        int ComputePvsSize(const RayInfoContainer &rays) const;
443
444        /** Returns true if tree can be terminated.
445        */
446        inline bool TerminationCriteriaMet(const VspBspTraversalData &data) const;
447
448        /** Computes accumulated ray lenght of this rays.
449        */
450        float AccumulatedRayLength(const RayInfoContainer &rays) const;
451
452        /** Splits polygons with respect to the split plane.
453
454                @param plane the split plane
455                @param polys the polygons to be split. the polygons are consumed and
456                           distributed to the containers frontPolys, backPolys, coincident.
457                @param frontPolys returns the polygons in the front of the split plane
458                @param backPolys returns the polygons in the back of the split plane
459                @param coincident returns the polygons coincident to the split plane
460
461                @returns the number of splits   
462        */
463        int SplitPolygons(const Plane3 &plane,
464                                          PolygonContainer &polys,
465                                          PolygonContainer &frontPolys,
466                                          PolygonContainer &backPolys,
467                                          PolygonContainer &coincident) const;
468
469        /** Adds ray sample contributions to the PVS.
470                @param sampleContributions the number contributions of the samples
471                @param contributingSampels the number of contributing rays
472               
473        */
474        void AddToPvs(BspLeaf *leaf,
475                                  const RayInfoContainer &rays,
476                                  int &sampleContributions,
477                                  int &contributingSamples);
478
479
480        /** Take 3 ray endpoints, where two are minimum and one a maximum
481                point or the other way round.
482        */
483        Plane3 ChooseCandidatePlane(const RayInfoContainer &rays) const;
484
485        /** Take plane normal as plane normal and the midpoint of the ray.
486                PROBLEM: does not resemble any point where visibility is likely to change
487        */
488        Plane3 ChooseCandidatePlane2(const RayInfoContainer &rays) const;
489
490        /** Fit the plane between the two lines so that the plane has equal shortest
491                distance to both lines.
492        */
493        Plane3 ChooseCandidatePlane3(const RayInfoContainer &rays) const;
494 
495        /** Merge view cells of leaves l1 and l2.
496        */
497        bool MergeViewCells(BspLeaf *l1, BspLeaf *l2);
498
499        /// Pointer to the root of the tree
500        BspNode *mRoot;
501               
502        BspTreeStatistics mStat;
503
504        /// Strategies for choosing next split plane.
505        enum {NO_STRATEGY = 0,
506                  RANDOM_POLYGON = 1,
507                  AXIS_ALIGNED = 2,
508                  LEAST_RAY_SPLITS = 256,
509                  BALANCED_RAYS = 512,
510                  PVS = 1024
511                };
512
513        /// box around the whole view domain
514        AxisAlignedBox3 mBox;
515
516        /// view cell corresponding to unbounded space
517        BspViewCell *mRootCell;
518
519        /// minimal number of rays before subdivision termination
520        int mTermMinRays;
521        /// maximal possible depth
522        int mTermMaxDepth;
523        /// mininum area
524        float mTermMinArea;
525        /// mininum PVS
526        int mTermMinPvs;
527
528        /// minimal number of rays for axis aligned split
529        int mTermMinRaysForAxisAligned;
530        /// minimal number of objects for axis aligned split
531        int mTermMinObjectsForAxisAligned;
532        /// maximal contribution per ray
533        float mTermMaxRayContribution;
534        /// minimal accumulated ray length
535        float mTermMinAccRayLength;
536
537        /// strategy to get the best split plane
538        int mSplitPlaneStrategy;
539        /// number of candidates evaluated for the next split plane
540        int mMaxPolyCandidates;
541        /// number of candidates for split planes evaluated using the rays
542        int mMaxRayCandidates;
543        /// balancing factor for PVS criterium
544        float mCtDivCi;
545
546        //-- axis aligned split criteria
547        float mAxisAlignedCtDivCi;
548        /// spezifies the split border of the axis aligned split
549        float mAxisAlignedSplitBorder;
550
551        /// maximal acceptable cost ratio
552        float mTermMaxCostRatio;
553        /// tolerance value indicating how often the max cost ratio can be failed
554        int mTermMissTolerance;
555
556        //-- factors guiding the split plane heuristics
557        float mLeastRaySplitsFactor;
558        float mBalancedRaysFactor;
559        float mPvsFactor;
560
561        /// if area or accumulated ray lenght should be used for PVS heuristics
562        bool mPvsUseArea;
563        /// tolerance for polygon split
564        float mEpsilon;
565        /// maximal number of test rays used to evaluate candidate split plane
566        int mMaxTests;
567        /// normalizes different bsp split plane criteria
568        float mCostNormalizer;
569        /// maximal number of view cells
570        int mMaxViewCells;
571        /// minimal number of view cells
572        int mMergeMinViewCells;
573        /// maximal cost ratio for the merge
574        float mMergeMaxCostRatio;
575
576        ViewCellsManager *mViewCellsManager;
577
578        // if rays should be stored in leaves
579        bool mStoreRays;
580
581        vector<SortableEntry> *mSplitCandidates;
582
583        bool mOnlyDrivingAxis;
584
585
586private:
587       
588        static const float sLeastRaySplitsTable[5];
589        /** Evaluates split plane classification with respect to the plane's
590                contribution for balanced rays.
591        */
592        static const float sBalancedRaysTable[5];
593
594        /// Generates unique ids for PVS criterium
595        static void GenerateUniqueIdsForPvs();
596
597        //-- unique ids for PVS criterium
598        static int sFrontId;
599        static int sBackId;
600        static int sFrontAndBackId;
601};
602
603/**
604        Candidate for leaf merging based on priority.
605*/
606class BspMergeCandidate
607
608public:
609
610        BspMergeCandidate(BspLeaf *l1, BspLeaf *l2);
611
612        /** If this merge pair is still valid.
613        */
614        bool Valid() const;
615
616        /** Sets this merge candidate to be valid.
617        */
618        void SetValid();
619
620        friend bool operator<(const BspMergeCandidate &leafa, const BspMergeCandidate &leafb)
621        {
622                return leafb.GetMergeCost() < leafa.GetMergeCost();
623        }
624
625        void SetLeaf1(BspLeaf *l);
626        void SetLeaf2(BspLeaf *l);
627
628        BspLeaf *GetLeaf1();
629        BspLeaf *GetLeaf2();
630
631        /** Merge cost of this candidate pair.
632        */
633        float GetMergeCost() const;
634
635        /** Returns cost of leaf 1.
636        */
637        float GetLeaf1Cost() const;
638        /** Returns cost of leaf 2.
639        */
640        float GetLeaf2Cost() const;
641
642        /// maximal pvs size
643        static int sMaxPvsSize;
644        /// overall cost used to normalize cost ratio
645        static float sOverallCost;
646
647protected:
648       
649        /** Evaluates the merge costs of the leaves.
650        */
651        void EvalMergeCost();
652
653        int mLeaf1Id;
654        int mLeaf2Id;
655
656        float mMergeCost;
657       
658        BspLeaf *mLeaf1;
659        BspLeaf *mLeaf2;
660};
661
662
663#endif
Note: See TracBrowser for help on using the repository browser.