From 3091e14de659112e23a11efc14ce4576f65fa135 Mon Sep 17 00:00:00 2001 From: Terri00 Date: Mon, 11 Mar 2019 19:47:20 +0000 Subject: [PATCH] Compositor Engine --- MCDV/1whammy.png | Bin 0 -> 50015 bytes MCDV/FrameBuffer.hpp | 71 ++- MCDV/MCDV.vcxproj | 2 + MCDV/MCDV.vcxproj.filters | 6 + MCDV/Mesh.hpp | 21 +- MCDV/Texture.hpp | 6 + MCDV/buyzone-bombtargets.png | Bin 30558 -> 41176 bytes MCDV/de_tavr_test.prt | 705 +++++++++++++++-------------- MCDV/de_tavr_test.txt | 8 +- MCDV/de_tavr_test.vmf | 788 +++++---------------------------- MCDV/de_tavr_test.vmx | 788 +++++---------------------------- MCDV/interpolation.h | 5 + MCDV/main.cpp | 122 +++-- MCDV/playable-space.png | Bin 60079 -> 42023 bytes MCDV/shaders/depth.fs | 2 +- MCDV/shaders/fullscreenbase.vs | 9 + MCDV/shaders/ss_test.fs | 62 +++ MCDV/vdf.hpp | 6 + MCDV/vmf.hpp | 46 +- 19 files changed, 844 insertions(+), 1803 deletions(-) create mode 100644 MCDV/1whammy.png create mode 100644 MCDV/shaders/fullscreenbase.vs create mode 100644 MCDV/shaders/ss_test.fs diff --git a/MCDV/1whammy.png b/MCDV/1whammy.png new file mode 100644 index 0000000000000000000000000000000000000000..f494a40037f66cd370a8182c5b2d84eb3fc96fe5 GIT binary patch literal 50015 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 GnDGBwa?~RL literal 0 HcmV?d00001 diff --git a/MCDV/FrameBuffer.hpp b/MCDV/FrameBuffer.hpp index 555685b..3bb6e28 100644 --- a/MCDV/FrameBuffer.hpp +++ b/MCDV/FrameBuffer.hpp @@ -8,63 +8,56 @@ #include "GLFWUtil.hpp" -#define STBI_MSC_SECURE_CRT -#define STB_IMAGE_WRITE_IMPLEMENTATION -#include "stb_image_write.h" - - class FrameBuffer { public: unsigned int fbo; unsigned int rbo; - unsigned int texture; + unsigned int texColorBuffer; - FrameBuffer(bool depthtest = true) { - glGenFramebuffers(1, &this->fbo); //Generate frame buffer - glBindFramebuffer(GL_FRAMEBUFFER, this->fbo); + unsigned int width; + unsigned int height; - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { + FrameBuffer(int width = 1024, int height = 1024, bool depthtest = true) { + this->width = width; + this->height = height; - glGenTextures(1, &this->texture); - glBindTexture(GL_TEXTURE_2D, this->texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + //unsigned int framebuffer; + glGenFramebuffers(1, &this->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, this->fbo); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBindTexture(GL_TEXTURE_2D, 0); + // generate texture + //unsigned int texColorBuffer; + glGenTextures(1, &this->texColorBuffer); + glBindTexture(GL_TEXTURE_2D, this->texColorBuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); - //attach - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->texture, 0); + // attach it to currently bound framebuffer object + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->texColorBuffer, 0); - if (depthtest) - { - glGenRenderbuffers(1, &this->rbo); - glBindRenderbuffer(GL_RENDERBUFFER, this->rbo); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1024, 1024); - glBindRenderbuffer(GL_RENDERBUFFER, 0); + glGenRenderbuffers(1, &this->rbo); + glBindRenderbuffer(GL_RENDERBUFFER, this->rbo); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1024, 1024); + glBindRenderbuffer(GL_RENDERBUFFER, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, this->rbo); - } + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, this->rbo); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - std::cout << "Framebuffer failed to generate" << std::endl; - } + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl; FrameBuffer::Unbind(); } - void Bind() { - glBindFramebuffer(GL_FRAMEBUFFER, this->fbo); + void BindRTtoTexSlot(int slot = 0) { + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(GL_TEXTURE_2D, this->texColorBuffer); + glActiveTexture(GL_TEXTURE0); } - void Save() { - void* data = malloc(3 * 1024 * 1024); - glReadPixels(0, 0, 1024, 1024, GL_RGB, GL_UNSIGNED_BYTE, data); - - if (data != 0) - stbi_write_png("test.png", 1024, 1024, 3, data, 1024 * 3); - else - std::cout << "Something went wrong making render" << std::endl; + void Bind() { + glBindFramebuffer(GL_FRAMEBUFFER, this->fbo); //Set as active draw target } static void Unbind() { diff --git a/MCDV/MCDV.vcxproj b/MCDV/MCDV.vcxproj index 4431cc5..3a1e722 100644 --- a/MCDV/MCDV.vcxproj +++ b/MCDV/MCDV.vcxproj @@ -163,6 +163,8 @@ + + diff --git a/MCDV/MCDV.vcxproj.filters b/MCDV/MCDV.vcxproj.filters index 9c85231..8068d42 100644 --- a/MCDV/MCDV.vcxproj.filters +++ b/MCDV/MCDV.vcxproj.filters @@ -165,6 +165,12 @@ OpenGL\Shader Files + + OpenGL\Shader Files + + + OpenGL\Shader Files + diff --git a/MCDV/Mesh.hpp b/MCDV/Mesh.hpp index a5a5c13..77d6a1e 100644 --- a/MCDV/Mesh.hpp +++ b/MCDV/Mesh.hpp @@ -15,7 +15,8 @@ enum MeshMode { POS_XYZ_TEXCOORD_UV, - POS_XYZ_NORMAL_XYZ + POS_XYZ_NORMAL_XYZ, + SCREEN_SPACE_UV }; class Mesh { @@ -39,7 +40,6 @@ public: this->vertices = vertices; this->elementCount = vertices.size() / 5; - // first, configure the cube's VAO (and VBO) glGenVertexArrays(1, &this->VAO); glGenBuffers(1, &this->VBO); @@ -60,7 +60,6 @@ public: this->vertices = vertices; this->elementCount = vertices.size() / 6; - // first, configure the cube's VAO (and VBO) glGenVertexArrays(1, &this->VAO); glGenBuffers(1, &this->VBO); @@ -77,6 +76,22 @@ public: glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); } + else if (mode == MeshMode::SCREEN_SPACE_UV) { + this->vertices = vertices; + this->elementCount = vertices.size() / 2; + + 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, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + } } Mesh(std::vector vertices) { diff --git a/MCDV/Texture.hpp b/MCDV/Texture.hpp index c237ca6..b032fdc 100644 --- a/MCDV/Texture.hpp +++ b/MCDV/Texture.hpp @@ -17,6 +17,7 @@ public: Texture(std::string filepath); void bind(); + void bindOnSlot(int slot); ~Texture(); }; @@ -81,4 +82,9 @@ Texture::~Texture() void Texture::bind() { glBindTexture(GL_TEXTURE_2D, this->texture_id); +} + +void Texture::bindOnSlot(int slot = 0) { + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(GL_TEXTURE_2D, this->texture_id); } \ No newline at end of file diff --git a/MCDV/buyzone-bombtargets.png b/MCDV/buyzone-bombtargets.png index ad4c654ebd0b4b6a57e700949d8417ca4c974b82..e91265546b235d32ed1d9a2944c6bc39426e253d 100644 GIT binary patch literal 41176 zcmeI)Pe>F|9Ki86y4ET?G97|((`+vh*kO`AgaoN;s|zI|K@b>Ifou@{L&6|XGn8W0 zyO)9`p-UKajs?jmiyS-zoeDh^cnInc1lqJ-Tz7f%HfDE|z8=Ou50^J@f4|RrGy8jU z|8#G+UKg$tLg;w(QUzOx26j!SC|d zb6d5D)h4W&x83sBi`jvDnJ*%fY;D#@}Kw*Ncgv@6(2M;mdXDv90LX%E(9l5P9_d$%ii+Ugft{7jw&P zAFn;`TeT(!e#lFuvaQ9G^Up0UPLJJA)V{FH{;RF$>bG|yw~L`2QA|v6m)zuH3RVxN zpB3H@0hI4eEuJy&T<^3}a{+0K$nL|F7Q~>)I?0+^vDeN!uzjB@mVEMFG zf(l?Ql4%Vu%6D_bS^{Q+X?Cw%i3WPyG;}wMT^^8!o7<`!9?Vnnu~eR?*t6hq8LAwT z%CiY#m0c{j@QDlc*@VR>i_Zev(v_7|p25^Z63TrFNjWC8a#xePn#JAKBxlGOa)zAo zxELi#ND`8SBw@LLgh+^lNQi_;h=fRpgh+^lNQi_;h=l%0c&J`maID6y9~@q2+I)uk zx6Nm$-+Gn2nA5I>v{`4#^P%K!5y<-Hlg{7#XU|ur=E}n;KB(WCZ~4_yJEDk!nk)G{ zRDuE*YOcziH&71cg%(@>&tN6sLb;Pr4&?=IEmSfjm6t&BcaGLVdhxdc(N3rk7K8=& zS3MTIBne4El8_`U7myGMkq`-y5DAeG36T&9kq`-y5DAeG36bz$l5pffM2Mx;klC_+ R@|SSG5+{1Qo_5-Ie*=47j}QO= delta 75 zcmca{km=q##tD+5ObiSRAL{p9VPGg%^>lFzsfbIKVBHw#A-S #include @@ -25,19 +27,19 @@ #include "stb_image_write.h" void render_to_png(int x, int y, const char* filepath){ - void* data = malloc(3 * x * y); + void* data = malloc(4 * x * y); - glReadPixels(0, 0, x, y, GL_RGB, GL_UNSIGNED_BYTE, data); + glReadPixels(0, 0, x, y, GL_RGBA, GL_UNSIGNED_BYTE, data); if (data != 0) { stbi_flip_vertically_on_write(true); - stbi_write_png(filepath, x, y, 3, data, x * 3); + stbi_write_png(filepath, x, y, 4, data, x * 4); } } int main(int argc, char* argv[]) { std::cout << "Loading VMF\n"; - vmf::vmf vmf_main("blimey.vmf"); + vmf::vmf vmf_main("de_tavr_test.vmf"); std::cout << "Initializing OpenGL\n"; @@ -69,39 +71,27 @@ int main(int argc, char* argv[]) { glViewport(0, 0, 1024, 1024); - glClearColor(0.00f, 0.00f, 0.00f, 1.0f); - -#pragma endregion - -#pragma region init_framebuffer + glClearColor(0.00f, 0.00f, 0.00f, 0.00f); - unsigned int framebuffer; - glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + std::cout << "Creating render buffers\n"; - // generate texture - unsigned int texColorBuffer; - glGenTextures(1, &texColorBuffer); - glBindTexture(GL_TEXTURE_2D, texColorBuffer); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBindTexture(GL_TEXTURE_2D, 0); + FrameBuffer fb_tex_playspace = FrameBuffer(1024, 1024); + FrameBuffer fb_tex_objectives = FrameBuffer(1024, 1024); + FrameBuffer fb_comp = FrameBuffer(1024, 1024); - // attach it to currently bound framebuffer object - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0); + // Screenspace quad + std::cout << "Creating screenspace mesh\n"; - unsigned int rbo; - glGenRenderbuffers(1, &rbo); - glBindRenderbuffer(GL_RENDERBUFFER, rbo); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1024, 1024); - glBindRenderbuffer(GL_RENDERBUFFER, 0); + std::vector __meshData = { + -1, -1, + -1, 1, + 1, -1, + -1, 1, + 1, 1, + 1, -1 + }; - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl; - //glBindFramebuffer(GL_FRAMEBUFFER, 0); + Mesh* mesh_screen_quad = new Mesh(__meshData, MeshMode::SCREEN_SPACE_UV); #pragma endregion @@ -141,15 +131,30 @@ int main(int argc, char* argv[]) { glm::vec2 view_origin = glm::vec2(x_bounds_min - justify_x, y_bounds_max + justify_y); std::cout << "done\n"; -#pragma endregion bounds +#pragma endregion + +#pragma region shader_compilation std::cout << "Compiling Shaders\n"; + + // Engine shaders Shader shader_depth("shaders/depth.vs", "shaders/depth.fs"); Shader shader_unlit("shaders/unlit.vs", "shaders/unlit.fs"); + // Compositing shaders + Shader shader_comp_main("shaders/fullscreenbase.vs", "shaders/ss_test.fs"); // le big one + + std::cout << "Loading textures\n"; + + Texture tex_background = Texture("textures/grid.png"); + +#pragma endregion + #pragma region render_playable_space std::cout << "Rendering playable space..."; + fb_tex_playspace.Bind(); //Bind framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT, GL_FILL); //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -180,11 +185,13 @@ int main(int argc, char* argv[]) { render_to_png(1024, 1024, "playable-space.png"); std::cout << "done!\n"; -#pragma endregion render_playable_space +#pragma endregion -#pragma region render_buyzone_bombsites +#pragma region render_objectives std::cout << "Rendering bombsites & buyzones space..."; + fb_tex_objectives.Bind(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT, GL_FILL); //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -209,7 +216,7 @@ int main(int argc, char* argv[]) { render_to_png(1024, 1024, "buyzone-bombtargets.png"); std::cout << "done!\n"; -#pragma endregion +#pragma endregion #pragma region generate_radar_txt @@ -221,17 +228,52 @@ int main(int argc, char* argv[]) { node_radar.Values.insert({ "pos_y", std::to_string(view_origin.y) }); node_radar.Values.insert({ "scale", std::to_string(render_ortho_scale / 1024.0f) }); + // Try resolve spawn positions + glm::vec3* loc_spawnCT = vmf_main.calculateSpawnLocation(vmf::team::counter_terrorist); + glm::vec3* loc_spawnT = vmf_main.calculateSpawnLocation(vmf::team::terrorist); + + if (loc_spawnCT != NULL) { + node_radar.Values.insert({ "CTSpawn_x", std::to_string(glm::round(remap(loc_spawnCT->x, view_origin.x, view_origin.x + render_ortho_scale, 0.0f, 1.0f) / 0.01f) * 0.01f) }); + node_radar.Values.insert({ "CTSpawn_y", std::to_string(glm::round(remap(loc_spawnCT->y, view_origin.y, view_origin.y - render_ortho_scale, 0.0f, 1.0f) / 0.01f) * 0.01f) }); + } + if (loc_spawnT != NULL) { + node_radar.Values.insert({ "TSpawn_x", std::to_string(glm::round(remap(loc_spawnT->x, view_origin.x, view_origin.x + render_ortho_scale, 0.0f, 1.0f) / 0.01f) * 0.01f) }); + node_radar.Values.insert({ "TSpawn_y", std::to_string(glm::round(remap(loc_spawnT->y, view_origin.y, view_origin.y - render_ortho_scale, 0.0f, 1.0f) / 0.01f) * 0.01f) }); + } + std::ofstream out("de_tavr_test.txt"); out << "// TAVR - AUTO RADAR. v 2.0.0\n"; node_radar.Serialize(out); out.close(); -#pragma endregion generate_radar_txt +#pragma endregion #pragma region compositing + std::cout << "Compositing... \n"; + + fb_comp.Bind(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glPolygonMode(GL_FRONT, GL_FILL); + + shader_comp_main.use(); + + tex_background.bindOnSlot(0); + shader_comp_main.setInt("tex_background", 0); + + fb_tex_playspace.BindRTtoTexSlot(1); + shader_comp_main.setInt("tex_playspace", 1); + + fb_tex_objectives.BindRTtoTexSlot(2); + shader_comp_main.setInt("tex_objectives", 2); + + mesh_screen_quad->Draw(); + + render_to_png(1024, 1024, "1whammy.png"); + std::cout << "Done\n"; -#pragma endregion compositing +#pragma endregion #pragma region auto_export_game diff --git a/MCDV/playable-space.png b/MCDV/playable-space.png index f923291f210b61dff8630aa2d3e63c5907661f4c..ed0e74e60af7551a8401070ae7da898698fc708b 100644 GIT binary patch literal 42023 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 diff --git a/MCDV/shaders/depth.fs b/MCDV/shaders/depth.fs index 90890a5..0c9efda 100644 --- a/MCDV/shaders/depth.fs +++ b/MCDV/shaders/depth.fs @@ -21,5 +21,5 @@ void main() { float height = pow(remap(FragPos.y, HEIGHT_MIN, HEIGHT_MAX, 0, 1), 2.2); - FragColor = vec4(0, height, 1, 1.0); + FragColor = vec4(0, 1, 1, height); } \ No newline at end of file diff --git a/MCDV/shaders/fullscreenbase.vs b/MCDV/shaders/fullscreenbase.vs new file mode 100644 index 0000000..e498c20 --- /dev/null +++ b/MCDV/shaders/fullscreenbase.vs @@ -0,0 +1,9 @@ +#version 330 core +layout (location = 0) in vec2 vert; +out vec2 TexCoords; + +void main() +{ + gl_Position = vec4(vert.xy, 0.0, 1.0); + TexCoords = (vert.xy + vec2(1, 1)) * 0.5; +} \ No newline at end of file diff --git a/MCDV/shaders/ss_test.fs b/MCDV/shaders/ss_test.fs new file mode 100644 index 0000000..cf8385b --- /dev/null +++ b/MCDV/shaders/ss_test.fs @@ -0,0 +1,62 @@ +#version 330 core +// Note:: All channels marked with an ** are currently not filled out by the engine. + +// OPENGL +// ____________________________________________________________________________________________ +in vec2 TexCoords; +out vec4 FragColor; + +// UNIFORMS +// Vector Information _________________________________________________________________________ +// ( A bunch of vectors that give you the location of different entities ) +uniform vec3 bounds_NWU; // North-West-Upper coordinate of the playspace (worldspace) +uniform vec3 bounds_SEL; // South-East-Lower coordinate of the playspace (worldspace) +uniform vec2 bounds_NWU_SS; // North-West coordinate of the playspace (screen space) +uniform vec2 bounds_SEL_SS; // South-East coordinate of the playspace (screen space) + +uniform vec2 pos_spawn_ct; // Location of the CT Spawn (0-1) +uniform vec2 pos_spawn_t; // Location of the T Spawn (0-1) +uniform vec2 bombsite_a; // Location of bomsite A (0-1) +uniform vec2 bombsite_b; // Location of bombsite B (0-1) + +// SAMPLER UNIFORMS +// Image Inputs _______________________________________________________________________________ +// ( Standard generated maps from the engine ) +uniform sampler2D tex_background; // Background texture +uniform sampler2D tex_playspace; // Playspace + // R: Playable space (0 or 1), + // G: Height (0-1 normalized) + // **B: AO map (mask 0-1) + // **A: Outline (mask 0-1)) + +uniform sampler2D tex_objectives; // Objectives + // R: Buzones (0 or 1) + // G: Bombsites (0 or 1) + // **B: Glow map (mask 0-1) + // **A: Outline (mask 0-1) + +uniform sampler2D tex_props; // Props + // **R: Props (0 or 1) + // **G: Height (0-1 normalized) + // **B: Glow map (mask 0-1) + // **A: Outline (mask 0-1) + +uniform sampler2D tex_gradient; // Gradient input + // **RGBA: 256x1 image defining a gradient + +uniform sampler2D texture0; // Custom Image input 3 (**RGBA) +uniform sampler2D texture1; // Custom Image input 4 (**RGBA) +uniform sampler2D texture2; // Custom Image input 5 (**RGBA) + +// SHADER PROGRAM +// ____________________________________________________________________________________________ +// ( Write all your shader code & functions here ) + +void main() +{ + vec4 sBackground = vec4(texture(tex_background, TexCoords)); + vec4 sObjectives = vec4(texture(tex_objectives, TexCoords)); + + // Return the final output color + FragColor = vec4(sBackground.rgb, 1);//-sBackground; +} \ No newline at end of file diff --git a/MCDV/vdf.hpp b/MCDV/vdf.hpp index bcbb1f7..1a36d57 100644 --- a/MCDV/vdf.hpp +++ b/MCDV/vdf.hpp @@ -15,6 +15,12 @@ namespace kv { const std::regex reg_kv("(\"([^=\"]*)\")|([^=\\s]+)"); + template + T tryGetValue(std::map map, const char* key, T defaultValue) { + if (!map.count(key)) return defaultValue; + return static_cast(::atof(key)); + } + class DataBlock { public: diff --git a/MCDV/vmf.hpp b/MCDV/vmf.hpp index 003accd..3064cb9 100644 --- a/MCDV/vmf.hpp +++ b/MCDV/vmf.hpp @@ -94,6 +94,12 @@ namespace vmf_parse { namespace vmf { + + enum team { + terrorist, + counter_terrorist + }; + struct BoundingBox { glm::vec3 NWU; glm::vec3 SEL; @@ -293,7 +299,7 @@ namespace vmf { glm::vec3 loc = glm::vec3(); if (block.Values.count("origin")) { //Start with hammer origin vmf_parse::Vector3f(block.Values["origin"], &loc); - ent.origin = glm::vec3(-loc.x, loc.z, loc.y); + ent.origin = glm::vec3(loc.x, loc.y, loc.z); } else if (block.GetFirstByName("solid") != NULL) { //Try to process it from solid //Get all solids @@ -434,6 +440,44 @@ namespace vmf { return list; } + /* Gets a list of entities with matching classname */ + std::vector findEntitiesByClassName(std::string classname) { + std::vector list; + for (auto && ent : this->entities) { + if (ent.classname == classname) { + list.push_back(&ent); + } + } + return list; + } + + glm::vec3* calculateSpawnLocation(team _team) { + + std::vector spawns = this->findEntitiesByClassName(_team == team::terrorist ? "info_player_terrorist" : "info_player_counterterrorist"); + + if (spawns.size() <= 0) return NULL; + + //Find lowest priority (highest) + int lowest = kv::tryGetValue(spawns[0]->keyValues, "priority", 0); + for (auto && s : spawns) { + int l = kv::tryGetValue(s->keyValues, "priority", 0); + lowest = l < lowest ? l : lowest; + } + + //Collect all spawns with that priority + glm::vec3* location = new glm::vec3(); + int c = 0; + for (auto && s : spawns) { + if (kv::tryGetValue(s->keyValues, "priority", 0) == lowest) { + *location += s->origin; c++; + } + } + + //avg + *location = *location / (float)c; + return location; + } + void ComputeGLMeshes() { auto start = std::chrono::high_resolution_clock::now(); -- 2.25.1