source: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h @ 289

Revision 289, 13.1 KB checked in by mattausch, 19 years ago (diff)
Line 
1#ifndef _ViewCellBsp_H__
2#define _ViewCellBsp_H__
3
4#include "Mesh.h"
5#include "Containers.h"
6#include <stack>
7
8class ViewCell;
9class Plane3;
10//class Mesh;
11class BspTree; 
12class BspInterior;
13class Polygon3;
14class AxisAlignedBox3;
15class Ray;
16
17//namespace GtpVisibilityPreprocessor {
18
19/** Container storing a soup of polygons used during BSP tree construction
20*/
21typedef vector<Polygon3 *> PolygonContainer;
22typedef vector<Ray *> RayContainer;
23
24struct BspRayTraversalData
25{
26    BspNode *mNode;
27    Vector3 mExitPoint;
28    float mMaxT;
29   
30    BspRayTraversalData() {}
31
32    BspRayTraversalData(BspNode *n, const Vector3 &p, const float maxt):
33    mNode(n), mExitPoint(p), mMaxT(maxt)
34        {}
35};
36
37class BspTreeStatistics // TODO: should have common superclass with KdTreeStatistics
38{
39public:
40  // total number of nodes
41  int nodes;
42  // number of splits
43  int splits;
44  // totals number of rays
45  int rays;
46  // maximal reached depth
47  int maxDepth;
48  // minimal depth
49  int minDepth;
50  // total number of query domains
51  int queryDomains;
52  // total number of ray references
53  int rayRefs;
54  // refs in non empty leafs
55  int rayRefsNonZeroQuery;
56  // total number of query references
57  int objectRefs;
58  // nodes with zero queries
59  int zeroQueryNodes;
60  // max depth nodes
61  int maxDepthNodes;
62  // max number of rays per node
63  int maxObjectRefs;
64  // number of dynamically added ray refs
65  int addedRayRefs;
66  // number of dynamically removed ray refs
67  int removedRayRefs;
68  // accumulated depth (used to compute average)
69  int accumDepth;
70  // number of initial polygons
71  int polys;
72  /// number of view cells in leaf
73  int viewCellLeaves;
74
75  // Constructor
76  BspTreeStatistics()
77  {
78          Reset();
79  }
80
81  int Nodes() const {return nodes;}
82  int Interior() const { return nodes / 2; }
83  int Leaves() const { return (nodes / 2) + 1; }
84  double AvgDepth() const { return accumDepth / (double)Leaves();}; // TODO: computation wrong
85 
86  void Reset()
87  {
88          nodes = 0;
89          splits = 0;
90          rays = queryDomains = 0;
91          rayRefs = rayRefsNonZeroQuery = objectRefs = 0;
92          zeroQueryNodes = 0;
93      maxDepthNodes = 0;
94
95          maxObjectRefs = 0;
96          addedRayRefs = removedRayRefs = 0;
97          maxDepth = 0;
98          minDepth = 99999;
99          polys = 0;
100          accumDepth = 0;
101          viewCellLeaves = 0;
102  }
103
104  void
105  Print(ostream &app) const;
106
107  friend ostream &operator<<(ostream &s, const BspTreeStatistics &stat) {
108    stat.Print(s);
109    return s;
110  }
111 
112};
113
114/**
115    BspNode abstract class serving for interior and leaf node implementation
116*/
117class BspNode
118{
119        friend BspTree;
120
121public:
122        BspNode();
123        virtual ~BspNode();
124        BspNode(BspInterior *parent);
125
126        /** Determines whether this node is a leaf or not
127        @return true if leaf
128        */
129        virtual bool IsLeaf() const = 0;
130
131        /** Determines whether this node is a root
132        @return true if root
133        */
134        virtual bool IsRoot() const;
135
136        /** Returns parent node.
137        */
138        BspInterior *GetParent();
139        /** Sets parent node.
140        */
141        void SetParent(BspInterior *parent);
142
143        /** Returns pointer to polygons.
144        */
145        PolygonContainer *GetPolygons();
146        /** Stores polygons in node or discards them according to storePolys.
147        */
148        void ProcessPolygons(PolygonContainer *polys, const bool storePolys);
149
150//int mViewCellIdx;
151protected:
152
153        /// parent of this node
154        BspInterior *mParent;
155
156        /// store polygons created during BSP splits
157        PolygonContainer *mPolygons;
158};
159
160/** BSP interior node implementation
161*/
162class BspInterior : public BspNode
163{
164public:
165        /** Standard contructor taking split plane as argument.
166        */
167        BspInterior(const Plane3 &plane);
168        /** @return false since it is an interior node
169        */
170        bool IsLeaf() const;
171
172        BspNode *GetBack();
173        BspNode *GetFront();
174
175        Plane3 *GetPlane();
176
177        void ReplaceChildLink(BspNode *oldChild, BspNode *newChild);
178        void SetupChildLinks(BspNode *b, BspNode *f);
179
180        /** Splits polygons.
181                @param polys the polygons to be split
182                @param frontPolys returns the polygons in the front of the split plane
183                @param backPolys returns the polygons in the back of the split plane
184                @param coincident returns the polygons coincident to the split plane
185                @param splits returns the splits number of splits       
186                @param storePolys if the polygons should be stored in the node
187        */
188        void SplitPolygons(PolygonContainer *polys,
189                                           PolygonContainer *frontPolys,
190                                           PolygonContainer *backPolys,
191                                           PolygonContainer *coincident,
192                                           int &splits,
193                                           bool storePolys = false);
194
195        /** Stores polygon in node or discards them according to storePolys.
196                @param polys the polygons
197                @param storePolys if the polygons should be stored or discarded
198        */
199        void ProcessPolygon(Polygon3 **poly, const bool storePolys);
200
201        friend ostream &operator<<(ostream &s, const BspInterior &A)
202        {
203                return s << A.mPlane;
204        }
205
206protected:     
207       
208        /// Splitting plane corresponding to this node
209        Plane3 mPlane;
210        /// back node
211        BspNode *mBack;
212        /// front node
213        BspNode *mFront;
214};
215
216/** BSP leaf node implementation.
217*/
218class BspLeaf : public BspNode
219{
220        friend BspTree;
221
222public:
223        BspLeaf();
224        BspLeaf(ViewCell *viewCell);
225        BspLeaf(BspInterior *parent);
226        BspLeaf(BspInterior *parent, ViewCell *viewCell);
227
228        /** @return true since it is an interior node
229        */
230        bool IsLeaf() const;
231        /** Returns pointer from view cell.
232        */
233        ViewCell *GetViewCell();
234        /** Sets pointer to view cell.
235        */
236        void SetViewCell(ViewCell *viewCell);
237
238protected:
239
240        /// polygonal representation of this viewcell
241        /// if NULL this note does not correspond to feasible viewcell
242        ViewCell *mViewCell;
243};
244
245
246/** Implementation of the ViewCell BSP tree. */
247class BspTree
248{
249public:
250               
251        /** Additional data which is passed down the BSP tree during traversal.
252        */
253        struct BspTraversalData
254        { 
255                /// the current node
256                BspNode *mNode;
257                /// polygonal data for splitting
258                PolygonContainer *mPolygons;
259                /// current depth
260                int mDepth;
261                /// the view cell associated with this subdivsion
262                ViewCell *mViewCell;
263                /// if the node is an inside or outside node with respect to the parent plane
264                //bool mIsInside;
265                BspTraversalData() {}
266               
267                BspTraversalData(BspNode *node, PolygonContainer *polys, const int depth, ViewCell *viewCell):
268                mNode(node), mPolygons(polys), mDepth(depth), mViewCell(viewCell) {}
269    };
270
271        typedef std::stack<BspTraversalData> BspTraversalStack;
272
273        /// BSP tree construction type
274        enum {VIEW_CELLS, SCENE_GEOMETRY, RAYS};
275
276        /** Default constructor creating an empty tree.
277        */
278        BspTree();
279
280        ~BspTree();
281
282        const BspTreeStatistics &GetStatistics() const;
283 
284        /** Constructs tree using the given list of view cells.
285            For this type of construction we filter all view cells down the
286                tree. If there is no polygon left, the last split plane
287            decides inside or outside of the viewcell. A pointer to the
288                appropriate view cell is stored within each leaf.
289                Many leafs can point to the same viewcell.
290        */
291        void Construct(const ViewCellContainer &viewCells);
292
293        /** Constructs tree using the given list of objects.
294            Note that the objects are not taken as view cells, but the view cells are
295                constructed from the subdivision: Each leaf is taken as one viewcell;
296
297                @param objects list of objects
298                @returns list of view cells.
299        */
300        void Construct(const ObjectContainer &objects, ViewCellContainer *viewCells);
301
302        /** Constructs tree using the given number of rays
303            @param objects list of objects
304                @returns list of view cells.
305        */
306        void Construct(const RayContainer &rays, ViewCellContainer *viewCells);
307
308        int CollectLeafPvs();
309
310        void CollectLeaves(vector<BspLeaf *> &leaves);
311
312        /** Returns box which bounds the whole tree.
313        */
314        AxisAlignedBox3 GetBoundingBox()const;
315
316        /** Returns root of BSP tree.
317        */
318        BspNode *GetRoot() const;
319
320        /** If the view cell polygons are stored in the nodes.
321        */
322        bool StorePolys() const;
323
324        /** Exports Bsp tree to file.
325        */
326        bool Export(const string filename);
327
328        //static bool displayDebug;
329protected:
330       
331        /** Initialises BSP tree.
332                @param maxPolygons the maximal polygon count before termination of
333                subdivision
334                @param maxDepth the maximal depth before termination of
335                subdivision
336        */
337        void InitTree(int maxPolygons, int maxDepth);
338
339        /** Constructs the tree from the given list of polygons.
340                @param viewCells if not NULL, new view cells are
341                created in the leafs and stored in the conatainer
342        */
343        void Construct(PolygonContainer *polys, ViewCellContainer *viewCells = NULL);
344
345        /** Evaluates the contribution of the candidate split plane.
346        */
347        int EvalSplitPlane(PolygonContainer *polygons, const Plane3 &candidatePlane) const;
348
349        /** Evaluates tree stats in the BSP tree leafs.
350        */
351        void EvaluateLeafStats(const BspTraversalData &data);
352
353        /** Subdivides node with respect to the traversal data.
354            @param tStack current traversal stack
355                @param tData traversal data also holding node to be subdivided
356                @param viewCellContainer if not null, a new viewcell is created and stored in the container
357                @returns new root of the subtree
358        */
359        BspNode *Subdivide(BspTraversalStack &tStack, BspTraversalData &tData, ViewCellContainer *viewCells = NULL);
360
361        /** Selects a splitting plane.
362                @param polys the polygon list on which the split decition is based
363        */
364        Plane3 SelectPlane(PolygonContainer *polys) const;
365
366        /** Filters next view cell down the tree and inserts it into the appropriate leaves
367                (i.e., possibly more than one leaf).
368        */
369        void InsertViewCell(ViewCell *viewCell);
370        /** Inserts polygons down the tree. The polygons are filtered until a leaf is reached,
371                then further subdivided.
372                @param viewCellContainer if not null, a new viewcell is created and stored in the container
373        */
374        void InsertPolygons(PolygonContainer *polys, ViewCellContainer *viewCells = NULL);
375
376        /** Subdivide leaf.
377                @param leaf the leaf to be subdivided
378                @param polys the input polygons
379                @param frontPolys returns the polygons in the front of the split plane
380                @param backPolys returns the polygons in the back of the split plane
381                @param coincident returns the polygons coincident to the split plane
382                @returns the root of the subdivision
383        */
384        BspInterior *SubdivideNode(BspLeaf *leaf,
385                                                           PolygonContainer *polys,
386                                                           PolygonContainer *frontPolys,
387                                                           PolygonContainer *backPolys,
388                                                           PolygonContainer *coincident);
389
390        /** Filters polygons down the tree.
391                @param node the current BSP node
392                @param polys the polygons to be filtered
393                @param frontPolys returns the polygons in front of the split plane
394                @param backPolys returns the polygons in the back of the split plane
395        */
396        void FilterPolygons(BspInterior *node, PolygonContainer *polys,
397                                                PolygonContainer *frontPolys, PolygonContainer *backPolys);
398
399        /** Selects the split plane in order to get a balanced tree.
400                @param polygons container of polygons
401                @param maxTests the maximal number of candidate tests
402        */
403        Plane3 SelectPlaneHeuristics(PolygonContainer *polygons, int maxTests) const;
404
405        /** Extracts the meshes of the objects and copies them into the mesh.
406                Adds object aabb to the aabb of the tree.
407                @param maxPolys the maximal number of objects to be stored as polygons
408                @returns the number of polygons
409        */
410        int Copy2PolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects = 0);
411        /** Extracts the meshes of the view cells and copies them into the mesh.
412                Adds view cell aabb to the aabb of the tree.
413                @param maxPolys the maximal number of objects to be stored as polygons
414                @returns the number of polygons
415        */
416        int Copy2PolygonSoup(const ViewCellContainer &viewCells, PolygonContainer &polys, int maxObjects = 0);
417
418        /** Extract polygons of this mesh and add to polygon container.
419                @param mesh the mesh that drives the polygon construction
420                @param parent the parent intersectable this polygon is constructed from
421                @returns number of polygons
422        */
423        int AddMesh2Polygons(Mesh *mesh, PolygonContainer &polys, Intersectable *parent = NULL);
424
425        /** A ray is cast possible intersecting the tree.
426                @param the ray that is cast.
427                @returns the number of intersections with objects stored in the tree.
428        */
429        int CastRay(Ray &ray);
430
431        /// Pointer to the root of the tree
432        BspNode *mRoot;
433
434        /// Pointer to the root cell of the viewspace
435        // ViewCell *mRootCell;
436               
437        BspTreeStatistics mStat;
438
439        /// local maximal polygons (changes depending on method)
440        int mTermMaxPolygons;
441        int mTermMaxDepth;
442
443        /// Strategies for choosing next split plane.
444        enum {NEXT_POLYGON, LEAST_SPLITS, BALANCED_TREE, COMBINED};
445
446        /// box around the whole view domain
447        AxisAlignedBox3 mBox;
448
449                /// if view cell calculation is incremential
450        bool mIsIncremential;
451
452        /// if polygons should be stored in the tree
453        bool mStorePolys;
454
455public:
456        /// Parses the environment and stores the global BSP tree parameters
457        static void ParseEnvironment();
458
459        /// maximal number of polygons where tree construction is terminated
460        static int sTermMaxPolygons;
461        /// maximal possible depth
462        static int sTermMaxDepth;
463        /// strategy to get the best split plane
464        static int sSplitPlaneStrategy;
465        /// number of candidates evaluated for the next split plane
466        static int sMaxCandidates;
467        /// BSP tree construction method
468        static int sConstructionMethod;
469
470private:
471        /** Evaluates split plane classification with respect to the plane's
472                contribution for a balanced tree.
473        */
474        static int sLeastSplitsTable[4];
475        /** Evaluates split plane classification with respect to the plane's
476                contribution for a minimum number splits in the tree.
477        */
478        static int sBalancedTreeTable[4];
479};
480
481//}; // GtpVisibilityPreprocessor
482
483#endif
Note: See TracBrowser for help on using the repository browser.