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

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

worked on vsp kd view cells

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
210protected:
211
212        // --------------------------------------------------------------
213        // For sorting objects
214        // --------------------------------------------------------------
215        struct SortableEntry
216        {
217                enum {POLY_MIN, POLY_MAX};
218   
219                int type;
220                float value;
221                Polygon3 *poly;
222                SortableEntry() {}
223                SortableEntry(const int t, const float v, Polygon3 *poly):
224                type(t), value(v), poly(poly) {}
225               
226                bool operator<(const SortableEntry &b) const
227                {
228                        return value < b.value;
229                } 
230        };
231
232        /** Evaluates tree stats in the BSP tree leafs.
233        */
234        void EvaluateLeafStats(const VspBspTraversalData &data);
235
236        /** Subdivides node with respect to the traversal data.
237            @param tStack current traversal stack
238                @param tData traversal data also holding node to be subdivided
239                @returns new root of the subtree
240        */
241        BspNode *Subdivide(VspBspTraversalStack &tStack,
242                                           VspBspTraversalData &tData);
243
244        /** Constructs the tree from the given traversal data.
245                @param polys stores set of polygons on which subdivision may be based
246                @param rays storesset of rays on which subdivision may be based
247        */
248        void Construct(const PolygonContainer &polys, RayInfoContainer *rays);
249
250        /** Selects the best possible splitting plane.
251                @param leaf the leaf to be split
252                @param polys the polygon list on which the split decition is based
253                @param rays ray container on which selection may be based
254                @note the polygons can be reordered in the process
255                @returns the split plane
256        */
257        Plane3 SelectPlane(BspLeaf *leaf,
258                                           VspBspTraversalData &data);
259
260       
261        /** Strategies where the effect of the split plane is tested
262            on all input rays.
263
264                @returns the cost of the candidate split plane
265        */
266        float SplitPlaneCost(const Plane3 &candidatePlane,
267                                                 const VspBspTraversalData &data);
268
269
270
271        /** Subdivide leaf.
272                @param leaf the leaf to be subdivided
273               
274                @param polys the polygons to be split
275                @param frontPolys returns the polygons in front of the split plane
276                @param backPolys returns the polygons in the back of the split plane
277               
278                @param rays the polygons to be filtered
279                @param frontRays returns the polygons in front of the split plane
280                @param backRays returns the polygons in the back of the split plane
281
282                @returns the root of the subdivision
283        */
284
285        BspInterior *SubdivideNode(VspBspTraversalData &tData,
286                                                           VspBspTraversalData &frontData,
287                                                           VspBspTraversalData &backData,
288                                                           PolygonContainer &coincident);
289
290        /** Selects the split plane in order to construct a tree with
291                certain characteristics (e.g., balanced tree, least splits,
292                2.5d aligned)
293                @param polygons container of polygons
294                @param rays bundle of rays on which the split can be based
295        */
296        Plane3 SelectPlaneHeuristics(BspLeaf *leaf,
297                                                                 VspBspTraversalData &data);
298
299        /** Extracts the meshes of the objects and adds them to polygons.
300                Adds object aabb to the aabb of the tree.
301                @param maxPolys the maximal number of objects to be stored as polygons
302                @returns the number of polygons
303        */
304        int AddToPolygonSoup(const ObjectContainer &objects,
305                                                 PolygonContainer &polys,
306                                                 int maxObjects = 0);
307
308        /** Extracts the meshes of the view cells and and adds them to polygons.
309                Adds view cell aabb to the aabb of the tree.
310                @param maxPolys the maximal number of objects to be stored as polygons
311                @returns the number of polygons
312        */
313        int AddToPolygonSoup(const ViewCellContainer &viewCells,
314                                                 PolygonContainer &polys,
315                                                 int maxObjects = 0);
316
317        /** Extract polygons of this mesh and add to polygon container.
318                @param mesh the mesh that drives the polygon construction
319                @param parent the parent intersectable this polygon is constructed from
320                @returns number of polygons
321        */
322        int AddMeshToPolygons(Mesh *mesh, PolygonContainer &polys, MeshInstance *parent);
323
324        /** returns next candidate index and reorders polygons so no candidate is chosen two times
325                @param the current candidate index
326                @param max the range of candidates
327        */
328        int GetNextCandidateIdx(int currentIdx, PolygonContainer &polys);
329       
330        /** Computes best cost ratio for the suface area heuristics for axis aligned
331                splits. This heuristics minimizes the cost for ray traversal.
332                @param polys the polygons guiding the ratio computation
333                @param box the bounding box of the leaf
334                @param axis the current split axis
335                @param position returns the split position
336                @param objectsBack the number of objects in the back of the split plane
337                @param objectsFront the number of objects in the front of the split plane
338        */
339        float BestCostRatio(const PolygonContainer &polys,
340                                                const AxisAlignedBox3 &box,
341                                                const int axis,
342                                                float &position,
343                                                int &objectsBack,
344                                                int &objectsFront) const;
345       
346        /** Sorts split candidates for surface area heuristics for axis aligned splits.
347                @param polys the input for choosing split candidates
348                @param axis the current split axis
349                @param splitCandidates returns sorted list of split candidates
350        */
351        void SortSplitCandidates(const PolygonContainer &polys,
352                                                         const int axis,
353                                                         vector<SortableEntry> &splitCandidates) const;
354
355        /** Selects an axis aligned split plane.
356                Returns true if split is valied
357        */
358        bool SelectAxisAlignedPlane(Plane3 &plane, const PolygonContainer &polys) const;
359
360        /** Subdivides the rays into front and back rays according to the split plane.
361               
362                @param plane the split plane
363                @param rays contains the rays to be split. The rays are
364                           distributed into front and back rays.
365                @param frontRays returns rays on the front side of the plane
366                @param backRays returns rays on the back side of the plane
367               
368                @returns the number of splits
369        */
370        int SplitRays(const Plane3 &plane,
371                                  RayInfoContainer &rays,
372                              RayInfoContainer &frontRays,
373                                  RayInfoContainer &backRays);
374
375
376        /** Extracts the split planes representing the space bounded by node n.
377        */
378        void ExtractHalfSpaces(BspNode *n, vector<Plane3> &halfSpaces) const;
379
380        /** Adds the object to the pvs of the front and back leaf with a given classification.
381
382                @param obj the object to be added
383                @param cf the ray classification regarding the split plane
384                @param frontPvs returns the PVS of the front partition
385                @param backPvs returns the PVS of the back partition
386       
387        */
388        void AddObjToPvs(Intersectable *obj, const int cf, int &frontPvs, int &backPvs) const;
389       
390        /** Computes PVS size induced by the rays.
391        */
392        int ComputePvsSize(const RayInfoContainer &rays) const;
393
394        /** Returns true if tree can be terminated.
395        */
396        inline bool TerminationCriteriaMet(const VspBspTraversalData &data) const;
397
398        /** Computes accumulated ray lenght of this rays.
399        */
400        float AccumulatedRayLength(const RayInfoContainer &rays) const;
401
402        /** Splits polygons with respect to the split plane.
403
404                @param plane the split plane
405                @param polys the polygons to be split. the polygons are consumed and
406                           distributed to the containers frontPolys, backPolys, coincident.
407                @param frontPolys returns the polygons in the front of the split plane
408                @param backPolys returns the polygons in the back of the split plane
409                @param coincident returns the polygons coincident to the split plane
410
411                @returns the number of splits   
412        */
413        int SplitPolygons(const Plane3 &plane,
414                                          PolygonContainer &polys,
415                                          PolygonContainer &frontPolys,
416                                          PolygonContainer &backPolys,
417                                          PolygonContainer &coincident) const;
418
419        /** Adds ray sample contributions to the PVS.
420                @param sampleContributions the number contributions of the samples
421                @param contributingSampels the number of contributing rays
422               
423        */
424        void AddToPvs(BspLeaf *leaf,
425                                  const RayInfoContainer &rays,
426                                  int &sampleContributions,
427                                  int &contributingSamples);
428
429        /// Pointer to the root of the tree
430        BspNode *mRoot;
431               
432        BspTreeStatistics mStat;
433
434        /// Strategies for choosing next split plane.
435        enum {NO_STRATEGY = 0,
436                  RANDOM_POLYGON = 1,
437                  AXIS_ALIGNED = 2,
438                  LEAST_RAY_SPLITS = 256,
439                  BALANCED_RAYS = 512,
440                  PVS = 1024
441                };
442
443        /// box around the whole view domain
444        AxisAlignedBox3 mBox;
445
446        /// view cell corresponding to unbounded space
447        BspViewCell *mRootCell;
448
449        /// minimal number of rays before subdivision termination
450        int mTermMinRays;
451        /// maximal possible depth
452        int mTermMaxDepth;
453        /// mininum area
454        float mTermMinArea;
455        /// mininum PVS
456        int mTermMinPvs;
457
458        /// minimal number of rays for axis aligned split
459        int mTermMinRaysForAxisAligned;
460        /// minimal number of objects for axis aligned split
461        int mTermMinObjectsForAxisAligned;
462        /// maximal contribution per ray
463        float mTermMaxRayContribution;
464        /// minimal accumulated ray length
465        float mTermMinAccRayLength;
466
467
468        /// strategy to get the best split plane
469        int mSplitPlaneStrategy;
470        /// number of candidates evaluated for the next split plane
471        int mMaxPolyCandidates;
472        /// number of candidates for split planes evaluated using the rays
473        int mMaxRayCandidates;
474        /// balancing factor for PVS criterium
475        float mCtDivCi;
476
477        //-- axis aligned split criteria
478        float mAaCtDivCi;
479        float mSplitBorder;
480        float mMaxCostRatio;
481
482        //-- factors guiding the split plane heuristics
483        float mLeastRaySplitsFactor;
484        float mBalancedRaysFactor;
485        float mPvsFactor;
486
487        /// if area or accumulated ray lenght should be used for PVS heuristics
488        bool mPvsUseArea;
489
490        float mEpsilon;
491
492        int mMaxTests;
493
494private:
495       
496        static const float sLeastRaySplitsTable[5];
497        /** Evaluates split plane classification with respect to the plane's
498                contribution for balanced rays.
499        */
500        static const float sBalancedRaysTable[5];
501
502        /// Generates unique ids for PVS criterium
503        static void GenerateUniqueIdsForPvs();
504
505        //-- unique ids for PVS criterium
506        static int sFrontId;
507        static int sBackId;
508        static int sFrontAndBackId;
509};
510
511#endif
Note: See TracBrowser for help on using the repository browser.