1 | #include "Plane3.h" |
---|
2 | #include "ViewCellBsp.h" |
---|
3 | #include "Mesh.h" |
---|
4 | |
---|
5 | #include "ViewCell.h" |
---|
6 | #include <stack> |
---|
7 | |
---|
8 | //namespace GtpVisibilityPreprocessor { |
---|
9 | /****************************************************************/ |
---|
10 | /* class BspNode implementation */ |
---|
11 | /****************************************************************/ |
---|
12 | bool BspNode::IsRoot() const |
---|
13 | { |
---|
14 | return mParent == NULL; |
---|
15 | } |
---|
16 | |
---|
17 | /****************************************************************/ |
---|
18 | /* class BspInterior implementation */ |
---|
19 | /****************************************************************/ |
---|
20 | |
---|
21 | |
---|
22 | BspInterior::BspInterior(Plane3 plane): mPlane(plane) |
---|
23 | {} |
---|
24 | |
---|
25 | bool BspInterior::IsLeaf() const |
---|
26 | { |
---|
27 | return false; |
---|
28 | } |
---|
29 | |
---|
30 | BspNode *BspInterior::GetBack() |
---|
31 | { |
---|
32 | return mBack; |
---|
33 | } |
---|
34 | |
---|
35 | BspNode *BspInterior::GetFront() |
---|
36 | { |
---|
37 | return mFront; |
---|
38 | } |
---|
39 | |
---|
40 | Plane3 *BspInterior::GetPlane() |
---|
41 | { |
---|
42 | return &mPlane; |
---|
43 | } |
---|
44 | |
---|
45 | void BspInterior::ReplaceChildLink(BspNode *oldChild, BspNode *newChild) |
---|
46 | { |
---|
47 | if (mBack == oldChild) |
---|
48 | { |
---|
49 | mBack = newChild; |
---|
50 | } |
---|
51 | else |
---|
52 | { |
---|
53 | mFront = newChild; |
---|
54 | } |
---|
55 | }
|
---|
56 |
|
---|
57 | void BspInterior::SetupChildLinks(BspNode *b, BspNode *f)
|
---|
58 | {
|
---|
59 | mBack = b;
|
---|
60 | mFront = f;
|
---|
61 | }
|
---|
62 | |
---|
63 | |
---|
64 | /****************************************************************/ |
---|
65 | /* class BspLeaf implementation */ |
---|
66 | /****************************************************************/ |
---|
67 | |
---|
68 | BspLeaf::BspLeaf(ViewCell *viewCell): mViewCell(viewCell) |
---|
69 | { |
---|
70 | } |
---|
71 | |
---|
72 | ViewCell *BspLeaf::GetViewCell() |
---|
73 | { |
---|
74 | return mViewCell; |
---|
75 | } |
---|
76 | |
---|
77 | bool BspLeaf::IsLeaf() const |
---|
78 | { |
---|
79 | return true; |
---|
80 | } |
---|
81 | |
---|
82 | /****************************************************************/ |
---|
83 | /* class BspTree implementation */ |
---|
84 | /****************************************************************/ |
---|
85 | |
---|
86 | BspTree::BspTree(ViewCell *cell) |
---|
87 | { |
---|
88 | mRootCell = cell; |
---|
89 | mRoot = new BspLeaf(mRootCell); |
---|
90 | } |
---|
91 |
|
---|
92 |
|
---|
93 | void BspTree::Subdivide() |
---|
94 | {
|
---|
95 | BspNode *currentNode = mRoot;
|
---|
96 |
|
---|
97 | std::stack<BspTraversalData> tStack;
|
---|
98 | // stack<STraversalData> tStack;
|
---|
99 |
|
---|
100 | //tStack.push(tdata);
|
---|
101 |
|
---|
102 | while (!tStack.empty())
|
---|
103 | {
|
---|
104 | BspTraversalData data = tStack.top();
|
---|
105 | tStack.pop();
|
---|
106 |
|
---|
107 | Mesh backPolys;
|
---|
108 | Mesh frontPolys;
|
---|
109 |
|
---|
110 | if (data.mNode->IsLeaf()) // if we have a leaf => subdivide
|
---|
111 | {
|
---|
112 | BspNode *node = SubdivideNode(dynamic_cast<BspLeaf *>(data.mNode),
|
---|
113 | data.mParent,
|
---|
114 | &data.mViewCell,
|
---|
115 | data.mDepth,
|
---|
116 | backPolys,
|
---|
117 | frontPolys);
|
---|
118 |
|
---|
119 | if (!node->IsLeaf()) // node was subdivided
|
---|
120 | {
|
---|
121 | BspInterior *interior = dynamic_cast<BspInterior *>(node);
|
---|
122 |
|
---|
123 | // push the children on the stack (there are always two children)
|
---|
124 | tStack.push(BspTraversalData(interior->GetBack(), interior, backPolys, data.mDepth + 1));
|
---|
125 | tStack.push(BspTraversalData(interior->GetFront(), interior, frontPolys, data.mDepth + 1));
|
---|
126 | }
|
---|
127 | }
|
---|
128 | } |
---|
129 | } |
---|
130 | |
---|
131 | Plane3 BspTree::SelectPlane(Mesh *polys) |
---|
132 | { |
---|
133 | // TODO: more sophisticated criteria |
---|
134 | return polys->GetFacePlane(0); |
---|
135 | } |
---|
136 | |
---|
137 | BspNode *BspTree::SubdivideNode(BspLeaf *leaf, BspInterior *parent,
|
---|
138 | Mesh *viewCell, const int depth,
|
---|
139 | Mesh &frontPolys, Mesh &backPolys)
|
---|
140 | {
|
---|
141 | ViewCell *viewCell = leaf->GetViewCell();
|
---|
142 |
|
---|
143 | // terminate traversal if no more faces in mesh or outside
|
---|
144 | if (!viewCell || (viewCell->mFaces.size() == 0))
|
---|
145 | {
|
---|
146 | return leaf;
|
---|
147 | }
|
---|
148 | // add the new nodes to the tree + select subdivision plane
|
---|
149 | BspInterior *node = new BspInterior(SelectPlane(viewCell));
|
---|
150 |
|
---|
151 | FaceContainer::const_iterator fi;
|
---|
152 |
|
---|
153 | for (fi = viewCell->mFaces.begin(); fi != viewCell->mFaces.end(); ++ fi)
|
---|
154 | {
|
---|
155 | int result = node->GetPlane()->Side();
|
---|
156 | Mesh *front_piece, *back_piece;
|
---|
157 |
|
---|
158 | switch (result)
|
---|
159 | {
|
---|
160 | case 1:
|
---|
161 | frontPolys.AddFace(poly);
|
---|
162 | break;
|
---|
163 | case -1:
|
---|
164 | backPolys.AddFace(poly);
|
---|
165 | break;
|
---|
166 | case 0:
|
---|
167 | //Split_Polygon (poly, tree->partition, front_piece, back_piece);
|
---|
168 | backPolys.AddFace(back_piece);
|
---|
169 | frontPolys.AddFace(front_piece);
|
---|
170 | break;
|
---|
171 | default;
|
---|
172 | brak;
|
---|
173 | }
|
---|
174 | }
|
---|
175 | // backside of convex view cell polygon => outside
|
---|
176 | BspLeaf *back = new BspLeaf(NULL);
|
---|
177 | BspLeaf *front = new BspLeaf(viewCell);
|
---|
178 |
|
---|
179 | // replace a link from node's parent
|
---|
180 | if (parent)
|
---|
181 | {
|
---|
182 | parent->ReplaceChildLink(leaf, node);
|
---|
183 | }
|
---|
184 |
|
---|
185 | // and setup child links
|
---|
186 | node->SetupChildLinks(back, front);
|
---|
187 |
|
---|
188 | delete leaf;
|
---|
189 | return node;
|
---|
190 | }
|
---|
191 | |
---|
192 | //} // GtpVisibilityPreprocessor |
---|