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

Revision 466, 14.8 KB checked in by bittner, 19 years ago (diff)

changed the viewcellsmanager interface to use vssrays - some functionality like the bsp merging is now restricted

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