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

Revision 242, 9.4 KB checked in by mattausch, 19 years ago (diff)

added output functions and castray method for bsp viewcells

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;
15
16
17//namespace GtpVisibilityPreprocessor {
18
19/** Container storing a soup of polygons used during BSP tree construction
20*/
21typedef std::vector<Polygon3 *> PolygonContainer;
22
23struct BspRayTraversalData
24{
25    BspNode *mNode;
26    Vector3 mExitPoint;
27    float mMaxT;
28   
29    BspRayTraversalData() {}
30
31    BspRayTraversalData(BspNode *n, const Vector3 &p, const float maxt):
32    mNode(n), mExitPoint(p), mMaxT(maxt)
33        {}
34};
35
36class BspTreeStatistics // TODO: should have common superclass with KdTreeStatistics
37{
38public:
39  // total number of nodes
40  int nodes;
41  // number of splits
42  int splits;
43  // totals number of rays
44  int rays;
45  // maximal reached depth
46  int maxDepth;
47  // total number of query domains
48  int queryDomains;
49  // total number of ray references
50  int rayRefs;
51  // refs in non empty leafs
52  int rayRefsNonZeroQuery;
53  // total number of query references
54  int objectRefs;
55  // nodes with zero queries
56  int zeroQueryNodes;
57  // max depth nodes
58  int maxDepthNodes;
59  // max number of rays per node
60  int maxObjectRefs;
61  // number of dynamically added ray refs
62  int addedRayRefs;
63  // number of dynamically removed ray refs
64  int removedRayRefs;
65 
66  // Constructor
67  BspTreeStatistics()
68  {
69          Reset();
70  }
71
72  int Nodes() const {return nodes;}
73  int Interior() const { return nodes/2; }
74  int Leaves() const { return (nodes/2) + 1; }
75
76  void Reset()
77  {
78          nodes = 0;
79          splits = 0;
80          rays = queryDomains = 0;
81          rayRefs = rayRefsNonZeroQuery = objectRefs = 0;
82          zeroQueryNodes = 0;
83      maxDepthNodes = 0;
84      //minCostNodes = 0;
85          maxObjectRefs = 0;
86          addedRayRefs = removedRayRefs = 0;
87  }
88
89  void
90  Print(ostream &app) const;
91
92  friend ostream &operator<<(ostream &s, const BspTreeStatistics &stat) {
93    stat.Print(s);
94    return s;
95  }
96 
97};
98
99/**
100    BspNode abstract class serving for interior and leaf node implementation
101*/
102class BspNode
103{
104        friend BspTree;
105
106public:
107        BspNode();
108        BspNode(BspInterior *parent);
109
110        /** Determines whether this node is a leaf or not
111        @return true if leaf
112        */
113        virtual bool IsLeaf() const = 0;
114
115        /** Determines whether this node is a root
116        @return true if root
117        */
118        virtual bool IsRoot() const;
119
120        /** Returns parent node.
121        */
122        BspInterior *GetParent();
123        /** Sets parent node.
124        */
125        void SetParent(BspInterior *parent);
126
127protected:
128
129        /// parent of this node
130        BspInterior *mParent;
131};
132
133/** BSP interior node implementation
134*/
135class BspInterior : public BspNode
136{
137public:
138        /** Standard contructor taking split plane as argument.
139        */
140        BspInterior(Plane3 plane);
141        /** @return false since it is an interior node
142        */
143        bool IsLeaf() const;
144
145        BspNode *GetBack();
146        BspNode *GetFront();
147
148        Plane3 *GetPlane();
149
150        void ReplaceChildLink(BspNode *oldChild, BspNode *newChild);
151        void SetupChildLinks(BspNode *b, BspNode *f);
152
153        /** Splits polygons.
154                @param polys the polygons to be split
155                @param frontPolys returns the polygons in the front of the split plane
156                @param backPolys returns the polygons in the back of the split plane
157                @param splits number of splits
158        */
159        void SplitPolygons(PolygonContainer *polys, PolygonContainer *frontPolys,
160                                           PolygonContainer *backPolys, int &splits);
161
162        friend ostream &operator<<(ostream &s, const BspInterior &A)
163        {
164                return s << A.mPlane;
165        }
166
167
168protected:
169       
170        /// Splitting plane corresponding to this node
171        Plane3 mPlane;
172        /// back node
173        BspNode *mBack;
174        /// front node
175        BspNode *mFront;
176};
177
178/** BSP leaf node implementation.
179*/
180class BspLeaf : public BspNode
181{
182public:
183        BspLeaf(ViewCell *viewCell = NULL);
184
185        /** @return true since it is an interior node */
186        bool IsLeaf() const;
187        ViewCell *GetViewCell();
188
189protected:
190
191        /// polygonal representation of this viewcell
192        /// if NULL this note does not correspond to feasible viewcell
193        ViewCell *mViewCell;
194};
195
196
197/** Implementation of the ViewCell BSP tree. */
198class BspTree
199{
200public:
201               
202        /** Additional data which is passed down the BSP tree during traversal.
203        */
204        struct BspTraversalData
205        { 
206                /// the current node
207                BspNode *mNode;
208                /// parent of current node
209                BspInterior *mParent;
210                /// polygonal data for splitting
211                PolygonContainer *mPolygons;
212                /// current depth
213                int mDepth;
214               
215                BspTraversalData() {}
216               
217                BspTraversalData(BspNode *node, BspInterior *parent, PolygonContainer *polys, const int depth):
218                mNode(node), mParent(parent), mPolygons(polys), mDepth(depth) {}
219    };
220
221        typedef std::stack<BspTraversalData> BspTraversalStack;
222
223        /// BSP tree construction type
224        enum {VIEWCELLS, SCENE_GEOMETRY};
225
226        /** Default constructor creating an empty tree.
227        */
228        BspTree();
229
230        ~BspTree();
231
232        const BspTreeStatistics &GetStatistics() const;
233 
234        /** Constructs tree using the given list of viewcells.
235            A pointer to the appropriate viewcell is stored within each leaf.
236                Many leafs can point to the same viewcell.
237        */
238        void Construct(const ViewCellContainer &viewCells);
239        /** Constructs tree using the given list of objects. Each leaf is taken as viewcell.
240            No objects are treated as viewcells explicitly.
241
242                @param objects list of objects
243        */
244        void Construct(const ObjectContainer &objects);
245
246        int CollectLeafPvs();
247
248        void CollectLeaves(vector<BspLeaf *> &leaves);
249
250        /** Returns box which bounds the whole tree.
251        */
252        AxisAlignedBox3 GetBoundingBox()const;
253
254        /** Returns root of BSP tree.
255        */
256        BspNode *GetRoot() const;
257
258protected:
259       
260        /** Evaluates plane classification with respect to the plane's
261                contribution for a balanced tree.
262        */
263        static inline int EvalForBalancedTree(const int classficiation);
264        /** Evaluates plane classification with respect to the plane's
265                contribution for a minimum number splits in the tree.
266        */
267        static inline int EvalForLeastSplits(const int classification);
268
269        /** Evaluates the contribution of the candidate split plane.
270        */
271        int EvalSplitPlane(PolygonContainer *polygons, const Plane3 &candidatePlane) const;
272
273        /** Evaluates tree stats in the BSP tree leafs.
274        */
275        void EvaluateLeafStats(const BspTraversalData &data);
276
277        /** Subdivides node with respect to the traversal data.
278            @param tStack current traversal stack
279                @param tData traversal data also holding node to be subdivided
280                @param viewCell the view cell that will be represented with this part of the Bsp tree.
281                @returns new root of the subtree
282        */
283        BspNode *Subdivide(BspTraversalStack &tStack, BspTraversalData &tData, ViewCell *viewCell = NULL);
284
285        /** Selects a splitting plane.
286                @param polygons the polygon data on which the split decition is based
287        */
288        Plane3 SelectPlane(PolygonContainer *polygons) const;
289
290        /** Filters next viewcell down the tree and inserts it into the appropriate leaves
291                (i.e., possibly more than one leaf).
292        */
293        void InsertViewCell(ViewCell *viewCell);
294       
295        /** Subdivide leaf.
296                @param leaf the leaf to be subdivided
297                @param parent the parent node of this leaf
298                @param polys the input polygons
299                @param depth the current tree depth
300                @param frontPolys the polygons of the front child node as a result from splitting
301                @param backPolys the polygons of the back child node as a result from splitting
302        */
303        BspNode *SubdivideNode(BspLeaf *leaf, BspInterior *parent,
304                                                        PolygonContainer *polys, const int depth,
305                                                        ViewCell *viewCell,
306                                                        PolygonContainer *frontPolys, PolygonContainer *backPolys);
307
308        /** Filters polygons down the tree.
309                @param node the current BSP node
310                @param polys the polygons to be filtered
311                @param frontPolys returns the polygons in front of the split plane
312                @param backPolys returns the polygons in the back of the split plane
313        */
314        void FilterPolygons(BspInterior *node, PolygonContainer *polys,
315                                                PolygonContainer *frontPolys, PolygonContainer *backPolys);
316
317        /** Selects the split plane in order to get a balanced tree.
318                @param polygons container of polygons
319                @param maxTests the maximal number of candidate tests
320        */
321        Plane3 SelectPlaneHeuristics(PolygonContainer *polygons, int maxTests) const;
322
323        /** Extracts the meshes of the objects and copies them into the mesh. Also calculcates the bounding box of the tree.
324                @param maxPolys the maximal number of objects to be stored as polygons
325        */
326        void Copy2PolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects);
327
328        /** Add this mesh as polygons to polygon container.
329        */
330        void AddMesh2Polygons(Mesh *mesh, PolygonContainer &polys);
331
332        /** A ray is cast possible intersecting the tree.
333                @param the ray that is cast.
334                @returns the number of intersections with objects stored in the tree.
335        */
336        int CastRay(Ray &ray);
337
338        /// Pointer to the root of the tree
339        BspNode *mRoot;
340
341        /// Pointer to the root cell of the viewspace
342        // ViewCell *mRootCell;
343               
344        BspTreeStatistics mStat;
345
346        /// local maximal polygons (changes depending on method)
347        int mTermMaxPolygons;
348        int mTermMaxDepth;
349
350        /// Strategies for choosing next split plane.
351        enum {NEXT_POLYGON, LEAST_SPLITS, BALANCED_TREE, COMBINED};
352
353        /// box around the whole view domain
354        AxisAlignedBox3 mBox;
355
356public:
357        /// Parses the environment and stores the global BSP tree parameters
358        static void ParseEnvironment();
359
360        /// maximal number of polygons where tree construction is terminated
361        static int sTermMaxPolygons;
362        /// maximal possible depth
363        static int sTermMaxDepth;
364        /// strategy to get the best split plane
365        static int sSplitPlaneStrategy;
366        /// number of candidates evaluated for the next split plane
367        static int sMaxCandidates;
368};
369
370//}; // GtpVisibilityPreprocessor
371
372#endif
Note: See TracBrowser for help on using the repository browser.