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

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