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

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