From c922ad48807364ec4bf7daafa25f6cd0c1471dc3 Mon Sep 17 00:00:00 2001 From: Terri00 Date: Sat, 23 Jun 2018 05:04:45 +0100 Subject: [PATCH] BSP/NAV viewer --- MCDV/Camera.hpp | 8 +- MCDV/MCDV.vcxproj | 9 ++ MCDV/MCDV.vcxproj.filters | 12 ++ MCDV/Mesh.hpp | 55 +++++++ MCDV/VectorOctTree.hpp | 175 +++++++++++++++++++++ MCDV/de_overpass.txt | 22 +++ MCDV/depth.fs | 10 +- MCDV/depth.vs | 8 +- MCDV/main.cpp | 305 ++++++++++++++++++++++++------------ MCDV/nav.hpp | 322 ++++++++++++++++++++++++++++++++++++++ MCDV/radar.hpp | 37 +++++ MCDV/shaders/depth.fs | 20 +++ MCDV/shaders/depth.vs | 27 ++++ MCDV/shaders/lit.fs | 43 +++++ MCDV/shaders/lit.vs | 18 +++ MCDV/shaders/unlit.fs | 9 ++ MCDV/shaders/unlit.vs | 13 ++ MCDV/util.h | 94 ++++++++++- MCDV/vbsp.hpp | 180 ++++++++++++++------- MCDV/vdf.hpp | 123 +++++++++++++++ 20 files changed, 1329 insertions(+), 161 deletions(-) create mode 100644 MCDV/VectorOctTree.hpp create mode 100644 MCDV/de_overpass.txt create mode 100644 MCDV/nav.hpp create mode 100644 MCDV/radar.hpp create mode 100644 MCDV/shaders/depth.fs create mode 100644 MCDV/shaders/depth.vs create mode 100644 MCDV/shaders/lit.fs create mode 100644 MCDV/shaders/lit.vs create mode 100644 MCDV/shaders/unlit.fs create mode 100644 MCDV/shaders/unlit.vs create mode 100644 MCDV/vdf.hpp diff --git a/MCDV/Camera.hpp b/MCDV/Camera.hpp index 9824e6d..340f4f7 100644 --- a/MCDV/Camera.hpp +++ b/MCDV/Camera.hpp @@ -27,8 +27,7 @@ private: //Used for true fps control glm::vec3 travelFront = glm::vec3(0.0f, 0.0f, 1.0f); - float yaw = 90.0f; - float pitch = 0.0f; + util_keyHandler* keyHandler; public: @@ -36,6 +35,9 @@ public: glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, -16.0f); + float yaw = 90.0f; + float pitch = 0.0f; + float sensitivity = 0.05f; float speed = 2.5f; float fov = 90.0f; @@ -184,11 +186,13 @@ void Camera::mouseUpdate(double xpos, double ypos, bool isClicking) glm::mat4 Camera::getViewMatrix() { + //return glm::lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 10) + glm::vec3(0, 0, -1), glm::vec3(1, 0, 0)); return glm::lookAt(this->cameraPos, this->cameraPos + this->cameraFront, this->cameraUp); } glm::mat4 Camera::getProjectionMatrix() { + //return glm::ortho(-20.0f, 20.0f, -20.0f, 20.0f, 0.1f, 100.0f); return glm::perspective(glm::radians(fov / 2), (float)window_width / (float)window_height, near_z, far_z); } diff --git a/MCDV/MCDV.vcxproj b/MCDV/MCDV.vcxproj index b478a06..a3e0ab5 100644 --- a/MCDV/MCDV.vcxproj +++ b/MCDV/MCDV.vcxproj @@ -73,6 +73,10 @@ $(ProjectDir)../deps/inc;$(IncludePath) $(ProjectDir)../deps/lib;$(LibraryPath) + + $(ProjectDir)../deps/inc;$(IncludePath) + $(ProjectDir)../deps/lib;$(LibraryPath) + Level3 @@ -101,6 +105,7 @@ true true + glfw3.lib;opengl32.lib;%(AdditionalDependencies) @@ -125,12 +130,16 @@ + + + + diff --git a/MCDV/MCDV.vcxproj.filters b/MCDV/MCDV.vcxproj.filters index 8bfcbaa..fee4f54 100644 --- a/MCDV/MCDV.vcxproj.filters +++ b/MCDV/MCDV.vcxproj.filters @@ -80,6 +80,18 @@ OpenGL\engine + + Header Files\valve + + + OpenGL\engine + + + Header Files\valve + + + Header Files\valve + diff --git a/MCDV/Mesh.hpp b/MCDV/Mesh.hpp index 6bd4ca1..9c0ad9b 100644 --- a/MCDV/Mesh.hpp +++ b/MCDV/Mesh.hpp @@ -58,6 +58,61 @@ public: std::cout << "DESTRUCTED" << std::endl; } + void Draw() { + glBindVertexArray(this->VAO); + glDrawArrays(GL_TRIANGLES, 0, this->elementCount); + } +}; + +class VertAlphaMesh { + int elementCount; + +public: + unsigned int VBO, VAO; + + std::vector vertices; + + VertAlphaMesh() { + glGenVertexArrays(1, &this->VAO); + glBindBuffer(GL_ARRAY_BUFFER, this->VBO); + } + + VertAlphaMesh(std::vector vertices) { + if (vertices.size() <= 0) + return; + + this->vertices = vertices; + this->elementCount = vertices.size() / 7; + + // first, configure the cube's VAO (and VBO) + glGenVertexArrays(1, &this->VAO); + glGenBuffers(1, &this->VBO); + + glBindBuffer(GL_ARRAY_BUFFER, this->VBO); + glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW); + + glBindVertexArray(this->VAO); + + // position attribute + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + + //Normal vector + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(3 * sizeof(float))); + glEnableVertexAttribArray(1); + + //alpha + glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(6 * sizeof(float))); + glEnableVertexAttribArray(2); + } + + ~VertAlphaMesh() { + glDeleteVertexArrays(1, &this->VAO); + glDeleteBuffers(1, &this->VBO); + + std::cout << "DESTRUCTED" << std::endl; + } + void Draw() { glBindVertexArray(this->VAO); glDrawArrays(GL_TRIANGLES, 0, this->elementCount); diff --git a/MCDV/VectorOctTree.hpp b/MCDV/VectorOctTree.hpp new file mode 100644 index 0000000..6ab29f0 --- /dev/null +++ b/MCDV/VectorOctTree.hpp @@ -0,0 +1,175 @@ +#pragma once +#include +#include +#include +#include + +#include +#include +#include + +#define _HAS_ITERATOR_DEBUGGING = 0 +#define _SCL_SECURE = 0 + +namespace octree{ + class Node { + public: + Node* subnodes = NULL; + std::vector points = std::vector(); + int resolution = 0; + + glm::vec3 mins = glm::vec3(0,0,0); + glm::vec3 maxes = glm::vec3(0, 0, 0); + glm::vec3 midpoint = glm::vec3(0, 0, 0); + + Node() {} + + Node(int resolution, glm::vec3 mins, glm::vec3 maxes) { + //std::cout << "Octree level {" << resolution << "}" << std::endl; + + this->resolution = resolution; + + if (resolution > 0) { + this->subnodes = new Node[8]; //Generate subnodes + + //calculate sub distances + glm::vec3 subdist = (maxes - mins) * 0.5f; + subdist = glm::abs(subdist); //Make sure its positive + + //Calculate midpoint + glm::vec3 _midpoint = (mins + maxes) * 0.5f; + + this->midpoint = _midpoint; + + this->subnodes[0] = Node(resolution - 1, _midpoint + glm::vec3(-subdist.x, -subdist.y, -subdist.z), _midpoint); + this->subnodes[1] = Node(resolution - 1, _midpoint + glm::vec3(subdist.x, -subdist.y, -subdist.z), _midpoint); + this->subnodes[2] = Node(resolution - 1, _midpoint + glm::vec3(-subdist.x, subdist.y, -subdist.z), _midpoint); + this->subnodes[3] = Node(resolution - 1, _midpoint + glm::vec3(subdist.x, subdist.y, -subdist.z), _midpoint); + + this->subnodes[4] = Node(resolution - 1, _midpoint + glm::vec3(-subdist.x, -subdist.y, subdist.z), _midpoint); + this->subnodes[5] = Node(resolution - 1, _midpoint + glm::vec3(subdist.x, -subdist.y, subdist.z), _midpoint); + this->subnodes[6] = Node(resolution - 1, _midpoint + glm::vec3(-subdist.x, subdist.y, subdist.z), _midpoint); + this->subnodes[7] = Node(resolution - 1, _midpoint + glm::vec3(subdist.x, subdist.y, subdist.z), _midpoint); + } + } + + void insert(glm::vec3* v) { + if (this->resolution > 0) { + //Decide what oct to push into + int index = 0; + + //Index into upper quadrents if above midpoint + if (v->z > this->midpoint.z) + index += 4; + + //Index into upper(y) halfs + if (v->y > this->midpoint.y) + index += 2; + + //Index into remaining two + if (v->x > this->midpoint.x) + index += 1; + + //Dive into the next node + this->subnodes[index].insert(v); + return; //We are done in this node + } + else { //We are as low as resolution goes + this->points.push_back(v); + } + } + + Node* getNodeByVec(glm::vec3 v) { + if (this->resolution > 0) { + //Decide what oct to push into + int index = 0; + + //Index into upper quadrents if above midpoint + if (v.z > this->midpoint.z) + index += 4; + + //Index into upper(y) halfs + if (v.y > this->midpoint.y) + index += 2; + + //Index into remaining two + if (v.x > this->midpoint.x) + index += 1; + + //If the next node we try has no values + if(this->subnodes[index].getEntryCount() == 0) + return this; + + //Dive into the next node + return this->subnodes[index].getNodeByVec(v); + } + + //Lowest point + return this; + } + + int getEntryCount(int c = 0) { + if (this->resolution > 0) { + int temp = 0; + for (int i = 0; i < 8; i++) { + temp += this->subnodes[i].getEntryCount(); + } + c += temp; + return c; + } + + return this->points.size(); + } + + std::vector getContainedValues(std::vector vals = std::vector()) { + if (this->resolution > 0) { + for (int i = 0; i < 8; i++) { + std::vector temp = this->subnodes[i].getContainedValues(vals); + for (int x = 0; x < temp.size(); x++) { + vals.push_back(temp[x]); + } + } + return vals; + } + + return this->points; + } + }; + + class Tree { + public: + Node head; + glm::vec3 mins = glm::vec3(0, 0, 0); + glm::vec3 maxes = glm::vec3(0, 0, 0); + + Tree(std::vector data, int resolution) { + //Find master mins and maxes + for (int i = 0; i < data.size(); i++) { + glm::vec3 v0 = data[i]; + if (v0.x < mins.x) + mins.x = v0.x; + if (v0.y < mins.y) + mins.y = v0.y; + if (v0.z < mins.z) + mins.z = v0.z; + + if (v0.x > maxes.x) + maxes.x = v0.x; + if (v0.y > maxes.y) + maxes.y = v0.y; + if (v0.z > maxes.z) + maxes.z = v0.z; + } + + //Generate node structure + this->head = Node(resolution, mins, maxes); + std::cout << "Octree prepared" << std::endl; + + for (int i = 0; i < data.size(); i++) { + head.insert(&data[i]); + } + + std::cout << "Data inserted into tree" << std::endl; + } + }; +} \ No newline at end of file diff --git a/MCDV/de_overpass.txt b/MCDV/de_overpass.txt new file mode 100644 index 0000000..3b169b1 --- /dev/null +++ b/MCDV/de_overpass.txt @@ -0,0 +1,22 @@ +// HLTV overview description file for de_overpass.bsp + +"de_overpass" +{ + "material" "overviews/de_overpass" // texture file + "pos_x" "-4831" // upper left world coordinate + "pos_y" "1781" + "scale" "5.2" + "rotate" "0" + "zoom" "0" + + // loading screen icons and positions + "CTSpawn_x" "0.49" + "CTSpawn_y" "0.2" + "TSpawn_x" "0.66" + "TSpawn_y" "0.93" + + "bombA_x" "0.55" + "bombA_y" "0.23" + "bombB_x" "0.7" + "bombB_y" "0.31" +} \ No newline at end of file diff --git a/MCDV/depth.fs b/MCDV/depth.fs index 6fa5475..c3c8d5f 100644 --- a/MCDV/depth.fs +++ b/MCDV/depth.fs @@ -2,11 +2,19 @@ out vec4 FragColor; uniform vec3 color; +uniform float test; + +uniform float HEIGHT_MIN; +uniform float HEIGHT_MAX; in vec3 FragPos; in float Depth; +in float Alpha; + void main() { - FragColor = vec4(Depth, Depth, Depth, 1.0); + float height = (Depth - HEIGHT_MIN) / HEIGHT_MAX; + + FragColor = vec4(height, height, height, Alpha); } \ No newline at end of file diff --git a/MCDV/depth.vs b/MCDV/depth.vs index baa0d98..74322c9 100644 --- a/MCDV/depth.vs +++ b/MCDV/depth.vs @@ -1,15 +1,19 @@ #version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aNormal; +layout (location = 2) in float alpha; out vec3 FragPos; out vec3 Normal; out float Depth; +out float Alpha; uniform mat4 model; uniform mat4 view; uniform mat4 projection; + + void main() { FragPos = vec3(model * vec4(aPos, 1.0)); @@ -17,5 +21,7 @@ void main() gl_Position = projection * view * model * vec4(aPos, 1.0); //Depth = gl_Position.z / 100.0; - Depth = FragPos.y / 10.0; + + Depth = FragPos.y; + Alpha = alpha; } \ No newline at end of file diff --git a/MCDV/main.cpp b/MCDV/main.cpp index 2501edc..dd519a3 100644 --- a/MCDV/main.cpp +++ b/MCDV/main.cpp @@ -10,6 +10,9 @@ #include "GLFWUtil.hpp" #include "vbsp.hpp" +#include "nav.hpp" +#include "radar.hpp" +#include "util.h" #include "Shader.hpp" #include "Texture.hpp" @@ -27,8 +30,8 @@ void mouse_callback(GLFWwindow* window, double xpos, double ypos); void mouse_button_callback(GLFWwindow* window, int button, int action, int mods); void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); -int window_width = 800; -int window_height = 600; +int window_width = 1024; +int window_height = 1024; float deltaTime = 0.0f; float lastFrame = 0.0f; @@ -40,11 +43,85 @@ double mousey; Camera camera; -int main() { +int SV_WIREFRAME = 0; //0: off 1: overlay 2: only +int SV_RENDERMODE = 0; +int SV_PERSPECTIVE = 0; + +float M_HEIGHT_MIN = 0.0f; +float M_HEIGHT_MAX = 10.0f; + +float M_CLIP_NEAR = 0.1f; +float M_CLIP_FAR = 100.0f; + +bool SV_DRAW_BSP = true; +bool SV_DRAW_NAV = false; + +Radar* _radar; + +float M_ORTHO_SIZE = 20.0f; + +int main(int argc, char* argv[]) { + std::string _FILE_BSP = ""; + std::string _FILE_NAV = ""; + + for (int i = 1; i < argc; ++i) { + char* _arg = argv[i]; + std::string arg = _arg; + + if (split(arg, '.').back() == "bsp") { + _FILE_BSP = arg; + } + + if (split(arg, '.').back() == "nav") { + _FILE_NAV = arg; + } + } + + /* + std::vector data = { + glm::vec3(0,0,-5), + glm::vec3(0,0,-4.5), + glm::vec3(10,-2,0), + glm::vec3(-3,5,0), + glm::vec3(0,2,-9), + glm::vec3(3,-5,0), + glm::vec3(-2,0,4), + glm::vec3(1,4,5), + glm::vec3(1,4.5f, 5), + glm::vec3(4,-5,0), + glm::vec3(0,4,-4), + glm::vec3(0,6,4), + glm::vec3(0,10,0), + glm::vec3(-2,-16,0), + glm::vec3(0,-4,-8), + glm::vec3(1,1,0), + glm::vec3(3,3,-4), + glm::vec3(0,4,0), + glm::vec3(0,-1,0) + }; + + octree::Tree test(data, 3); + + octree::Node* tNode = test.head.getNodeByVec(glm::vec3(0, 0, -5)); + std::vector points = tNode->getContainedValues(); + + for (int i = 0; i < points.size(); i++) { + glm::vec3 p = points[i]; + + std::cout << p.x << " : " << p.y << " : " << p.z << std::endl; + } + + std::cout << "Total entries: " << test.head.getEntryCount() << std::endl; + + system("PAUSE"); + return 0; + */ + + #pragma region Initialisation - std::cout << "Harry Game Engine" << std::endl; + std::cout << "Bigman Engine" << std::endl; //Initialize OpenGL glfwInit(); @@ -54,7 +131,7 @@ int main() { //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //Creating the window - GLFWwindow* window = glfwCreateWindow(window_width, window_height, "bigman engine :: de_canals.bsp", NULL, NULL); + GLFWwindow* window = glfwCreateWindow(window_width, window_height, "bigman engine", NULL, NULL); //Check if window open if (window == NULL) @@ -71,7 +148,7 @@ int main() { } //Viewport - glViewport(0, 0, 800, 600); + glViewport(0, 0, 1024, 1024); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); //Mouse @@ -86,101 +163,38 @@ int main() { glEnable(GL_DEPTH_TEST); //The unlit shader thing - Shader shader_unlit("unlit.vs", "unlit.fs"); - Shader shader_lit("depth.vs", "depth.fs"); + Shader shader_unlit("shaders/unlit.vs", "shaders/unlit.fs"); + Shader shader_lit("shaders/depth.vs", "shaders/depth.fs"); //Mesh handling ----------------------------------------------------------------------------- - vbsp_level bsp_map("de_canals.bsp", true); - Mesh t200(bsp_map.generate_bigmesh()); - - //test2.generate_mesh(0); - - std::cout << "GENERATED" << std::endl; - - std::vector m_cube_verts = { - // positions // normals rds - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - }; - Mesh cube(m_cube_verts); - - std::vector level_meshes = std::vector(); - - Mesh hallo; - - for (int i = 0; i < bsp_map.texDataString.size(); i++) { - continue; - basic_mesh test_bsp_mesh = bsp_map.generate_mesh(i); - std::vector verts = std::vector(); - for (int x = 0; x < test_bsp_mesh.vertices.size(); x++) { - verts.push_back(test_bsp_mesh.vertices[x].x); - verts.push_back(test_bsp_mesh.vertices[x].y); - verts.push_back(test_bsp_mesh.vertices[x].z); - verts.push_back(test_bsp_mesh.normals[x].x); - verts.push_back(test_bsp_mesh.normals[x].y); - verts.push_back(test_bsp_mesh.normals[x].z); - } - - if (verts.size() < 3) - continue; + Mesh* t200 = NULL; + Mesh* t201 = NULL; - Mesh* m = new Mesh(verts); - GameObject obj(m); + if (_FILE_BSP != ""){ + vbsp_level bsp_map(_FILE_BSP, true); + t200 = new Mesh(bsp_map.generate_bigmesh()); + } - level_meshes.push_back(obj); + if (_FILE_NAV != "") { + Nav::Mesh bob(_FILE_NAV); + t201 = new Mesh(bob.generateGLMesh()); } + //Radar rtest("de_overpass.txt"); + //_radar = &rtest; - std::cout << level_meshes.size() << std::endl; - std::cout << "MESH GENERATION COMPLETE" << std::endl; + //VertAlphaMesh t300(vbsp_level::genVertAlpha(t200.vertices, t201.vertices)); util_keyHandler keys(window); //Create camera (test) camera = Camera(&keys); + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); //The main loop @@ -197,31 +211,49 @@ int main() { //Rendering commands glClearColor(0.05f, 0.05f, 0.05f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glPolygonMode(GL_FRONT, GL_FILL); + - glm::vec3 sunColor = glm::vec3(2.0f, 2.0f, 2.0f); shader_lit.use(); - shader_lit.setVec3("directional.direction", 0.3f, -0.5f, -0.4f); - shader_lit.setVec3("directional.ambient", sunColor * 0.2f); - shader_lit.setVec3("directional.diffuse", sunColor * 0.4f); - shader_lit.setVec3("viewPos", camera.cameraPos); + if(SV_PERSPECTIVE == 0) + shader_lit.setMatrix("projection", glm::perspective(glm::radians(90.0f / 2), (float)window_width / (float)window_height, M_CLIP_NEAR, M_CLIP_FAR)); + else + shader_lit.setMatrix("projection", glm::ortho(-M_ORTHO_SIZE, M_ORTHO_SIZE, -M_ORTHO_SIZE, M_ORTHO_SIZE, M_CLIP_NEAR, M_CLIP_FAR)); - shader_lit.setMatrix("projection", camera.getProjectionMatrix()); shader_lit.setMatrix("view", camera.getViewMatrix()); glm::mat4 model = glm::mat4(); shader_lit.setMatrix("model", model); shader_lit.setVec3("color", 0.0f, 0.0f, 1.0f); + shader_lit.setFloat("HEIGHT_MIN", M_HEIGHT_MIN); + shader_lit.setFloat("HEIGHT_MAX", M_HEIGHT_MAX); + + + if (SV_RENDERMODE == 0) + if(t200 != NULL) + t200->Draw(); + + if(SV_RENDERMODE == 1) + if (t201 != NULL) + t201->Draw(); + + + + + //t300.Draw(); + + //glPolygonMode(GL_FRONT, GL_LINE); + // + //shader_unlit.use(); + //shader_unlit.setMatrix("projection", camera.getProjectionMatrix()); + //shader_unlit.setMatrix("view", camera.getViewMatrix()); + //shader_unlit.setMatrix("model", model); + //shader_unlit.setVec3("color", 0.0f, 0.0f, 1.0f); + // + //t201.Draw(); - //Do drawing logic - for (int i = 0; i < level_meshes.size(); i++) { - level_meshes[i].DrawMesh(); - } - hallo.Draw(); - cube.Draw(); - t200.Draw(); //Check and call events, swap buffers glfwSwapBuffers(window); @@ -241,10 +273,70 @@ void framebuffer_size_callback(GLFWwindow* window, int width, int height) window_height = height; } +bool K_CONTROL_MIN = false; +bool K_CONTROL_MAX = false; +int SV_EDITMODE = 0; + +void setWindowTitle() { + std::string title = "BigmanEngine | "; + +} + void processInput(GLFWwindow* window, util_keyHandler keys) { if (keys.getKeyDown(GLFW_KEY_ESCAPE)) glfwSetWindowShouldClose(window, true); + + if (keys.getKeyDown(GLFW_KEY_1)) { + SV_EDITMODE = 0; glfwSetWindowTitle(window, "Bigman Engine :: EDITING MIN"); + } + if (keys.getKeyDown(GLFW_KEY_2)) { + SV_EDITMODE = 1; glfwSetWindowTitle(window, "Bigman Engine :: EDITING MAX"); + } + if (keys.getKeyDown(GLFW_KEY_3)) { + //SV_EDITMODE = 2; glfwSetWindowTitle(window, "Bigman Engine :: de_overpass.bsp - EDITING NEAR"); + } + if (keys.getKeyDown(GLFW_KEY_4)) { + //SV_EDITMODE = 3; glfwSetWindowTitle(window, "Bigman Engine :: de_overpass.bsp - EDITING FAR"); + } + + if (keys.getKeyDown(GLFW_KEY_5)) { + SV_PERSPECTIVE = 0; glfwSetWindowTitle(window, "Bigman Engine :: perspective"); + } + + if (keys.getKeyDown(GLFW_KEY_6)) { + SV_PERSPECTIVE = 1; glfwSetWindowTitle(window, "Bigman Engine :: ortho"); + } + + + if (keys.getKeyDown(GLFW_KEY_7)) { + SV_RENDERMODE = 0; glfwSetWindowTitle(window, "Bigman Engine :: .bsp"); + + glEnable(GL_CULL_FACE); + } + + if (keys.getKeyDown(GLFW_KEY_8)) { + SV_RENDERMODE = 1; glfwSetWindowTitle(window, "Bigman Engine :: .nav"); + + glDisable(GL_CULL_FACE); + } + + if (keys.getKeyDown(GLFW_KEY_9)) { + SV_EDITMODE = 4; + //M_ORTHO_SIZE = (_radar->scale / 0.1f) / 2.0f; + //camera.cameraPos.x = (-_radar->pos_x ) * 0.01f; + //camera.cameraPos.z = (_radar->pos_y - 1024) * 0.01f; + glfwSetWindowTitle(window, "Bigman Engine :: EDITING ORTHO SCALE"); + + } + + if (keys.getKeyDown(GLFW_KEY_0)) { + camera.yaw = 0; + camera.pitch = -90; + camera.mouseUpdate(0, 0, true); + //camera.cameraFront = glm::vec3(0, 0, -1); + //camera.cameraUp = glm::vec3(0, 1, 0); + } } void mouse_callback(GLFWwindow* window, double xpos, double ypos) @@ -255,7 +347,20 @@ void mouse_callback(GLFWwindow* window, double xpos, double ypos) void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { - camera.fov = glm::clamp(camera.fov + (float)yoffset, 2.0f, 90.0f); + //camera.fov = glm::clamp(camera.fov + (float)yoffset, 2.0f, 90.0f); + + if(SV_EDITMODE == 0) + M_HEIGHT_MIN += (float)yoffset * 0.1f; + + if (SV_EDITMODE == 1) + M_HEIGHT_MAX += (float)yoffset * 0.1f; + + if (SV_EDITMODE == 4) + M_ORTHO_SIZE += (float)yoffset * 0.1f; + + //if (SV_EDITMODE == 2) M_CLIP_NEAR += (float)yoffset * 0.1f; + + //if (SV_EDITMODE == 3) M_CLIP_FAR += (float)yoffset * 0.1f; } void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) diff --git a/MCDV/nav.hpp b/MCDV/nav.hpp new file mode 100644 index 0000000..fabd295 --- /dev/null +++ b/MCDV/nav.hpp @@ -0,0 +1,322 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +//Nav mesh reader +namespace Nav +{ + struct Place { + unsigned int ID; + std::string Name; + }; + + struct Area { + unsigned int ID; + glm::vec3 NW_Point; + glm::vec3 SW_Point; + glm::vec3 NE_Point; + glm::vec3 SE_Point; + + unsigned int flags; + float NE_Z; + float SW_Z; + float NW_Light; + float NE_Light; + float SW_Light; + float SE_Light; + float earliestOccupyA; + float earliestOccupyB; + unsigned short placeID; + }; + + class Mesh { + public: + std::vector areas; + float latestOccupy = 0.0f; + unsigned int majorVersion = 0; + unsigned int minorVersion = 0; + unsigned int BSPSize = 0; + unsigned char meshAnal = 0x0; + + Mesh(std::string filename) { + std::ifstream file(filename, std::ios::in | std::ios::binary); + file.seekg(0); + //Read magic number + unsigned int magicnum = 0; + file.read((char*)&magicnum, sizeof(magicnum)); + + if (magicnum != 0xFEEDFACE) + throw std::exception("Invalid nav mesh file"); + + //Read version number + file.read((char*)&this->majorVersion, sizeof(this->majorVersion)); + + //if (this->majorVersion < 6 || this->majorVersion > 16) throw std::exception("Major version out of bounds"); + + std::cout << "Major version: " << majorVersion << std::endl; + + //Minor version (m10+) + if (majorVersion >= 10) { + file.read((char*)&this->minorVersion, sizeof(this->minorVersion)); + std::cout << "Minor version: " << minorVersion << std::endl; + } + + + //BSP size + file.read((char*)&this->BSPSize, sizeof(this->BSPSize)); + std::cout << "BSP Size (b) " << this->BSPSize << std::endl; + + + if (this->majorVersion >= 14){ + file.read((char*)&this->meshAnal, 1); + std::cout << "mesh analysis: " << (int)this->meshAnal << std::endl; + } + + + file.seekg(17); + + //Getting place count on mesh + unsigned short placecount = 0; + file.read((char*)&placecount, 2); + std::cout << "Places: " << placecount << std::endl; + + //read placenames + for (int i = 0; i < placecount; i++) { + unsigned short namelength = 0; + file.read((char*)&namelength, sizeof(namelength)); + char* name = new char[namelength]; + + file.read(name, namelength); + + std::cout << i << " : " << namelength << " : " << name << std::endl; + + delete[] name; + } + + //Unnamed areas + bool hasUnnamedAreas = false; + if (majorVersion > 11) { + unsigned char v = 0; + file.read((char*)&v, sizeof(v)); + if (v > 0) + hasUnnamedAreas = true; + } + + std::cout << "Mesh has unnamed areas? " << (hasUnnamedAreas ? "True" : "False") << std::endl; + + //Navmesh data + unsigned int areaCount = 0; + file.read((char*)&areaCount, sizeof(areaCount)); + + std::cout << "Areas: " << areaCount << std::endl; + + for (int i = 0; i < areaCount; i++) { + Area thisarea; + + unsigned int areaID = 0; + file.read((char*)&areaID, sizeof(areaID)); + + if (majorVersion <= 8) { + unsigned char flags = 0x0; + file.read((char*)&flags, 1); + } + else if (majorVersion < 13) { + unsigned short flags = 0x0; + file.read((char*)&flags, 2); + } + else { + unsigned int flags = 0x0; + file.read((char*)&flags, 4); + } + + //Read the NW position + file.read((char*)&thisarea.NW_Point, sizeof(glm::vec3)); + file.read((char*)&thisarea.SE_Point, sizeof(glm::vec3)); + + file.read((char*)&thisarea.NE_Z, sizeof(float)); + file.read((char*)&thisarea.SW_Z, sizeof(float)); + + thisarea.NE_Point.x = thisarea.SE_Point.x; + thisarea.NE_Point.y = thisarea.NW_Point.y; + thisarea.NE_Point.z = thisarea.NE_Z; + + thisarea.SW_Point.x = thisarea.NW_Point.x; + thisarea.SW_Point.y = thisarea.SE_Point.y; + thisarea.SW_Point.z = thisarea.SW_Z; + + //Connections + for (int c = 0; c < 4; c++) { + unsigned int conCount; + file.read((char*)&conCount, sizeof(conCount)); + + for (int ci = 0; ci < conCount; ci++) { + unsigned int targetAreaID; + file.read((char*)&targetAreaID, sizeof(targetAreaID)); + } + } + + //How many hiding spots are there in this area? + unsigned char hidingSpotsCount; + file.read((char*)&hidingSpotsCount, 1); + + //Loop each spot to get its flags and locations + for (int hidingindex = 0; hidingindex < hidingSpotsCount; hidingindex++) { + unsigned int hidingID = 0; + file.read((char*)&hidingID, sizeof(hidingID)); + + glm::vec3 location; + file.read((char*)&location, sizeof(location)); + + unsigned char hidingFlags; + file.read((char*)&hidingFlags, 1); + } + + if (majorVersion < 15) { + unsigned char apprAreaCount; + file.read((char*)&apprAreaCount, 1); + + //Skip junk + int junksize = (4 * 3 + 2) * (int)apprAreaCount; + char* junk = new char[junksize]; + file.read(junk, junksize); + delete[] junk; + } + + //Encounter paths + unsigned int encounterpaths; + file.read((char*)&encounterpaths, sizeof(encounterpaths)); + + for (int path = 0; path < encounterpaths; path++) { + unsigned int fromareaID; + file.read((char*)&fromareaID, sizeof(fromareaID)); + unsigned char navDir; + file.read((char*)&navDir, 1); + unsigned int toareaID; + file.read((char*)&toareaID, sizeof(toareaID)); + unsigned char navTargetDir; + file.read((char*)&navTargetDir, 1); + + unsigned char spotcount; + file.read((char*)&spotcount, 1); + for (int spotindex = 0; spotindex < spotcount; spotindex++) { + unsigned int orderID; + file.read((char*)&orderID, sizeof(orderID)); + unsigned char distance; + file.read((char*)&distance, 1); + } + } + + //Handle placenames + unsigned short placeID; + file.read((char*)&placeID, sizeof(placeID)); + + //Ladder stuffs + for (int dir = 0; dir < 2; dir++) { + unsigned int ladderConnections; + file.read((char*)&ladderConnections, sizeof(ladderConnections)); + for (int conn = 0; conn < ladderConnections; conn++) { + unsigned int targetID; + file.read((char*)&targetID, sizeof(targetID)); + } + } + + file.read((char*)&thisarea.earliestOccupyA, sizeof(thisarea.earliestOccupyA)); + file.read((char*)&thisarea.earliestOccupyB, sizeof(thisarea.earliestOccupyB)); + + if(thisarea.earliestOccupyA > latestOccupy) + latestOccupy = thisarea.earliestOccupyA; + + if (thisarea.earliestOccupyB > latestOccupy) + latestOccupy = thisarea.earliestOccupyB; + + //Lighting intensity on area + if (majorVersion >= 11) { + file.read((char*)&thisarea.NW_Light, sizeof(thisarea.NW_Light)); + file.read((char*)&thisarea.NE_Light, sizeof(thisarea.NE_Light)); + file.read((char*)&thisarea.SE_Light, sizeof(thisarea.SE_Light)); + file.read((char*)&thisarea.SW_Light, sizeof(thisarea.SW_Light)); + } + + //Visible areas + if (majorVersion >= 16) { + unsigned int visareaCount; + file.read((char*)&visareaCount, sizeof(visareaCount)); + + for (int visarea = 0; visarea < visareaCount; visarea++) { + unsigned int visibileArea; + file.read((char*)&visibileArea, sizeof(visibileArea)); + + unsigned char attr; + file.read((char*)&attr, 1); + } + } + + unsigned int inheritVisibility; + file.read((char*)&inheritVisibility, sizeof(inheritVisibility)); + + //Unkown + unsigned char unknown; + file.read((char*)&unknown, 1); + + char* bytes = new char[(int)unknown * 14]; + file.read(bytes, (int)unknown * 14); + delete[] bytes; + + areas.push_back(thisarea); + } + + file.close(); + } + + std::vector generateGLMesh() { + std::vector m; + + for (int i = 0; i < this->areas.size(); i++) { + Area area = this->areas[i]; + + m.push_back(this->areas[i].NW_Point.x* 0.01f); + m.push_back(this->areas[i].NW_Point.z* 0.01f); + m.push_back(-this->areas[i].NW_Point.y* 0.01f); + + m.push_back(0); m.push_back(0); m.push_back(1); + + m.push_back(this->areas[i].NE_Point.x* 0.01f); + m.push_back(this->areas[i].NE_Point.z* 0.01f); + m.push_back(-this->areas[i].NE_Point.y* 0.01f); + + m.push_back(0); m.push_back(0); m.push_back(1); + + m.push_back(this->areas[i].SE_Point.x* 0.01f); + m.push_back(this->areas[i].SE_Point.z* 0.01f); + m.push_back(-this->areas[i].SE_Point.y* 0.01f); + + m.push_back(0); m.push_back(0); m.push_back(1); + + m.push_back(this->areas[i].NW_Point.x* 0.01f); + m.push_back(this->areas[i].NW_Point.z* 0.01f); + m.push_back(-this->areas[i].NW_Point.y* 0.01f); + + m.push_back(0); m.push_back(0); m.push_back(1); + + m.push_back(this->areas[i].SE_Point.x* 0.01f); + m.push_back(this->areas[i].SE_Point.z* 0.01f); + m.push_back(-this->areas[i].SE_Point.y* 0.01f); + + m.push_back(0); m.push_back(0); m.push_back(1); + + m.push_back(this->areas[i].SW_Point.x* 0.01f); + m.push_back(this->areas[i].SW_Point.z* 0.01f); + m.push_back(-this->areas[i].SW_Point.y* 0.01f); + + m.push_back(0); m.push_back(0); m.push_back(1); + } + + std::cout << m.size() << std::endl; + return m; + } + }; +} \ No newline at end of file diff --git a/MCDV/radar.hpp b/MCDV/radar.hpp new file mode 100644 index 0000000..0131795 --- /dev/null +++ b/MCDV/radar.hpp @@ -0,0 +1,37 @@ +#pragma once +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +#include "vdf.hpp" + +class Radar { +public: + float pos_x = 0.0f; + float pos_y = 0.0f; + float scale = 0.0f; + + Radar(std::string path) { + std::cout << "Opening radar file" << std::endl; + + std::ifstream t(path); + std::string data((std::istreambuf_iterator(t)), + std::istreambuf_iterator()); + + kv::FileData kvfile(data); + + this->pos_x = ::atof(kvfile.headNode.SubBlocks[0].Values["pos_x"].c_str()); + this->pos_y = ::atof(kvfile.headNode.SubBlocks[0].Values["pos_y"].c_str()); + this->scale = ::atof(kvfile.headNode.SubBlocks[0].Values["scale"].c_str()); + + std::cout << "X:{" << this->pos_x << "} Y:{" << this->pos_y << "} SCALE:{" << this->scale << "}" << std::endl; + } +}; \ No newline at end of file diff --git a/MCDV/shaders/depth.fs b/MCDV/shaders/depth.fs new file mode 100644 index 0000000..c3c8d5f --- /dev/null +++ b/MCDV/shaders/depth.fs @@ -0,0 +1,20 @@ +#version 330 core +out vec4 FragColor; + +uniform vec3 color; +uniform float test; + +uniform float HEIGHT_MIN; +uniform float HEIGHT_MAX; + +in vec3 FragPos; +in float Depth; +in float Alpha; + + +void main() +{ + float height = (Depth - HEIGHT_MIN) / HEIGHT_MAX; + + FragColor = vec4(height, height, height, Alpha); +} \ No newline at end of file diff --git a/MCDV/shaders/depth.vs b/MCDV/shaders/depth.vs new file mode 100644 index 0000000..74322c9 --- /dev/null +++ b/MCDV/shaders/depth.vs @@ -0,0 +1,27 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +layout (location = 2) in float alpha; + +out vec3 FragPos; +out vec3 Normal; +out float Depth; +out float Alpha; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + + + +void main() +{ + FragPos = vec3(model * vec4(aPos, 1.0)); + Normal = mat3(transpose(inverse(model))) * aNormal; + + gl_Position = projection * view * model * vec4(aPos, 1.0); + //Depth = gl_Position.z / 100.0; + + Depth = FragPos.y; + Alpha = alpha; +} \ No newline at end of file diff --git a/MCDV/shaders/lit.fs b/MCDV/shaders/lit.fs new file mode 100644 index 0000000..0aec410 --- /dev/null +++ b/MCDV/shaders/lit.fs @@ -0,0 +1,43 @@ +#version 330 core +out vec4 FragColor; + +struct DirLight { + vec3 direction; + + vec3 ambient; + vec3 diffuse; +}; + +in vec3 FragPos; +in vec3 Normal; + +uniform vec3 viewPos; + +//Lights +uniform DirLight directional; +uniform vec3 color; + +//Prototypes +vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir); + +void main() +{ + vec3 viewDir = normalize(viewPos - FragPos); + + FragColor = vec4(CalcDirLight(directional, Normal, viewDir) * color, 1.0); +} + +vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir) +{ + //Ambient value + vec3 ambient = light.ambient; + + vec3 norm = normalize(normal); + + //diffuse + vec3 lightDir = normalize(-light.direction); + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = light.diffuse * diff; + + return (ambient + diffuse); +} \ No newline at end of file diff --git a/MCDV/shaders/lit.vs b/MCDV/shaders/lit.vs new file mode 100644 index 0000000..59b3128 --- /dev/null +++ b/MCDV/shaders/lit.vs @@ -0,0 +1,18 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; + +out vec3 FragPos; +out vec3 Normal; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + FragPos = vec3(model * vec4(aPos, 1.0)); + Normal = mat3(transpose(inverse(model))) * aNormal; + + gl_Position = projection * view * model * vec4(aPos, 1.0); +} \ No newline at end of file diff --git a/MCDV/shaders/unlit.fs b/MCDV/shaders/unlit.fs new file mode 100644 index 0000000..1c599c2 --- /dev/null +++ b/MCDV/shaders/unlit.fs @@ -0,0 +1,9 @@ +#version 330 core +out vec4 FragColor; + +uniform vec3 color; + +void main() +{ + FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/MCDV/shaders/unlit.vs b/MCDV/shaders/unlit.vs new file mode 100644 index 0000000..3119a41 --- /dev/null +++ b/MCDV/shaders/unlit.vs @@ -0,0 +1,13 @@ +#version 330 core +layout (location = 0) in vec3 aPos; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +out vec3 Normal; + +void main() +{ + gl_Position = projection * view * model * vec4(aPos, 1.0); +} \ No newline at end of file diff --git a/MCDV/util.h b/MCDV/util.h index ebc331a..8441b08 100644 --- a/MCDV/util.h +++ b/MCDV/util.h @@ -2,7 +2,9 @@ #include #include #include -#include +#include + +#include // Attach to a class for verbosity debug message control @@ -23,4 +25,94 @@ namespace util { } } }; +} + +std::vector split(std::string string, char delim) +{ + std::stringstream cStream(string); + std::string seg; + std::vector sgts; + + while (std::getline(cStream, seg, delim)) + sgts.push_back(seg); + + return sgts; +} + +std::vector split(std::string s, std::string delimiter) +{ + std::vector sgts; + size_t pos = 0; + std::string token; + while ((pos = s.find(delimiter)) != std::string::npos) { + token = s.substr(0, pos); + sgts.push_back(token); + s.erase(0, pos + delimiter.length()); + } + sgts.push_back(s); + return sgts; +} + +namespace sutil +{ + std::string trimspace(std::string const& str) + { + if (str.empty()) + return str; + + std::size_t firstScan = str.find_first_not_of(' '); + std::size_t first = firstScan == std::string::npos ? str.length() : firstScan; + std::size_t last = str.find_last_not_of(' '); + return str.substr(first, last - first + 1); + } + + std::string trimbt(std::string const& str) + { + if (str.empty()) + return str; + + std::size_t firstScan = str.find_first_not_of('\t'); + std::size_t first = firstScan == std::string::npos ? str.length() : firstScan; + std::size_t last = str.find_last_not_of('\t'); + return str.substr(first, last - first + 1); + } + + std::string trim(std::string str) + { + return trimspace(trimbt(str)); + } + + std::string removeChar(std::string str, char ch) + { + str.erase(std::remove(str.begin(), str.end(), ch), str.end()); + return str; + } + + std::vector regexmulti(std::string src, std::string pattern) + { + const std::regex r(pattern); + + std::smatch res; + + std::vector matches; + while (std::regex_search(src, res, r)) { + matches.push_back(res[0]); + src = res.suffix(); + } + + return matches; + } + + std::vector regexmulti(std::string src, const std::regex pattern) + { + std::smatch res; + + std::vector matches; + while (std::regex_search(src, res, pattern)) { + matches.push_back(res[0]); + src = res.suffix(); + } + + return matches; + } } \ No newline at end of file diff --git a/MCDV/vbsp.hpp b/MCDV/vbsp.hpp index e883061..c758f24 100644 --- a/MCDV/vbsp.hpp +++ b/MCDV/vbsp.hpp @@ -2,9 +2,11 @@ #include #include #include +#include #include "util.h" #include "interpolation.h" +#include "VectorOctTree.hpp" #include "generic.hpp" #include "lumps_geometry.hpp" @@ -527,66 +529,74 @@ public: for (int i = 0; i < this->faces.size(); i++) { bsp::face face = this->faces[i]; - std::vector vertices; - for (int e = face.firstEdge; e < face.firstEdge + face.numEdges; e++) { - //edge_indexes.push_back); - int index = this->surfEdges[e]; - if (index >= 0) //Trace forwards - { - vertices.push_back(this->vertices[this->edges[index].vertex[0]]); - vertices.push_back(this->vertices[this->edges[index].vertex[1]]); + if (face.dispInfo == -1 || true) + { + std::vector vertices; + for (int e = face.firstEdge; e < face.firstEdge + face.numEdges; e++) { + //edge_indexes.push_back); + int index = this->surfEdges[e]; + if (index >= 0) //Trace forwards + { + vertices.push_back(this->vertices[this->edges[index].vertex[0]]); + vertices.push_back(this->vertices[this->edges[index].vertex[1]]); + } + else + { + vertices.push_back(this->vertices[this->edges[std::abs(index)].vertex[1]]); + vertices.push_back(this->vertices[this->edges[std::abs(index)].vertex[0]]); + } } - else - { - vertices.push_back(this->vertices[this->edges[std::abs(index)].vertex[1]]); - vertices.push_back(this->vertices[this->edges[std::abs(index)].vertex[0]]); + + //Get face normal + glm::vec3 normal = this->planes[face.planeNum].normal; + if (face.side != 0) + normal = -normal; + + normal = glm::normalize(normal); + + //Write to verts array + for (int v = 1; v < vertices.size() - 1; v++) { + //Get verts positions + bsp::vertex v0 = vertices[0]; + bsp::vertex v1 = vertices[v]; + bsp::vertex v2 = vertices[v + 1]; + + //Write + verts.push_back(v0.position.x* 0.01f); + verts.push_back(v0.position.z* 0.01f); + verts.push_back(-v0.position.y* 0.01f); + + + verts.push_back(normal.x); + verts.push_back(normal.z); + verts.push_back(-normal.y); + + + verts.push_back(v1.position.x* 0.01f); + verts.push_back(v1.position.z* 0.01f); + verts.push_back(-v1.position.y* 0.01f); + + + verts.push_back(normal.x); + verts.push_back(normal.z); + verts.push_back(-normal.y); + + + verts.push_back(v2.position.x* 0.01f); + verts.push_back(v2.position.z* 0.01f); + verts.push_back(-v2.position.y* 0.01f); + + + verts.push_back(normal.x); + verts.push_back(normal.z); + verts.push_back(-normal.y); } } - //Get face normal - glm::vec3 normal = this->planes[face.planeNum].normal; - if (face.side != 0) - normal = -normal; - - normal = glm::normalize(normal); - - //Write to verts array - for (int v = 1; v < vertices.size() -1; v++) { - //Get verts positions - bsp::vertex v0 = vertices[0]; - bsp::vertex v1 = vertices[v]; - bsp::vertex v2 = vertices[v + 1]; - - //Write - verts.push_back(v0.position.x* 0.01f); - verts.push_back(v0.position.z* 0.01f); - verts.push_back(v0.position.y* 0.01f); - - - verts.push_back(normal.x); - verts.push_back(normal.z); - verts.push_back(normal.y); - - - verts.push_back(v1.position.x* 0.01f); - verts.push_back(v1.position.z* 0.01f); - verts.push_back(v1.position.y* 0.01f); - - - verts.push_back(normal.x); - verts.push_back(normal.z); - verts.push_back(normal.y); - - - verts.push_back(v2.position.x* 0.01f); - verts.push_back(v2.position.z* 0.01f); - verts.push_back(v2.position.y* 0.01f); - - - verts.push_back(normal.x); - verts.push_back(normal.z); - verts.push_back(normal.y); - + //Deal with displacements + else + { + } if (i > 35000) { @@ -597,4 +607,62 @@ public: return verts; } + + static std::vector genVertAlpha(std::vector source, std::vector mask) { + std::cout << "Generating vertex alpha mask" << std::endl; + std::cout << "Vertices to process :: " << source.size() / 6 << std::endl; + std::cout << "Mask vertices :: " << mask.size() / 6 << std::endl; + + std::vector maskverts; + for (int i = 0; i < mask.size() / 6; i++) { + maskverts.push_back(glm::vec3(mask[i * 6 + 0], mask[i * 6 + 1], mask[i * 6 + 2])); + } + + std::vector bspverts; + for (int i = 0; i < source.size() / 6; i++) { + bspverts.push_back(glm::vec3(source[i * 6 + 0], source[i * 6 + 1], source[i * 6 + 2])); + } + + //Generate oct tree for mask vertices + octree::Tree cloud(maskverts, 2); + + std::vector verts; //Vertex output + + std::cout << "Processing" << std::endl; + + int _c = 0; + + for (int i = 0; i < bspverts.size(); i++) { + glm::vec3 v0 = bspverts[i]; + + octree::Node* tNode = cloud.head.getNodeByVec(v0); + std::vector points = tNode->getContainedValues(); + + //Initialize smallest distance to infinity + float mindist = std::numeric_limits::infinity(); + + for (int x = 0; x < points.size(); x++) { + float d = glm::distance(*points[x], v0); + if (d < mindist) + mindist = d; + } + + verts.push_back(v0.x); verts.push_back(v0.y); verts.push_back(v0.z); + verts.push_back(0); verts.push_back(0); verts.push_back(1); + + verts.push_back(mindist * 0.05f); + + _c++; + + if (_c > 1000) { + std::cout << "% " << ((float)i / (float)bspverts.size())*100.0f << std::endl; + std::cout << "Completed " << i << "verts" << std::endl; + _c = 0; + } + } + + std::cout << "Done!!" << std::endl; + + return verts; + } }; \ No newline at end of file diff --git a/MCDV/vdf.hpp b/MCDV/vdf.hpp new file mode 100644 index 0000000..cf49a1a --- /dev/null +++ b/MCDV/vdf.hpp @@ -0,0 +1,123 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +#include + +#include "Util.h" + + +namespace kv +{ + const std::regex reg_kv("(\"([^=\"]*)\")|([^=\\s]+)"); + + class DataBlock + { + public: + std::string name = ""; + std::vector SubBlocks; + std::map Values; + + DataBlock() {} + + DataBlock(std::istringstream* stream, std::string name = "") { + this->name = sutil::trim(name); + + std::string line, prev = ""; + while (std::getline(*stream, line)) { + line = split(line, "//")[0]; + + if (line.find("{") != std::string::npos) { + std::string pname = prev; + prev.erase(std::remove(prev.begin(), prev.end(), '"'), prev.end()); + this->SubBlocks.push_back(DataBlock(stream, pname)); + continue; + } + if (line.find("}") != std::string::npos) { + return; + } + +#ifdef _DEBUG + // Regex is so fucking slow in debug mode its unreal + // Rather have it mess up than take 10 hours + + std::vector s1 = split(line, '"'); + std::vector strings; + + if (s1.size() >= 3) + { + strings.push_back(s1[1]); + strings.push_back(s1[3]); + } +#endif + +#ifndef _DEBUG + std::vector strings = sutil::regexmulti(line, reg_kv); +#endif + + for (int i = 0; i < strings.size(); i++) { + strings[i] = sutil::removeChar(strings[i], '"'); + } + + if (strings.size() == 2) { + this->Values.insert({ strings[0], strings[1] }); + } + + prev = line; + } + } + + //Scan for sub block with name + DataBlock* GetFirstByName(std::string _name) { + for (int i = 0; i < this->SubBlocks.size(); i++) { + if (_name == this->SubBlocks[i].name) + return &this->SubBlocks[i]; + } + + return NULL; + } + + //Gets all sub blocks by type + std::vector GetAllByName(std::string _name) { + std::vector c; + + for (int i = 0; i < this->SubBlocks.size(); i++) { + if (_name == this->SubBlocks[i].name) + c.push_back(this->SubBlocks[i]); + } + + return c; + } + }; + + class FileData + { + public: + DataBlock headNode; + + FileData(std::string filestring) + { + std::istringstream sr(filestring); + + auto start = std::chrono::high_resolution_clock::now(); + + this->headNode = DataBlock(&sr); + + + auto elapsed = std::chrono::high_resolution_clock::now() - start; + long long milliseconds = std::chrono::duration_cast(elapsed).count(); + std::cout << "KV Read time: " << milliseconds << "ms" << std::endl; + } + + FileData() + { + + } + + ~FileData() {} + }; +} \ No newline at end of file -- 2.25.1