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

Revision 473, 16.5 KB checked in by mattausch, 19 years ago (diff)

worked on new features,
removed Random Bug (took only 32000 values),
removed bug when choosing new candidates (totally wrong)
introduced new candidate plane method
implemented priority queue for vsp bsp

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;
22
23/*class BspNodeGeometry;
24class BspTreeStatistics;
25class ViewCellsStatistics;
26class BspNode;
27class BspLeaf;
28class BspInterior;
29*/
30
31/**
32        This is a view space partitioning specialised BSPtree. 
33        There are no polygon splits, but we split the sample rays.
34        The candidates for the next split plane are evaluated only
35        by checking the sampled visibility information.
36        The polygons are employed merely as candidates for the next split planes.
37*/
38class VspBspTree
39{
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                /// area of current node
55                float mArea;
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
63
64                /** Returns average ray contribution.
65                */
66                float GetAvgRayContribution() const
67                {
68                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
69                }
70
71
72                VspBspTraversalData():
73                mNode(NULL),
74                mPolygons(NULL),
75                mDepth(0),
76                mRays(NULL),
77                mPvs(0),
78                mArea(0.0),
79                mGeometry(NULL),
80                mMaxCostMisses(0)
81                {}
82               
83                VspBspTraversalData(BspNode *node,
84                                                        PolygonContainer *polys,
85                                                        const int depth,
86                                                        RayInfoContainer *rays,
87                                                        int pvs,
88                                                        float area,
89                                                        BspNodeGeometry *geom):
90                mNode(node),
91                mPolygons(polys),
92                mDepth(depth),
93                mRays(rays),
94                mPvs(pvs),
95                mArea(area),
96                mGeometry(geom),
97                mMaxCostMisses(0)
98                {}
99
100                VspBspTraversalData(PolygonContainer *polys,
101                                                        const int depth,
102                                                        RayInfoContainer *rays,
103                                                        BspNodeGeometry *geom):
104                mNode(NULL),
105                mPolygons(polys),
106                mDepth(depth),
107                mRays(rays),
108                mPvs(0),
109                mArea(0),
110                mGeometry(geom),
111                mMaxCostMisses(0)
112                {}
113
114                friend bool operator<(const VspBspTraversalData &a, const VspBspTraversalData &b)
115                {
116#if 0
117                        return a.mPvs * a.mArea < b.mPvs * b.mArea;
118#endif
119#if 1
120                        return a.mPvs * (int)a.mRays->size() < b.mPvs * (int)b.mRays->size();
121#endif
122#if 0
123                        return a.mPvs < b.mPvs;
124#endif
125#if 0
126                        return
127                                a.mPvs / (float)(a.mRays->size() + Limits::Small())
128                                >
129                                b.mPvs / (float)(b.mRays->size() + Limits::Small());
130#endif
131#if 0
132                        return a.mPvs * (int)a.mRays->size() <  b.mPvs * (int)b.mRays->size();
133#endif
134                }
135    };
136       
137        typedef std::priority_queue<VspBspTraversalData> VspBspTraversalStack;
138        //typedef std::stack<VspBspTraversalData> VspBspTraversalStack;
139
140        /** Default constructor creating an empty tree.
141        */
142        VspBspTree();
143
144        /** Default destructor.
145        */
146        ~VspBspTree();
147
148        /** Returns BSP Tree statistics.
149        */
150        const BspTreeStatistics &GetStatistics() const;
151 
152
153        /** Constructs the tree from a given set of rays.
154                @param sampleRays the set of sample rays the construction is based on
155                @param viewCells if not NULL, new view cells are
156                created in the leafs and stored in the container
157        */
158        void Construct(const VssRayContainer &sampleRays);
159
160        /** Returns list of BSP leaves.
161        */
162        void CollectLeaves(vector<BspLeaf *> &leaves) const;
163
164        /** Returns box which bounds the whole tree.
165        */
166        AxisAlignedBox3 GetBoundingBox()const;
167
168        /** Returns root of BSP tree.
169        */
170        BspNode *GetRoot() const;
171
172        /** Exports VspBsp tree to file.
173        */
174        bool Export(const string filename);
175
176        /** Collects the leaf view cells of the tree
177                @param viewCells returns the view cells
178        */
179        void CollectViewCells(ViewCellContainer &viewCells) const;
180
181        /** A ray is cast possible intersecting the tree.
182                @param the ray that is cast.
183                @returns the number of intersections with objects stored in the tree.
184        */
185        int CastRay(Ray &ray);
186
187        /// bsp tree construction types
188        enum {FROM_INPUT_VIEW_CELLS, FROM_SCENE_GEOMETRY, FROM_SAMPLES};
189
190        /** Returns statistics.
191        */
192        BspTreeStatistics &GetStat();
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        /** Traverses tree and counts all view cells as well as their PVS size.
225        */
226        void EvaluateViewCellsStats(ViewCellsStatistics &stat) const;
227
228
229        /** Returns view cell corresponding to unbounded space.
230        */
231        BspViewCell *GetRootCell() const;
232
233        /** Returns epsilon of this tree.
234        */
235        float GetEpsilon() const;
236
237
238    int
239        CastLineSegment(const Vector3 &origin,
240                                        const Vector3 &termination,
241                                        ViewCellContainer &viewcells
242                                        );
243
244protected:
245
246        // --------------------------------------------------------------
247        // For sorting objects
248        // --------------------------------------------------------------
249        struct SortableEntry
250        {
251                enum {POLY_MIN, POLY_MAX};
252   
253                int type;
254                float value;
255                Polygon3 *poly;
256                SortableEntry() {}
257                SortableEntry(const int t, const float v, Polygon3 *poly):
258                type(t), value(v), poly(poly) {}
259               
260                bool operator<(const SortableEntry &b) const
261                {
262                        return value < b.value;
263                } 
264        };
265
266        /** Evaluates tree stats in the BSP tree leafs.
267        */
268        void EvaluateLeafStats(const VspBspTraversalData &data);
269
270        /** Subdivides node with respect to the traversal data.
271            @param tStack current traversal stack
272                @param tData traversal data also holding node to be subdivided
273                @returns new root of the subtree
274        */
275        BspNode *Subdivide(VspBspTraversalStack &tStack,
276                                           VspBspTraversalData &tData);
277
278        /** Constructs the tree from the given traversal data.
279                @param polys stores set of polygons on which subdivision may be based
280                @param rays storesset of rays on which subdivision may be based
281        */
282        void Construct(const PolygonContainer &polys, RayInfoContainer *rays);
283
284        /** Selects the best possible splitting plane.
285                @param plane returns the split plane
286                @param leaf the leaf to be split
287                @param polys the polygon list on which the split decition is based
288                @param rays ray container on which selection may be based
289                @note the polygons can be reordered in the process
290                @returns true if the cost of the split is under maxCostRatio
291
292        */
293        bool SelectPlane(Plane3 &plane,
294                                         BspLeaf *leaf,
295                                         VspBspTraversalData &data);
296       
297        /** Strategies where the effect of the split plane is tested
298            on all input rays.
299
300                @returns the cost of the candidate split plane
301        */
302        float SplitPlaneCost(const Plane3 &candidatePlane,
303                                                 const VspBspTraversalData &data);
304
305
306        /** Subdivide leaf.
307                @param leaf the leaf to be subdivided
308               
309                @param polys the polygons to be split
310                @param frontPolys returns the polygons in front of the split plane
311                @param backPolys returns the polygons in the back of the split plane
312               
313                @param rays the polygons to be filtered
314                @param frontRays returns the polygons in front of the split plane
315                @param backRays returns the polygons in the back of the split plane
316
317                @returns the root of the subdivision
318        */
319
320        BspNode *SubdivideNode(VspBspTraversalData &tData,
321                                                   VspBspTraversalData &frontData,
322                                                   VspBspTraversalData &backData,
323                                                   PolygonContainer &coincident);
324
325        /** Selects the split plane in order to construct a tree with
326                certain characteristics (e.g., balanced tree, least splits,
327                2.5d aligned)
328                @param bestPlane returns the split plane
329                @param polygons container of polygons
330                @param rays bundle of rays on which the split can be based
331
332                @returns true if the overall cost is under maxCostRatio
333        */
334        bool SelectPlaneHeuristics(Plane3 &bestPlane,
335                                                           BspLeaf *leaf,
336                                                           VspBspTraversalData &data);
337
338        /** Extracts the meshes of the objects and adds them to polygons.
339                Adds object aabb to the aabb of the tree.
340                @param maxPolys the maximal number of objects to be stored as polygons
341                @returns the number of polygons
342        */
343        int AddToPolygonSoup(const ObjectContainer &objects,
344                                                 PolygonContainer &polys,
345                                                 int maxObjects = 0);
346
347        /** Extracts the meshes of the view cells and and adds them to polygons.
348                Adds view cell aabb to the aabb of the tree.
349                @param maxPolys the maximal number of objects to be stored as polygons
350                @returns the number of polygons
351        */
352        int AddToPolygonSoup(const ViewCellContainer &viewCells,
353                                                 PolygonContainer &polys,
354                                                 int maxObjects = 0);
355
356        /** Extract polygons of this mesh and add to polygon container.
357                @param mesh the mesh that drives the polygon construction
358                @param parent the parent intersectable this polygon is constructed from
359                @returns number of polygons
360        */
361        int AddMeshToPolygons(Mesh *mesh, PolygonContainer &polys, MeshInstance *parent);
362
363        /** Computes best cost ratio for the suface area heuristics for axis aligned
364                splits. This heuristics minimizes the cost for ray traversal.
365                @param polys the polygons guiding the ratio computation
366                @param box the bounding box of the leaf
367                @param axis the current split axis
368                @param position returns the split position
369                @param objectsBack the number of objects in the back of the split plane
370                @param objectsFront the number of objects in the front of the split plane
371        */
372        float BestCostRatio(const PolygonContainer &polys,
373                                                const AxisAlignedBox3 &box,
374                                                const int axis,
375                                                float &position,
376                                                int &objectsBack,
377                                                int &objectsFront) const;
378       
379        /** Sorts split candidates for surface area heuristics for axis aligned splits.
380                @param polys the input for choosing split candidates
381                @param axis the current split axis
382                @param splitCandidates returns sorted list of split candidates
383        */
384        void SortSplitCandidates(const PolygonContainer &polys,
385                                                         const int axis,
386                                                         vector<SortableEntry> &splitCandidates) const;
387
388        /** Selects an axis aligned split plane.
389                Returns true if split is valied
390        */
391        bool SelectAxisAlignedPlane(Plane3 &plane, const PolygonContainer &polys) const;
392
393        /** Subdivides the rays into front and back rays according to the split plane.
394               
395                @param plane the split plane
396                @param rays contains the rays to be split. The rays are
397                           distributed into front and back rays.
398                @param frontRays returns rays on the front side of the plane
399                @param backRays returns rays on the back side of the plane
400               
401                @returns the number of splits
402        */
403        int SplitRays(const Plane3 &plane,
404                                  RayInfoContainer &rays,
405                              RayInfoContainer &frontRays,
406                                  RayInfoContainer &backRays);
407
408
409        /** Extracts the split planes representing the space bounded by node n.
410        */
411        void ExtractHalfSpaces(BspNode *n, vector<Plane3> &halfSpaces) const;
412
413        /** Adds the object to the pvs of the front and back leaf with a given classification.
414
415                @param obj the object to be added
416                @param cf the ray classification regarding the split plane
417                @param frontPvs returns the PVS of the front partition
418                @param backPvs returns the PVS of the back partition
419       
420        */
421        void AddObjToPvs(Intersectable *obj, const int cf, int &frontPvs, int &backPvs) const;
422       
423        /** Computes PVS size induced by the rays.
424        */
425        int ComputePvsSize(const RayInfoContainer &rays) const;
426
427        /** Returns true if tree can be terminated.
428        */
429        inline bool TerminationCriteriaMet(const VspBspTraversalData &data, const int numLeaves) const;
430
431        /** Computes accumulated ray lenght of this rays.
432        */
433        float AccumulatedRayLength(const RayInfoContainer &rays) const;
434
435        /** Splits polygons with respect to the split plane.
436
437                @param plane the split plane
438                @param polys the polygons to be split. the polygons are consumed and
439                           distributed to the containers frontPolys, backPolys, coincident.
440                @param frontPolys returns the polygons in the front of the split plane
441                @param backPolys returns the polygons in the back of the split plane
442                @param coincident returns the polygons coincident to the split plane
443
444                @returns the number of splits   
445        */
446        int SplitPolygons(const Plane3 &plane,
447                                          PolygonContainer &polys,
448                                          PolygonContainer &frontPolys,
449                                          PolygonContainer &backPolys,
450                                          PolygonContainer &coincident) const;
451
452        /** Adds ray sample contributions to the PVS.
453                @param sampleContributions the number contributions of the samples
454                @param contributingSampels the number of contributing rays
455               
456        */
457        void AddToPvs(BspLeaf *leaf,
458                                  const RayInfoContainer &rays,
459                                  int &sampleContributions,
460                                  int &contributingSamples);
461
462
463        /** Take 3 ray endpoints, where two are minimum and one a maximum
464                point or the other way round.
465        */
466        Plane3 ChooseCandidatePlane(const RayInfoContainer &rays) const;
467
468        /** Take plane normal as plane normal and the midpoint of the ray.
469                PROBLEM: does not resemble any point where visibility is likely to change
470        */
471        Plane3 ChooseCandidatePlane2(const RayInfoContainer &rays) const;
472
473        /** Fit the plane between the two lines so that the plane has equal shortest
474                distance to both lines.
475        */
476        Plane3 ChooseCandidatePlane3(const RayInfoContainer &rays) const;
477 
478        /// Pointer to the root of the tree
479        BspNode *mRoot;
480               
481        BspTreeStatistics mStat;
482
483        /// Strategies for choosing next split plane.
484        enum {NO_STRATEGY = 0,
485                  RANDOM_POLYGON = 1,
486                  AXIS_ALIGNED = 2,
487                  LEAST_RAY_SPLITS = 256,
488                  BALANCED_RAYS = 512,
489                  PVS = 1024
490                };
491
492        /// box around the whole view domain
493        AxisAlignedBox3 mBox;
494
495        /// view cell corresponding to unbounded space
496        BspViewCell *mRootCell;
497
498        /// minimal number of rays before subdivision termination
499        int mTermMinRays;
500        /// maximal possible depth
501        int mTermMaxDepth;
502        /// mininum area
503        float mTermMinArea;
504        /// mininum PVS
505        int mTermMinPvs;
506
507        /// minimal number of rays for axis aligned split
508        int mTermMinRaysForAxisAligned;
509        /// minimal number of objects for axis aligned split
510        int mTermMinObjectsForAxisAligned;
511        /// maximal contribution per ray
512        float mTermMaxRayContribution;
513        /// minimal accumulated ray length
514        float mTermMinAccRayLength;
515
516        /// strategy to get the best split plane
517        int mSplitPlaneStrategy;
518        /// number of candidates evaluated for the next split plane
519        int mMaxPolyCandidates;
520        /// number of candidates for split planes evaluated using the rays
521        int mMaxRayCandidates;
522        /// balancing factor for PVS criterium
523        float mCtDivCi;
524
525        //-- axis aligned split criteria
526        float mAxisAlignedCtDivCi;
527        /// spezifies the split border of the axis aligned split
528        float mAxisAlignedSplitBorder;
529
530        /// maximal acceptable cost ratio
531        float mTermMaxCostRatio;
532        /// tolerance value indicating how often the max cost ratio can be failed
533        int mTermMissTolerance;
534
535        //-- factors guiding the split plane heuristics
536        float mLeastRaySplitsFactor;
537        float mBalancedRaysFactor;
538        float mPvsFactor;
539
540        /// if area or accumulated ray lenght should be used for PVS heuristics
541        bool mPvsUseArea;
542        /// tolerance for polygon split
543        float mEpsilon;
544        /// maximal number of test rays used to evaluate candidate split plane
545        int mMaxTests;
546        /// number of different bsp split plane criteria
547        int mNumCriteria;
548        /// maximal number of view cells
549        int mMaxViewCells;
550
551private:
552       
553        static const float sLeastRaySplitsTable[5];
554        /** Evaluates split plane classification with respect to the plane's
555                contribution for balanced rays.
556        */
557        static const float sBalancedRaysTable[5];
558
559        /// Generates unique ids for PVS criterium
560        static void GenerateUniqueIdsForPvs();
561
562        //-- unique ids for PVS criterium
563        static int sFrontId;
564        static int sBackId;
565        static int sFrontAndBackId;
566};
567
568#endif
Note: See TracBrowser for help on using the repository browser.