# VMF Planes to Mesh

Jul 2nd, 2013
139
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. // ===========
2. // objects.h
3. // ===========
4.
5. // Vector and Plane may not even be necessary anymore since I'm
6. // using Armadillo libraries. I may get rid of all these classes later.
7.
8. #ifndef OBJECTS_H_INCLUDED
9. #define OBJECTS_H_INCLUDED
10.
11. #include <iostream>
12. using namespace std;
13.
14. class Vector
15. {
16. public:
17.     float x, y, z, d;
18.     Vector (const float& = 0, const float& = 0, const float& = 0);
19.     bool operator == (const Vector&);
20.     Vector operator + (const Vector&);
21.     Vector operator - (const Vector&);
22.     Vector operator * (const float&);
23.     Vector operator / (const float&);
24.     Vector operator ^ (const Vector&);
25.     float operator * (const Vector&);
26. };
27.
28. class Plane
29. {
30. public:
31.     Vector a, b, c, n;
32.     Plane (const Vector&, const Vector&, const Vector&);
33.
34. private:
35.     void getNormal ();
36. };
37.
38. ostream& operator << (ostream&, const Vector&);
39. bool operator < (const Vector&, const Vector&);
40. Vector norm (Vector&);
41.
42. #endif // OBJECTS_H_INCLUDED
43.
44.
45.
46.
47.
48. // =============
49. // objects.cpp
50. // =============
51.
52. #include <cmath>
53. #include "objects.h"
54. using namespace std;
55.
56. // With a Vector type, you can initialize, compare, add and subtract
57. // other Vectors, multiply and divide by scalars, do a cross product (^)
58. // and dot product (*) between two Vectors, normalize a Vector, and
59. // print out a Vector directly to the console.
60.
61. Vector::Vector (const float& a, const float& b, const float& c) {
62.     x = a; y = b; z = c; }
63.
64. bool Vector::operator == (const Vector& param) {
65.     return (x == param.x) && (y == param.y) && (z == param.z); }
66.
67. ostream& operator << (ostream& out, const Vector& param) {
68.     return out << "(" << param.x << ", " << param.y << ", " << param.z << ")"; }
69.
70. Vector Vector::operator + (const Vector& param) {
71.     return Vector (x + param.x, y + param.y, z + param.z); }
72.
73. Vector Vector::operator - (const Vector& param) {
74.     return Vector (x - param.x, y - param.y, z - param.z); }
75.
76. Vector Vector::operator * (const float& param) {
77.     return Vector (x * param, y * param, z * param); }
78.
79. Vector Vector::operator / (const float& param) {
80.     return Vector (x / param, y / param, z / param); }
81.
82. float Vector::operator * (const Vector& param) {
83.     return (x * param.x) + (y * param.y) + (z * param.z); }
84.
85. Vector Vector::operator ^ (const Vector& param)
86. {
87.     Vector temp;
88.     temp.x = (y * param.z) - (z * param.y);
89.     temp.y = (z * param.x) - (x * param.z);
90.     temp.z = (x * param.y) - (y * param.x);
91.     return temp;
92. }
93.
94. bool operator < (const Vector& a, const Vector& b)
95. {
96.     if (a.x != b.x) return (a.x < b.x);
97.     else if (a.y != b.y) return (a.y < b.y);
98.     else return (a.z < b.z);
99. }
100.
101. Vector norm (Vector& param) {
102.     return param / sqrt (param * param); }
103.
104. // A Plane type holds the Vectors of three points that make up
105. // the Plane. It then calculates its normal and assigns that to d.
106.
107. Plane::Plane (const Vector& d, const Vector& e, const Vector& f)
108. {
109.     a = d; b = e; c = f;
110.     getNormal ();
111. }
112.
113. void Plane::getNormal ()
114. {
115.     Vector temp (
116.     Vector (b.x - a.x, b.y - a.y, b.z - a.z) ^
117.     Vector (c.x - b.x, c.y - b.y, c.z - b.z));
118.
119.     n = norm (temp);
120.     n.d = n * a;
121. }
122.
123.
124.
125.
126.
127. // ==========
128. // main.cpp
129. // ==========
130.
131. // Using the Armadillo library.
132. // http://arma.sourceforge.net/
133.
134. #include <map>
135. #include <set>
137. #include "objects.h"
138.
139. #define SMALL_NUM 0.0001
140.
141. using namespace std;
142. using namespace arma;
143.
144. // Get the intersection point of three planes if there is one.
145. // http://www.gamedev.net/topic/304411-three-plane-intersection-point/
146.
147. void plane3Int (const Vector& i, const Vector& j, const Vector& k, mat& result, bool& success)
148. {
149.     success = false;
150.     static mat abc(3, 3);
151.     static vec d(3);
152.
153.     abc(0, 0) = i.x; abc(0, 1) = i.y; abc(0, 2) = i.z;
154.     abc(1, 0) = j.x; abc(1, 1) = j.y; abc(1, 2) = j.z;
155.     abc(2, 0) = k.x; abc(2, 1) = k.y; abc(2, 2) = k.z;
156.     d[0] = i.d; d[1] = j.d; d[2] = k.d;
157.
158.     if (det(abc) != 0) { success = true; result = solve(abc, d); }
159. }
160.
161. int main()
162. {
163.     size_t planeSize = sizeof(plane) / sizeof(plane[0]);
164.     map<int, vector<Vector>> face;
165.
166.     for (int i = 0; i < planeSize; ++i) {
167.         for (int j = i + 1; j < planeSize; ++j) {
168.             for (int k = j + 1; k < planeSize; ++k)
169.             {
170.                 // If all three planes are parallel, move to next plane.
171.                 // This also prevents use from running unnecessary matrix operations.
172.                 // I may need to add more optimizing comparisons, either within K or J.
173.
174.                 if (fabs(plane[i].n * (plane[j].n ^ plane[k].n)) <= SMALL_NUM) continue;
175.
176.                 // Find the intersection of planes I, J, and K.
177.                 // http://www.gamedev.net/topic/304411-three-plane-intersection-point/
178.
179.                 bool success;
180.                 static vec temp(3);
181.
182.                 plane3Int(plane[i].n, plane[j].n, plane[k].n, temp, success);
183.                 if (!success) continue;
184.                 Vector result (temp(0), temp(1), temp(2));
185.
186.                 // Figure out if each vertex is part of the solid. Run a line from
187.                 // plane I to our vertex. If there is an intersection, discard the vertex.
188.                 // Algorithm for plane/line segment intersection from
189.                 // http://math.stackexchange.com/questions/47594/plane-intersecting-line-segment
190.
191.                 for (int l = 0; l < planeSize; ++l)
192.                 {
193.                     success = true;
194.                     if (l == i || l == j || l == k) continue;
195.
196.                     Vector midpoint = (((plane[i].a + plane[i].b) / 2) + plane[i].c) / 2;
197.                     float distV1 = plane[l].n * (midpoint - plane[l].b);
198.                     float distV2 = plane[l].n * (result - plane[l].b);
199.
200.                     if (distV1 * distV2 <= -SMALL_NUM) { success = false; break; }
201.                 }
202.
203.                 // If our vertex is not discarded, we put it in faces I, J, and K.
204.
205.                 if (success)
206.                 {
207.                     face[i].push_back(result);
208.                     face[j].push_back(result);
209.                     face[k].push_back(result);
210.                 }
211.             }
212.         }
213.     }
214.
215.     // Finally, we remove the duplicate points from each face. Thanks Jag!
216.     // Source: http://stackoverflow.com/questions/12200486/
217.
218.     for (auto& vertices : face)
219.     {
220.         set<Vector> verticesCopy(vertices.second.begin(), vertices.second.end());
221.         vertices.second.assign(verticesCopy.begin(), verticesCopy.end());
222.     }
223.
224.     return 0;
225. }