Advertisement
KeinMitleid

VMF Planes to Mesh

Jul 2nd, 2013
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.93 KB | None | 0 0
  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>
  136. #include <armadillo>
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement