KeinMitleid

Auxillary VMF Map Editor

Jul 4th, 2013
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.79 KB | None | 0 0
  1. // ==========
  2. // object.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. // vmfdata.h
  129. // ===========
  130.  
  131. #ifndef DATA_H_INCLUDED
  132. #define DATA_H_INCLUDED
  133.  
  134. #include <map>
  135. #include <tuple>
  136. #include <string>
  137. #include <vector>
  138. #include "objects.h"
  139.  
  140. using namespace std;
  141.  
  142. // This block holds reused sections of the VMF structure.
  143. // They will be part of what's below this block.
  144.  
  145. struct Editor
  146. {
  147.     Vector color;
  148.     int visgroupid;
  149.     int group;
  150.     bool visgroupshown;
  151.     bool visgroupautoshown;
  152.     string comments;
  153. };
  154.  
  155. struct Solid
  156. {
  157.     struct Side
  158.     {
  159.         Vector plane[3];
  160.         string material;
  161.         Vector uaxis[2];
  162.         Vector vaxis[2];
  163.         float rotation;
  164.         int lightmapscale;
  165.         int smoothing_groups;
  166.  
  167.         struct Dispinfo
  168.         {
  169.             int power;
  170.             Vector startposition;
  171.             float elevation;
  172.             bool subdiv;
  173.             vector<vector<Vector>> normals;
  174.             vector<vector<float>> distances;
  175.             vector<vector<Vector>> offsets;
  176.             vector<vector<Vector>> offset_normals;
  177.             vector<vector<float>> alphas;
  178.             vector<vector<int>> triangle_tags;
  179.             vector<vector<int>> allowed_verts;
  180.         }
  181.         dispinfo;
  182.     };
  183.     map<int, Side> side;
  184.  
  185.     Editor editor;
  186. };
  187.  
  188. struct Hidden
  189. {
  190.     map<int, Solid> solid;
  191. };
  192.  
  193. // A struct that holds the VMF file.
  194. // https://developer.valvesoftware.com/wiki/VMF_documentation
  195.  
  196. struct Data
  197. {
  198.     struct Versioninfo
  199.     {
  200.         int editorversion;
  201.         int editorbuild;
  202.         int mapversion;
  203.         int formatversion;
  204.         bool prefab;
  205.     }
  206.     versioninfo;
  207.  
  208.     struct Visgroups
  209.     {
  210.         int visgroupid;
  211.         Vector rgb;
  212.         map<string, Visgroups> branch;
  213.     };
  214.     map<string, Visgroups> visgroups;
  215.  
  216.     struct Viewsettings
  217.     {
  218.         bool bSnapToGrid;
  219.         bool bShowGrid;
  220.         bool bShowLogicalGrid;
  221.         int nGridSpacing;
  222.         bool bShow3DGrid;
  223.     }
  224.     viewsettings;
  225.  
  226.     struct World
  227.     {
  228.         string mapversion;
  229.         string classname;
  230.         string skyname;
  231.         Hidden hidden;
  232.         map<int, Solid> solid;
  233.  
  234.         struct Group
  235.         {
  236.             Editor editor;
  237.         };
  238.         map<int, Group> group;
  239.     };
  240.     map<int, World> world;
  241.  
  242.     struct Entity
  243.     {
  244.         string classname;
  245.         int spawnflags;
  246.         Vector origin;
  247.         Solid solid;
  248.         Editor editor;
  249.         Hidden hidden;
  250.         map<string, string> properties;
  251.  
  252.         struct Connections
  253.         {
  254.             map<string, tuple<string, string, string, float, bool>> output;
  255.         }
  256.         connections;
  257.     };
  258.     map<int, Entity> entity;
  259.  
  260.     struct Cameras
  261.     {
  262.         int activecamera;
  263.  
  264.         struct Camera
  265.         {
  266.             Vector position;
  267.             Vector look;
  268.         };
  269.         vector<Camera> camera;
  270.     }
  271.     cameras;
  272.  
  273.     struct Cordon
  274.     {
  275.         Vector mins;
  276.         Vector maxs;
  277.         bool active;
  278.     }
  279.     cordon;
  280. };
  281.  
  282. #endif // DATA_H_INCLUDED
  283.  
  284.  
  285.  
  286.  
  287.  
  288. // =======
  289. // vmf.h
  290. // =======
  291.  
  292. #ifndef VMFREAD_H_INCLUDED
  293. #define VMFREAD_H_INCLUDED
  294.  
  295. #include <fstream>
  296. #include "vmfdata.h"
  297. using namespace std;
  298.  
  299. #define FILE_IS_OPEN   0
  300. #define FILE_NOT_OPEN  1
  301. #define FILE_NOT_VALID 2
  302.  
  303. class VMF
  304. {
  305. public:
  306.     Data data;
  307.     int open (const string&);
  308.     void close ();
  309.     void read ();
  310.  
  311. private:
  312.     fstream file;
  313.     string tokenize ();
  314. };
  315.  
  316. #endif // VMFREAD_H_INCLUDED
  317.  
  318.  
  319.  
  320.  
  321.  
  322. // =========
  323. // vmf.cpp
  324. // =========
  325.  
  326. #include "vmf.h"
  327. using namespace std;
  328.  
  329. void VMF::close () {
  330.     file.close (); }
  331.  
  332. int VMF::open (const string& filename)
  333. {
  334.     file.open (filename, fstream::in | fstream::out);
  335.     if (!file.is_open()) return FILE_NOT_OPEN;
  336.     else if (filename.find(".vmf") == string::npos) return FILE_NOT_VALID;
  337.     else return FILE_IS_OPEN;
  338. }
  339.  
  340. string VMF::tokenize ()
  341. {
  342.     bool withinQuotes = false;
  343.     string token;
  344.     while (true)
  345.     {
  346.         char ch = file.get ();
  347.         if (file.eof ()) return token;
  348.         else if (withinQuotes == true && ch == '\"') return token;
  349.         else if (withinQuotes == false)
  350.         {
  351.             if (token.length() == 0 && ch == '\"') { withinQuotes = true; continue; }
  352.             if (ch == ' ' || ch == '\n' || ch == '\n' || ch == '\t') return token;
  353.             if (token.length() == 0 && ch == '{' || ch == '}') { token = ch; return token; }
  354.             if (ch == '{' || ch == '}') { file.unget(); return token; }
  355.         }
  356.         token.push_back(ch);
  357.     }
  358. }
  359.  
  360. void VMF::read ()
  361. {
  362.     while (!file.eof ())
  363.     {
  364.         string token;
  365.         token = tokenize ();
  366.         if (token != "") cout << token << endl;
  367.     }
  368. }
  369.  
  370.  
  371.  
  372.  
  373.  
  374. // ===============
  375. // planeconv.cpp
  376. // ===============
  377.  
  378. // Using the Armadillo library.
  379. // http://arma.sourceforge.net/
  380.  
  381. #include <set>
  382. #include <armadillo>
  383. #include "vmf.h"
  384. #include "objects.h"
  385.  
  386. #define SMALL_NUM 0.0001
  387.  
  388. using namespace std;
  389. using namespace arma;
  390.  
  391. // Uncomment this code if you want to debug.
  392. // A set of planes used for debugging. They come from a VMF file.
  393.  
  394. // Plane plane[] =
  395. // {
  396. //  Plane ({384, 128, 384}, {384, -128, 384}, {0, 0, 256}),
  397. //  Plane ({384, -128, 128}, {384, 128, 128}, {0, 256, 0}),
  398. //  Plane ({0, 0, 256}, {0, 0, 0}, {0, 256, 0}),
  399. //  Plane ({384, -128, 128}, {384, -128, 384}, {384, 128, 384}),
  400. //  Plane ({0, 256, 256}, {0, 256, 0}, {384, 128, 128}),
  401. //  Plane ({0, 0, 0}, {0, 0, 256}, {384, -128, 384})
  402. // };
  403.  
  404. // Get the intersection point of three planes if there is one.
  405. // http://www.gamedev.net/topic/304411-three-plane-intersection-point/
  406.  
  407. void plane3Int (const Vector& i, const Vector& j, const Vector& k, mat& result, bool& success)
  408. {
  409.     success = false;
  410.     static mat abc(3, 3);
  411.     static vec d(3);
  412.  
  413.     abc(0, 0) = i.x; abc(0, 1) = i.y; abc(0, 2) = i.z;
  414.     abc(1, 0) = j.x; abc(1, 1) = j.y; abc(1, 2) = j.z;
  415.     abc(2, 0) = k.x; abc(2, 1) = k.y; abc(2, 2) = k.z;
  416.     d[0] = i.d; d[1] = j.d; d[2] = k.d;
  417.  
  418.     if (det(abc) != 0) { success = true; result = solve(abc, d); }
  419. }
  420.  
  421. int main()
  422. {
  423.     size_t planeSize = sizeof(plane) / sizeof(plane[0]);
  424.     map<int, vector<Vector>> face;
  425.  
  426.     // If you want to find the speed, uncomment the following line
  427.     // and its accompanying bracket at the bottom.
  428.  
  429.     // for (int run = 0; run < 10000; ++run) {
  430.  
  431.     for (int i = 0; i < planeSize; ++i) {
  432.         for (int j = i + 1; j < planeSize; ++j) {
  433.             for (int k = j + 1; k < planeSize; ++k)
  434.             {
  435.                 // If all three planes are parallel, move to next plane.
  436.                 // This also prevents use from running unnecessary  matrix operations.
  437.                 // I may need to add more comparisons for optimization, either within K or J.
  438.  
  439.                 if (fabs(plane[i].n * (plane[j].n ^ plane[k].n)) <= SMALL_NUM) continue;
  440.  
  441.                 // Find the intersection of planes I, J, and K.
  442.                 // http://www.gamedev.net/topic/304411-three-plane-intersection-point/
  443.  
  444.                 bool success;
  445.                 static vec temp(3);
  446.  
  447.                 plane3Int(plane[i].n, plane[j].n, plane[k].n, temp, success);
  448.                 if (!success) continue;
  449.                 Vector result (temp(0), temp(1), temp(2));
  450.  
  451.                 // Figure out if each vertex is part of the solid. Run a line from
  452.                 // plane I to our vertex. If there is an intersection, discard the vertex.
  453.                 // Algorithm for plane/line segment intersection from
  454.                 // http://math.stackexchange.com/questions/47594/plane-intersecting-line-segment
  455.  
  456.                 for (int l = 0; l < planeSize; ++l)
  457.                 {
  458.                     success = true;
  459.                     if (l == i || l == j || l == k) continue;
  460.  
  461.                     Vector midpoint = (((plane[i].a + plane[i].b) / 2) + plane[i].c) / 2;
  462.                     float distV1 = plane[l].n * (midpoint - plane[l].b);
  463.                     float distV2 = plane[l].n * (result - plane[l].b);
  464.  
  465.                     if (distV1 * distV2 <= -SMALL_NUM) { success = false; break; }
  466.                 }
  467.  
  468.                 // If our vertex is not discarded, we put it in faces I, J, and K.
  469.  
  470.                 if (success)
  471.                 {
  472.                     face[i].push_back(result);
  473.                     face[j].push_back(result);
  474.                     face[k].push_back(result);
  475.                 }
  476.             }
  477.         }
  478.     }
  479.  
  480.     // Finally, we remove the duplicate points from each face. Thanks Jag!
  481.     // Source: http://stackoverflow.com/questions/12200486/
  482.  
  483.     for (auto& vertices : face)
  484.     {
  485.         set<Vector> verticesCopy(vertices.second.begin(), vertices.second.end());
  486.         vertices.second.assign(verticesCopy.begin(), verticesCopy.end());
  487.  
  488.         // Uncomment this code to find out if right vertices are being found.
  489.  
  490.         // cout << "=== FACE " << vertices.first << " ===\n";
  491.         // for (auto& vertex: vertices.second) cout << vertex << endl;
  492.         // cout << endl;
  493.     }
  494.  
  495.     // }
  496.  
  497.     return 0;
  498. }
Advertisement
Add Comment
Please, Sign In to add comment