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

Revision 448, 14.1 KB checked in by mattausch, 19 years ago (diff)

fixed bug in VspBspTree?
view cells in VssPreprocessor?
bounding rays for vspkdtree

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