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

Revision 271, 12.2 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();
146int mViewCellIdx;
147protected:
148
149        /** Adds or discards polygons according to storePolys.
150        */
151        void ProcessPolygons(PolygonContainer *polys, const bool storePolys);
152
153
154        /// parent of this node
155        BspInterior *mParent;
156
157        /// store polygons created during BSP splits
158        PolygonContainer *mPolygons;
159};
160
161/** BSP interior node implementation
162*/
163class BspInterior : public BspNode
164{
165public:
166        /** Standard contructor taking split plane as argument.
167        */
168        BspInterior(const Plane3 &plane);
169        /** @return false since it is an interior node
170        */
171        bool IsLeaf() const;
172
173        BspNode *GetBack();
174        BspNode *GetFront();
175
176        Plane3 *GetPlane();
177
178        void ReplaceChildLink(BspNode *oldChild, BspNode *newChild);
179        void SetupChildLinks(BspNode *b, BspNode *f);
180
181        /** Splits polygons.
182                @param polys the polygons to be split
183                @param frontPolys returns the polygons in the front of the split plane
184                @param backPolys returns the polygons in the back of the split plane
185                @param splits number of splits
186                @returns true if one or more polygons are inside of the split plane
187        */
188        bool SplitPolygons(PolygonContainer *polys, PolygonContainer *frontPolys,
189                                           PolygonContainer *backPolys, int &splits, bool storePolys = false);
190
191        friend ostream &operator<<(ostream &s, const BspInterior &A)
192        {
193                return s << A.mPlane;
194        }
195
196protected:
197       
198        /** Discards or stores polygon in node.
199                @param polys the polygons
200                @param storePolys if the polygons should be stored or discarded
201        */
202        void ProcessPolygon(Polygon3 *poly, const bool storePolys);
203
204        /// Splitting plane corresponding to this node
205        Plane3 mPlane;
206        /// back node
207        BspNode *mBack;
208        /// front node
209        BspNode *mFront;
210};
211
212/** BSP leaf node implementation.
213*/
214class BspLeaf : public BspNode
215{
216        friend BspTree;
217
218public:
219        BspLeaf();
220        BspLeaf(ViewCell *viewCell);
221        BspLeaf(BspInterior *parent);
222        BspLeaf(BspInterior *parent, ViewCell *viewCell);
223
224        /** @return true since it is an interior node
225        */
226        bool IsLeaf() const;
227        /** Returns pointer from view cell.
228        */
229        ViewCell *GetViewCell();
230        /** Sets pointer to view cell.
231        */
232        void SetViewCell(ViewCell *viewCell);
233
234protected:
235
236        /// polygonal representation of this viewcell
237        /// if NULL this note does not correspond to feasible viewcell
238        ViewCell *mViewCell;
239};
240
241
242/** Implementation of the ViewCell BSP tree. */
243class BspTree
244{
245public:
246               
247        /** Additional data which is passed down the BSP tree during traversal.
248        */
249        struct BspTraversalData
250        { 
251                /// the current node
252                BspNode *mNode;
253                /// polygonal data for splitting
254                PolygonContainer *mPolygons;
255                /// current depth
256                int mDepth;
257                /// if the node is an inside or outside node with respect to the parent plane
258                bool mIsInside;
259                BspTraversalData() {}
260               
261                BspTraversalData(BspNode *node, PolygonContainer *polys, const int depth, const bool inside):
262                mNode(node), mPolygons(polys), mDepth(depth), mIsInside(inside) {}
263    };
264
265        typedef std::stack<BspTraversalData> BspTraversalStack;
266
267        /// BSP tree construction type
268        enum {VIEW_CELLS, SCENE_GEOMETRY, RAYS};
269
270        /** Default constructor creating an empty tree.
271        */
272        BspTree();
273
274        ~BspTree();
275
276        const BspTreeStatistics &GetStatistics() const;
277 
278        /** Constructs tree using the given list of view cells.
279            A pointer to the appropriate view cell is stored within each leaf.
280                Many leafs can point to the same viewcell.
281        */
282        void Construct(const ViewCellContainer &viewCells);
283
284        /** Constructs tree using the given list of objects.
285            Note that the objects are not taken as view cells, but the view cells are
286                constructed from the subdivision: Each leaf is taken as one viewcell;
287
288                @param objects list of objects
289                @returns list of view cells.
290        */
291        void Construct(const ObjectContainer &objects, ViewCellContainer *viewCells);
292
293        /** Constructs tree using the given number of rays
294            @param objects list of objects
295                @returns list of view cells.
296        */
297        void Construct(const RayContainer &rays, ViewCellContainer *viewCells);
298
299        int CollectLeafPvs();
300
301        void CollectLeaves(vector<BspLeaf *> &leaves);
302
303        /** Returns box which bounds the whole tree.
304        */
305        AxisAlignedBox3 GetBoundingBox()const;
306
307        /** Returns root of BSP tree.
308        */
309        BspNode *GetRoot() const;
310
311        /** If the view cell polygons are stored in the nodes.
312        */
313        bool StorePolys() const;
314
315        /** Exports Bsp tree to file.
316        */
317        bool Export(const string filename);
318
319static bool displayDebug;
320protected:
321       
322        /** Initialises BSP tree.
323                @param maxPolygons the maximal polygon count before termination of
324                subdivision
325                @param maxDepth the maximal depth before termination of
326                subdivision
327        */
328        void InitTree(int maxPolygons, int maxDepth);
329
330        /** Constructs the tree from the given list of polygons.
331                @param viewCells if not NULL, new view cells are
332                created in the leafs and stored in the conatainer
333        */
334        void Construct(PolygonContainer *polys, ViewCellContainer *viewCells = NULL);
335
336        /** Evaluates the contribution of the candidate split plane.
337        */
338        int EvalSplitPlane(PolygonContainer *polygons, const Plane3 &candidatePlane) const;
339
340        /** Evaluates tree stats in the BSP tree leafs.
341        */
342        void EvaluateLeafStats(const BspTraversalData &data);
343
344        /** Subdivides node with respect to the traversal data.
345            @param tStack current traversal stack
346                @param tData traversal data also holding node to be subdivided
347                @param viewCell the view cell that will be represented with this part of the Bsp tree.
348                @returns new root of the subtree
349        */
350        BspNode *Subdivide(BspTraversalStack &tStack, BspTraversalData &tData, ViewCell *viewCell = NULL);
351
352        /** Selects a splitting plane.
353                @param polys the polygon list on which the split decition is based
354        */
355        Plane3 SelectPlane(PolygonContainer *polys) const;
356
357        /** Filters next viewcell down the tree and inserts it into the appropriate leaves
358                (i.e., possibly more than one leaf).
359        */
360        void InsertViewCell(ViewCell *viewCell);
361       
362        /** Subdivide leaf.
363                @param leaf the leaf to be subdivided
364                @param polys the input polygons
365                @param frontPolys the polygons of the front child node as a result from splitting
366                @param backPolys the polygons of the back child node as a result from splitting
367                @param if the polygons are outside or inside with respect to the interior node plane
368                @returns the root of the subdivision
369        */
370        BspInterior *SubdivideNode(BspLeaf *leaf,
371                                                           PolygonContainer *polys,
372                                                           PolygonContainer *frontPolys,
373                                                           PolygonContainer *backPolys, bool &inside);
374
375        /** Filters polygons down the tree.
376                @param node the current BSP node
377                @param polys the polygons to be filtered
378                @param frontPolys returns the polygons in front of the split plane
379                @param backPolys returns the polygons in the back of the split plane
380        */
381        void FilterPolygons(BspInterior *node, PolygonContainer *polys,
382                                                PolygonContainer *frontPolys, PolygonContainer *backPolys);
383
384        /** Selects the split plane in order to get a balanced tree.
385                @param polygons container of polygons
386                @param maxTests the maximal number of candidate tests
387        */
388        Plane3 SelectPlaneHeuristics(PolygonContainer *polygons, int maxTests) const;
389
390        /** Extracts the meshes of the objects and copies them into the mesh.
391                Adds object aabb to the aabb of the tree.
392                @param maxPolys the maximal number of objects to be stored as polygons
393                @returns the number of polygons
394        */
395        int Copy2PolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects = 0);
396        /** Extracts the meshes of the view cells and copies them into the mesh.
397                Adds view cell aabb to the aabb of the tree.
398                @param maxPolys the maximal number of objects to be stored as polygons
399                @returns the number of polygons
400        */
401        int Copy2PolygonSoup(const ViewCellContainer &viewCells, PolygonContainer &polys, int maxObjects = 0);
402
403        /** Extract polygons of this mesh and add to polygon container.
404                @returns number of polygons
405        */
406        int AddMesh2Polygons(Mesh *mesh, PolygonContainer &polys);
407
408        /** A ray is cast possible intersecting the tree.
409                @param the ray that is cast.
410                @returns the number of intersections with objects stored in the tree.
411        */
412        int CastRay(Ray &ray);
413
414        /// Pointer to the root of the tree
415        BspNode *mRoot;
416
417        /// Pointer to the root cell of the viewspace
418        // ViewCell *mRootCell;
419               
420        BspTreeStatistics mStat;
421
422        /// local maximal polygons (changes depending on method)
423        int mTermMaxPolygons;
424        int mTermMaxDepth;
425
426        /// Strategies for choosing next split plane.
427        enum {NEXT_POLYGON, LEAST_SPLITS, BALANCED_TREE, COMBINED};
428
429        /// box around the whole view domain
430        AxisAlignedBox3 mBox;
431
432                /// if view cell calculation is incremential
433        bool mIsIncremential;
434
435        /// if polygons should be stored in the tree
436        bool mStorePolys;
437
438public:
439        /// Parses the environment and stores the global BSP tree parameters
440        static void ParseEnvironment();
441
442        /// maximal number of polygons where tree construction is terminated
443        static int sTermMaxPolygons;
444        /// maximal possible depth
445        static int sTermMaxDepth;
446        /// strategy to get the best split plane
447        static int sSplitPlaneStrategy;
448        /// number of candidates evaluated for the next split plane
449        static int sMaxCandidates;
450        /// BSP tree construction method
451        static int sConstructionMethod;
452
453private:
454        /** Evaluates split plane classification with respect to the plane's
455                contribution for a balanced tree.
456        */
457        static int sLeastSplitsTable[4];
458        /** Evaluates split plane classification with respect to the plane's
459                contribution for a minimum number splits in the tree.
460        */
461        static int sBalancedTreeTable[4];
462};
463
464//}; // GtpVisibilityPreprocessor
465
466#endif
Note: See TracBrowser for help on using the repository browser.