source: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp @ 224

Revision 224, 7.2 KB checked in by mattausch, 19 years ago (diff)

added stuff for bsp tree

Line 
1#include "Plane3.h"
2#include "ViewCellBsp.h"
3#include "Mesh.h"
4
5#include "ViewCell.h"
6#include <stack>
7
8#define DEL_PTR(ptr) while (0) {if (ptr) {delete (ptr); (ptr) = NULL;}}
9
10//namespace GtpVisibilityPreprocessor {
11/****************************************************************/
12/*                  class BspNode implementation                */
13/****************************************************************/
14bool BspNode::IsRoot() const
15{
16        return mParent == NULL;
17}
18
19BspInterior *BspNode::GetParent()
20{
21        return mParent;
22}
23/****************************************************************/
24/*              class BspInterior implementation                */
25/****************************************************************/
26
27
28BspInterior::BspInterior(Plane3 plane): mPlane(plane)
29{}
30
31bool BspInterior::IsLeaf() const
32{
33        return false;
34}
35
36BspNode *BspInterior::GetBack()
37{
38        return mBack;
39}
40
41BspNode *BspInterior::GetFront()
42{
43        return mFront;
44}
45
46Plane3 *BspInterior::GetPlane()
47{
48        return &mPlane;
49}
50
51void BspInterior::ReplaceChildLink(BspNode *oldChild, BspNode *newChild)
52{
53        if (mBack == oldChild)
54        {
55                mBack = newChild;
56        }
57    else
58        {
59                mFront = newChild;
60        }
61}
62
63void BspInterior::SetupChildLinks(BspNode *b, BspNode *f)
64{
65    mBack = b;
66    mFront = f;
67}
68
69/****************************************************************/
70/*                  class BspLeaf implementation                */
71/****************************************************************/
72
73BspLeaf::BspLeaf(ViewCell *viewCell): mViewCell(viewCell)
74{
75}
76
77ViewCell *BspLeaf::GetViewCell()
78{
79        return mViewCell;
80}
81
82bool BspLeaf::IsLeaf() const
83{
84        return true;
85}
86
87/****************************************************************/
88/*                  class BspTree implementation                */
89/****************************************************************/
90
91BspTree::BspTree(const ViewCellContainer &viewCells):
92mMaxPolys(0), mMaxDepth(0), mRoot(NULL)
93{
94        //mRootCell = cell;
95        Subdivide(viewCells);
96}
97
98BspTree::BspTree(const ObjectContainer &objects, int maxPolys, int maxDepth):
99mMaxPolys(maxPolys), mMaxDepth(maxDepth)
100{
101        mRoot = new BspLeaf();
102
103        Subdivide(objects);
104}
105 
106BspTree::~BspTree()
107{
108        std::stack<BspNode *> tStack;
109
110        tStack.push(mRoot);
111
112        while (!tStack.empty())
113        {
114                BspNode *node = tStack.top();
115
116            tStack.pop();
117       
118                if (!node->IsLeaf())
119                {
120                        BspInterior *interior = dynamic_cast<BspInterior *>(node);
121
122                        // push the children on the stack (there are always two children)
123                        interior->GetBack()->mParent = NULL;
124                        interior->GetFront()->mParent = NULL;
125
126                        tStack.push(interior->GetBack());
127                        tStack.push(interior->GetFront());
128                }
129
130                delete node;
131                node = NULL;
132        }
133}
134
135
136void BspTree::InsertViewCell(ViewCell *viewCell)
137{
138        BspNode *currentNode = mRoot;
139 
140        std::stack<BspTraversalData> tStack;
141        //  stack<STraversalData> tStack;
142
143        //tStack.push(tdata);
144
145        while (!tStack.empty())
146        {
147            BspTraversalData data = tStack.top();
148
149            tStack.pop();
150   
151                Mesh backPolys;
152                Mesh frontPolys;
153
154                if (data.mNode->IsLeaf()) // if we have a leaf => subdivide
155                {
156                        BspNode *node = SubdivideNode(dynamic_cast<BspLeaf *>(data.mNode),
157                                                                                  data.mParent,
158                                                                                  data.mPolys,
159                                                                              data.mDepth,
160                                                                                  backPolys,
161                                                                                  frontPolys);
162       
163                        if (!node->IsLeaf()) // node was subdivided
164                        {
165                                BspInterior *interior = dynamic_cast<BspInterior *>(node);
166
167                                // push the children on the stack (there are always two children)
168                                //tStack.push(BspTraversalData(interior->GetBack(), interior, backPolys, data.mDepth + 1));
169                                //tStack.push(BspTraversalData(interior->GetFront(), interior, frontPolys, data.mDepth + 1));
170                        }
171                }
172        }
173}
174
175void BspTree::Subdivide(const ViewCellContainer &viewCells)
176{
177}
178
179void BspTree::Copy2PolygonSoup(const ObjectContainer &objects, Mesh &mesh)
180{
181        ObjectContainer::const_iterator it, it_end = objects.end();
182
183        for (it = objects.begin(); it != it_end; ++ it)
184        {
185                FaceContainer::const_iterator fi;
186                Intersectable *object = *it;
187
188                // extract the mesh instances
189                if (object->Type() == Intersectable::MESH_INSTANCE)
190                {
191                        MeshInstance *inst = dynamic_cast<MeshInstance *>(object);
192
193                        Mesh *polys = inst->GetMesh();
194
195                        // copy the face data
196                        for (fi = polys->mFaces.begin(); fi != polys->mFaces.end(); ++ fi)
197                        {
198                                Face *face = new Face((*fi)->mVertexIndices);
199                                mesh.AddFace(face);
200                        }
201                }
202        }
203}
204
205void BspTree::Subdivide(const ObjectContainer &objects)
206{
207        std::stack<BspTraversalData> tStack;
208        Mesh polys;
209       
210        // copy mesh instance polygons into one big polygon soup
211        Copy2PolygonSoup(objects, polys);
212
213        BspTraversalData tdata(mRoot, mRoot->GetParent(), &polys, 0);
214        tStack.push(tdata);
215
216        while (!tStack.empty())
217        {
218            BspTraversalData data = tStack.top();
219
220            tStack.pop();
221   
222                Mesh backPolys;
223                Mesh frontPolys;
224
225                BspNode *node = SubdivideNode(dynamic_cast<BspLeaf *>(data.mNode),
226                                                                          data.mParent,
227                                                                          data.mPolys,
228                                                                      data.mDepth,
229                                                                          backPolys,
230                                                                          frontPolys);
231       
232                if (!node->IsLeaf()) // node was subdivided
233                {
234                        BspInterior *interior = dynamic_cast<BspInterior *>(node);
235
236                        // push the children on the stack (there are always two children)
237                        tStack.push(BspTraversalData(interior->GetBack(), interior, &backPolys, data.mDepth + 1));
238                        tStack.push(BspTraversalData(interior->GetFront(), interior, &frontPolys, data.mDepth + 1));
239                }
240        }
241}
242
243Plane3 BspTree::SelectPlane(Mesh *polys)
244{
245        // TODO: more sophisticated criteria
246        return polys->GetFacePlane(0);
247}
248
249BspNode *BspTree::SubdivideNode(BspLeaf *leaf, BspInterior *parent,
250                                                                Mesh *polys, const int depth,
251                                                                Mesh &frontPolys, Mesh &backPolys)
252{
253        // terminate traversal if no more faces in mesh
254        if ((polys->mFaces.size() <= mMaxPolys) || (depth >= mMaxDepth))
255        {
256                // don't need to store polygon information
257                polys->mFaces->clear(); // HACK: faces were deleted before
258                DEL_PTR(polys); // we can savely delete mesh
259
260                return leaf;
261        }
262
263        // add the new nodes to the tree + select subdivision plane
264        BspInterior *node = new BspInterior(SelectPlane(polys));
265
266        FaceContainer::const_iterator fi;
267
268        for (fi = polys->mFaces.begin(); fi != polys->mFaces.end(); ++ fi)
269        {
270                Face *face = (*fi);
271
272                int  result = 0;// = node->GetPlane()->Side(node->GetPlane());
273
274                Face *front_piece, *back_piece;
275
276                switch (result)
277                {
278                        case 1:
279                                frontPolys.AddFace(face);
280                                break;
281                        case -1:
282                                backPolys.AddFace(face);
283                                break;
284                        case 0:
285                                //Split_Polygon (face, tree->partition, front_piece, back_piece);
286                                backPolys.AddFace(back_piece);
287                                frontPolys.AddFace(front_piece);
288
289                                // face not needed anymore
290                                DEL_PTR(face);
291
292                                break;
293                        default:
294                                break;
295                }
296        }
297
298        // backside of convex view cell polygon => outside
299        BspLeaf *back = new BspLeaf();
300        BspLeaf *front = new BspLeaf();
301
302        // replace a link from node's parent
303        if (parent)
304        {
305                parent->ReplaceChildLink(leaf, node);
306        }
307
308        // and setup child links
309        node->SetupChildLinks(back, front);
310
311        // don't need to store polygon information
312        polys->mFaces->clear(); // HACK: faces were deleted before
313        DEL_PTR(polys); // we can savely delete mesh
314
315        DEL_PTR(leaf);
316
317        return node;
318}
319
320//} // GtpVisibilityPreprocessor
Note: See TracBrowser for help on using the repository browser.