From e428a4a0626ac4c0044b8905266d0085243b2885 Mon Sep 17 00:00:00 2001 From: Terri00 Date: Fri, 22 Mar 2019 00:05:01 +0000 Subject: [PATCH] vvd vertex rotation fix, custom model support coverage. --- MCDV/MCDV.vcxproj | 1 + MCDV/MCDV.vcxproj.filters | 3 + MCDV/main.cpp | 5 +- MCDV/main2.cpp | 12 +-- MCDV/sample_stuff/de_tavr_test.vmx | 143 ++++++++++++----------------- MCDV/vmf.hpp | 60 +++++++++--- MCDV/vtx.hpp | 8 +- MCDV/vvd.hpp | 8 ++ 8 files changed, 130 insertions(+), 110 deletions(-) diff --git a/MCDV/MCDV.vcxproj b/MCDV/MCDV.vcxproj index dd31353..4d66790 100644 --- a/MCDV/MCDV.vcxproj +++ b/MCDV/MCDV.vcxproj @@ -147,6 +147,7 @@ + diff --git a/MCDV/MCDV.vcxproj.filters b/MCDV/MCDV.vcxproj.filters index 1fae28b..0c9174c 100644 --- a/MCDV/MCDV.vcxproj.filters +++ b/MCDV/MCDV.vcxproj.filters @@ -146,6 +146,9 @@ Header Files\valve + + Header Files\valve + diff --git a/MCDV/main.cpp b/MCDV/main.cpp index 9a449be..cc3a5c8 100644 --- a/MCDV/main.cpp +++ b/MCDV/main.cpp @@ -427,11 +427,14 @@ int app(int argc, const char** argv) { std::cout << "Rendering props\n"; shader_depth.setFloat("write_cover", 1.0f); for (auto && s_prop : vmf_main.props) { + if (vmf_main.modelCache[s_prop.modelID] == NULL) continue; // Skip uncanched / errored models. This shouldn't happen if the vmf references everything normally and all files exist. + model = glm::mat4(); - model = glm::translate(model, s_prop.origin); + model = glm::translate(model, s_prop.origin); // Position model = glm::rotate(model, glm::radians(s_prop.rotation.y), glm::vec3(0, 1, 0)); // Yaw model = glm::rotate(model, glm::radians(s_prop.rotation.x), glm::vec3(0, 0, 1)); // ROOOOOLLLLL model = glm::rotate(model, -glm::radians(s_prop.rotation.z), glm::vec3(1, 0, 0)); // Pitch + model = glm::scale(model, glm::vec3(s_prop.unifromScale)); // Scale shader_depth.setMatrix("model", model); vmf_main.modelCache[s_prop.modelID]->Draw(); diff --git a/MCDV/main2.cpp b/MCDV/main2.cpp index ed37d9d..a586adb 100644 --- a/MCDV/main2.cpp +++ b/MCDV/main2.cpp @@ -2,15 +2,13 @@ #ifdef entry_point_testing -#include "vpk.hpp" - -int main() -{ - - vpk::index test("D:/SteamLibrary/steamapps/common/Counter-Strike Global Offensive/csgo/pak01_dir.vpk"); - +#include +#include +#include +int main(){ + system("PAUSE"); return 0; diff --git a/MCDV/sample_stuff/de_tavr_test.vmx b/MCDV/sample_stuff/de_tavr_test.vmx index 506c5df..27b337e 100644 --- a/MCDV/sample_stuff/de_tavr_test.vmx +++ b/MCDV/sample_stuff/de_tavr_test.vmx @@ -2,7 +2,7 @@ versioninfo { "editorversion" "400" "editorbuild" "8075" - "mapversion" "130" + "mapversion" "145" "formatversion" "100" "prefab" "0" } @@ -56,7 +56,7 @@ viewsettings world { "id" "1" - "mapversion" "130" + "mapversion" "145" "classname" "worldspawn" "detailmaterial" "detail/detailsprites" "detailvbsp" "detail.vbsp" @@ -1685,83 +1685,6 @@ world } } solid - { - "id" "185" - side - { - "id" "597" - "plane" "(-272 672 96) (-272 800 96) (-144 800 96)" - "material" "RYAN_DEV/PURE_ORANGE2" - "uaxis" "[1 0 0 -64] 0.25" - "vaxis" "[0 -1 0 0] 0.25" - "rotation" "0" - "lightmapscale" "16" - "smoothing_groups" "0" - } - side - { - "id" "596" - "plane" "(-272 800 16) (-272 672 16) (-144 672 16)" - "material" "RYAN_DEV/PURE_ORANGE2" - "uaxis" "[1 0 0 -64] 0.25" - "vaxis" "[0 -1 0 0] 0.25" - "rotation" "0" - "lightmapscale" "16" - "smoothing_groups" "0" - } - side - { - "id" "595" - "plane" "(-272 672 16) (-272 800 16) (-272 800 96)" - "material" "RYAN_DEV/PURE_ORANGE2" - "uaxis" "[0 1 0 0] 0.25" - "vaxis" "[0 0 -1 0] 0.25" - "rotation" "0" - "lightmapscale" "16" - "smoothing_groups" "0" - } - side - { - "id" "594" - "plane" "(-144 800 16) (-144 672 16) (-144 672 96)" - "material" "RYAN_DEV/PURE_ORANGE2" - "uaxis" "[0 1 0 0] 0.25" - "vaxis" "[0 0 -1 0] 0.25" - "rotation" "0" - "lightmapscale" "16" - "smoothing_groups" "0" - } - side - { - "id" "593" - "plane" "(-272 800 16) (-144 800 16) (-144 800 96)" - "material" "RYAN_DEV/PURE_ORANGE2" - "uaxis" "[1 0 0 -64] 0.25" - "vaxis" "[0 0 -1 0] 0.25" - "rotation" "0" - "lightmapscale" "16" - "smoothing_groups" "0" - } - side - { - "id" "592" - "plane" "(-144 672 16) (-272 672 16) (-272 672 96)" - "material" "RYAN_DEV/PURE_ORANGE2" - "uaxis" "[1 0 0 -64] 0.25" - "vaxis" "[0 0 -1 0] 0.25" - "rotation" "0" - "lightmapscale" "16" - "smoothing_groups" "0" - } - editor - { - "color" "0 175 108" - "visgroupid" "16" - "visgroupshown" "1" - "visgroupautoshown" "1" - } - } - solid { "id" "40" side @@ -2855,10 +2778,35 @@ world } } entity +{ + "id" "1185" + "classname" "prop_static" + "angles" "0 0 0" + "fademindist" "-1" + "fadescale" "1" + "model" "models/props_castle/stonestair.mdl" + "renderamt" "255" + "rendercolor" "255 255 255" + "skin" "0" + "solid" "6" + "uniformscale" "1" + "origin" "-560 704 16" + editor + { + "color" "255 255 0" + "visgroupid" "14" + "visgroupid" "9" + "visgroupid" "16" + "visgroupshown" "1" + "visgroupautoshown" "1" + "logicalpos" "[0 0]" + } +} +entity { "id" "681" "classname" "prop_static" - "angles" "44.7565 317.939 -61.0452" + "angles" "0 0 0" "fademindist" "-1" "fadescale" "1" "model" "models/props/de_nuke/truck_nuke.mdl" @@ -2867,7 +2815,7 @@ entity "skin" "0" "solid" "6" "uniformscale" "1" - "origin" "-480 752 0" + "origin" "-640 320 0" editor { "color" "255 255 0" @@ -2890,10 +2838,12 @@ entity "skin" "0" "solid" "6" "uniformscale" "1" - "origin" "-608 416 16" + "origin" "-336 768 16" editor { "color" "255 255 0" + "visgroupid" "14" + "visgroupid" "9" "visgroupid" "16" "visgroupshown" "1" "visgroupautoshown" "1" @@ -2912,8 +2862,8 @@ entity "rendercolor" "255 255 255" "skin" "0" "solid" "6" - "uniformscale" "1" - "origin" "-272 368 16" + "uniformscale" "2" + "origin" "-208 240 16" editor { "color" "255 255 0" @@ -2947,6 +2897,31 @@ entity } } entity +{ + "id" "1015" + "classname" "prop_static" + "angles" "0 0 0" + "fademindist" "-1" + "fadescale" "1" + "model" "models/terri/monaco/vehicles/f1.mdl" + "renderamt" "255" + "rendercolor" "255 255 255" + "skin" "0" + "solid" "6" + "uniformscale" "1" + "origin" "-624 560 16" + editor + { + "color" "255 255 0" + "visgroupid" "14" + "visgroupid" "9" + "visgroupid" "16" + "visgroupshown" "1" + "visgroupautoshown" "1" + "logicalpos" "[0 0]" + } +} +entity { "id" "484" "classname" "tar_config" diff --git a/MCDV/vmf.hpp b/MCDV/vmf.hpp index ddfedf3..e2f3962 100644 --- a/MCDV/vmf.hpp +++ b/MCDV/vmf.hpp @@ -26,6 +26,8 @@ #include +#include + namespace vmf_parse { //Pass Vector3 bool Vector3f(std::string str, glm::vec3* vec) @@ -329,9 +331,6 @@ namespace vmf { //Process entities list std::vector EntitiesList = data.headNode.GetAllByName("entity"); for (auto && block : EntitiesList) { - - //if (block.Values["classname"] != "prop_static") continue; //Skip anything else than prop static for now - //Check wether origin can be resolved for entity if ((block.GetFirstByName("solid") == NULL) && (block.Values.count("origin") == 0)) { std::cout << "Origin could not be resolved for entity with ID " << block.Values["id"]; continue; @@ -342,6 +341,13 @@ namespace vmf { ent.ID = (int)::atof(block.Values["id"].c_str()); ent.keyValues = block.Values; + //Gather up the visgroups + kv::DataBlock* editorValues = block.GetFirstByName("editor"); + int viscount = -1; + while (editorValues->Values.count("visgroupid" + (++viscount > 0 ? std::to_string(viscount) : ""))) { + ent.visgroupids.push_back(std::stoi(editorValues->Values["visgroupid" + (viscount > 0 ? std::to_string(viscount) : "")])); + } + glm::vec3 loc = glm::vec3(); if (block.Values.count("origin")) { //Start with hammer origin vmf_parse::Vector3f(block.Values["origin"], &loc); @@ -378,9 +384,9 @@ namespace vmf { solid.faces.push_back(side); } - kv::DataBlock* editorValues = block.GetFirstByName("editor"); - //Gather up the visgroups + //TODO: move this dupe code away from solid processing + // add reference to source entity, to provide link to visgroups. int viscount = -1; while (editorValues->Values.count("visgroupid" + (++viscount > 0 ? std::to_string(viscount) : ""))) { solid.visgroupids.push_back(std::stoi(editorValues->Values["visgroupid" + (viscount > 0 ? std::to_string(viscount) : "")])); @@ -477,8 +483,7 @@ namespace vmf { return list; } - bool testIfInVisgroup(Entity* ent, std::string visgroup) - { + bool testIfInVisgroup(Entity* ent, std::string visgroup){ for (auto && esvid : ent->visgroupids) { if (this->visgroups[esvid] == visgroup) { return true; @@ -601,26 +606,25 @@ namespace vmf { void populateModelDict(std::string pakDir) { vpk::index pakIndex(pakDir + "pak01_dir.vpk"); // Open index + std::cout << "Populating model dictionary & caching model data...\n"; + unsigned int mIndex = 0; for (auto && ent : this->findEntitiesByClassName("prop_static")) { std::string modelName = kv::tryGetStringValue(ent->keyValues, "model", "error.mdl"); std::string baseName = split(modelName, ".")[0]; if (this->modelDict.count(modelName)) continue; // Skip already defined models - std::cout << "Processing model: " << modelName << "\n"; - this->modelDict.insert({ modelName, mIndex++ }); // Add to our list // Generate our model data and wham it into the model cache vpk::vEntry* vEntry = pakIndex.find(modelName); if (vEntry != NULL) { - std::cout << "Found model in pakfile: " << modelName << "\n"; - vpk::vEntry* vtx_entry = pakIndex.find(baseName + ".dx90.vtx"); vpk::vEntry* vvd_entry = pakIndex.find(baseName + ".vvd"); if (vtx_entry == NULL || vvd_entry == NULL) { std::cout << "Couldn't find vtx/vvd model data\n"; + this->modelCache.push_back(NULL); continue; } @@ -633,7 +637,7 @@ namespace vmf { // Read vvd std::string vvdPakDir = pakDir + "pak01_" + sutil::pad0(std::to_string(vvd_entry->entryInfo.ArchiveIndex), 3) + ".vpk"; std::ifstream vvdPakFile(vvdPakDir, std::ios::in | std::ios::binary); - vvd_data vvd(&vvdPakFile, vvd_entry->entryInfo.EntryOffset, true); + vvd_data vvd(&vvdPakFile, vvd_entry->entryInfo.EntryOffset, false); vvdPakFile.close(); // GENERATE MESH TING @@ -651,14 +655,42 @@ namespace vmf { this->modelCache.push_back(m); } else { - std::cout << "Searching for model in gamedir...\n"; + std::string vtxFile = pakDir + baseName + ".dx90.vtx"; + std::string vvdFile = pakDir + baseName + ".vvd"; + + // Check that custom model data actually exists + if (_access_s(vtxFile.c_str(), 0) != 0 || _access_s(vvdFile.c_str(), 0) != 0) { + std::cout << "Couldn't find vtx/vvd model data\n"; + this->modelCache.push_back(NULL); + continue; + } + + // Read vtx + vtx_mesh vtx(vtxFile); + + // Read vvd + vvd_data vvd(vvdFile); + + // GENERATE MESH TING + std::vector meshData; + for (auto && vert : vtx.vertexSequence) { + meshData.push_back(vvd.verticesLOD0[vert].m_vecPosition.x); + meshData.push_back(vvd.verticesLOD0[vert].m_vecPosition.y); + meshData.push_back(vvd.verticesLOD0[vert].m_vecPosition.z); + meshData.push_back(0); + meshData.push_back(0); + meshData.push_back(1); + } + + Mesh* m = new Mesh(meshData, MeshMode::POS_XYZ_NORMAL_XYZ); + this->modelCache.push_back(m); } } } void populatePropList(std::string visgroupfilter = "") { for (auto && prop : this->findEntitiesByClassName("prop_static")) { - //if (!this->testIfInVisgroup(prop, visgroupfilter)) continue; + if (!this->testIfInVisgroup(prop, visgroupfilter)) continue; std::string modelName = kv::tryGetStringValue(prop->keyValues, "model", "error.mdl"); diff --git a/MCDV/vtx.hpp b/MCDV/vtx.hpp index 321b6a9..6cb09b0 100644 --- a/MCDV/vtx.hpp +++ b/MCDV/vtx.hpp @@ -205,8 +205,9 @@ public: reader.seekg(MODEL.lodOffset - sizeof(vtx::ModelHeader), std::ios::cur); int abs_lod_base_offset = reader.tellg(); - for (int lod = 0; lod < MODEL.numLODs; lod++) - { + for (int lod = 0; lod < MODEL.numLODs; lod++){ + if (lod > 0) goto IL_EXIT; // Skip all the other lods for now + //Move to the current LOD header array item reader.seekg(abs_lod_base_offset); reader.seekg(lod * sizeof(vtx::ModelLODHeader), std::ios::cur); @@ -311,6 +312,7 @@ public: } } + IL_EXIT: __noop; //Dispose stream reader.close(); } @@ -462,8 +464,6 @@ public: } } } - - } IL_EXIT: __noop; } diff --git a/MCDV/vvd.hpp b/MCDV/vvd.hpp index 301d574..766fef6 100644 --- a/MCDV/vvd.hpp +++ b/MCDV/vvd.hpp @@ -80,6 +80,14 @@ public: VVD::Vertex vert; reader.read((char*)&vert, sizeof(vert)); + // THIS HURTS + // REAL BAD + // forgot to copy this... spent 9 hours trying to learning studiomdl. + // note to self: dont dupe your code. + // Do the sorce->opengl flipperoo + glm::vec3 temp = vert.m_vecPosition; + vert.m_vecPosition = glm::vec3(-temp.x, temp.z, temp.y); + this->verticesLOD0.push_back(vert); } -- 2.25.1