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

Revision 264, 11.5 KB checked in by mattausch, 19 years ago (diff)

debugged bsp stuff

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