From 5d65fa4747c917230255e1420f5def1a60f4e6a7 Mon Sep 17 00:00:00 2001 From: "C. S." <76898260+Pentalimbed@users.noreply.github.com> Date: Fri, 13 Dec 2024 00:37:19 +0000 Subject: [PATCH] feat: support directly using xlodgen output in terrain shadows (#854) --- src/Features/TerrainShadows.cpp | 110 ++++++++++++++++++++------------ src/Features/TerrainShadows.h | 3 + 2 files changed, 71 insertions(+), 42 deletions(-) diff --git a/src/Features/TerrainShadows.cpp b/src/Features/TerrainShadows.cpp index 086ff8240..167711b07 100644 --- a/src/Features/TerrainShadows.cpp +++ b/src/Features/TerrainShadows.cpp @@ -5,8 +5,6 @@ #include "State.h" #include "Util.h" -#include - #include #include @@ -76,55 +74,83 @@ void TerrainShadows::ClearShaderCache() CompileComputeShaders(); } -void TerrainShadows::SetupResources() +void TerrainShadows::ParseHeightmapPath(std::filesystem::path p, bool xlodgen_style) { - logger::debug("Listing height maps..."); - { - std::filesystem::path texture_dir{ L"Data\\textures\\heightmaps\\" }; - for (auto const& dir_entry : std::filesystem::directory_iterator{ texture_dir }) { - auto filename = dir_entry.path().filename(); - if (filename.extension() != ".dds") - continue; + auto filename = p.filename(); + if (filename.extension() != ".dds") + return; + logger::debug("Found dds: {}", filename.string()); + + auto splitstr = pystring::split(filename.stem().string(), "."); + if (splitstr.size() != (xlodgen_style ? 9 : 10)) { + logger::debug("{} has incorrect number ({}) of fields", filename.string(), splitstr.size()); + return; + } + + bool middle_check = xlodgen_style ? ((splitstr[1] == "Terrain") && (splitstr[2] == "HeightMap")) : (splitstr[1] == "HeightMap"); + if (middle_check) { + HeightMapMetadata metadata; + try { + if (xlodgen_style) { + metadata.worldspace = splitstr[0]; + metadata.pos0.x = std::stoi(splitstr[3]) * 4096.f; + metadata.pos1.y = std::stoi(splitstr[4]) * 4096.f; + metadata.pos1.x = (std::stoi(splitstr[5]) + 1) * 4096.f; + metadata.pos0.y = (std::stoi(splitstr[6]) + 1) * 4096.f; + metadata.pos0.z = -32767 * 8.f; + metadata.pos1.z = 32767 * 8.f; + metadata.zRange.x = std::stoi(splitstr[7]) * 8.f; + metadata.zRange.y = std::stoi(splitstr[8]) * 8.f; + } else { + metadata.worldspace = splitstr[0]; + metadata.pos0.x = std::stoi(splitstr[2]) * 4096.f; + metadata.pos1.y = std::stoi(splitstr[3]) * 4096.f; + metadata.pos1.x = (std::stoi(splitstr[4]) + 1) * 4096.f; + metadata.pos0.y = (std::stoi(splitstr[5]) + 1) * 4096.f; + metadata.pos0.z = std::stoi(splitstr[6]) * 8.f; + metadata.pos1.z = std::stoi(splitstr[7]) * 8.f; + metadata.zRange.x = std::stoi(splitstr[8]) * 8.f; + metadata.zRange.y = std::stoi(splitstr[9]) * 8.f; + } + } catch (std::exception& e) { + logger::debug("Failed to parse {}. Error: {}", filename.string(), e.what()); + return; + } - logger::debug("Found dds: {}", filename.string()); + metadata.dir = p.parent_path().wstring(); + metadata.filename = filename.string(); - auto splitstr = pystring::split(filename.stem().string(), "."); + if (heightmaps.contains(metadata.worldspace)) + logger::warn("{} has more than one height maps!", metadata.worldspace); + heightmaps[metadata.worldspace] = metadata; + + logger::info("{} loaded.", filename.string()); + } else + logger::debug("{} has unknown type ({})", filename.string(), splitstr[1]); +} - if (splitstr.size() != 10) { - logger::warn("{} has incorrect number ({} instead of 10) of fields", filename.string(), splitstr.size()); +void TerrainShadows::SetupResources() +{ + logger::debug("Listing xLODGen height maps..."); + { + std::filesystem::path texture_dir{ L"Data\\textures\\Terrain\\" }; + for (auto const& dir_entry : std::filesystem::directory_iterator{ texture_dir }) { + auto dir_path = dir_entry.path(); + if (!std::filesystem::is_directory(dir_path)) continue; - } - if (splitstr[1] == "HeightMap") { - HeightMapMetadata metadata; - try { - metadata.worldspace = splitstr[0]; - metadata.pos0.x = std::stoi(splitstr[2]) * 4096.f; - metadata.pos1.y = std::stoi(splitstr[3]) * 4096.f; - metadata.pos1.x = (std::stoi(splitstr[4]) + 1) * 4096.f; - metadata.pos0.y = (std::stoi(splitstr[5]) + 1) * 4096.f; - metadata.pos0.z = std::stoi(splitstr[6]) * 8.f; - metadata.pos1.z = std::stoi(splitstr[7]) * 8.f; - metadata.zRange.x = std::stoi(splitstr[8]) * 8.f; - metadata.zRange.y = std::stoi(splitstr[9]) * 8.f; - } catch (std::exception& e) { - logger::warn("Failed to parse {}. Error: {}", filename.string(), e.what()); - continue; - } - - metadata.dir = dir_entry.path().parent_path().wstring(); - metadata.filename = filename.string(); - - if (heightmaps.contains(metadata.worldspace)) { - logger::warn("{} has more than one height maps!", metadata.worldspace); - } else { - heightmaps[metadata.worldspace] = metadata; - } - } else if (splitstr[1] != "AO" && splitstr[1] != "Cone") - logger::warn("{} has unknown type ({})", filename.string(), splitstr[1]); + for (auto const& sub_dir_entry : std::filesystem::directory_iterator{ dir_path }) + ParseHeightmapPath(sub_dir_entry.path(), true); } } + logger::debug("Listing height maps..."); + { + std::filesystem::path texture_dir{ L"Data\\textures\\heightmaps\\" }; + for (auto const& dir_entry : std::filesystem::directory_iterator{ texture_dir }) + ParseHeightmapPath(dir_entry.path(), false); + } + logger::debug("Creating constant buffers..."); { shadowUpdateCB = std::make_unique(ConstantBufferDesc()); diff --git a/src/Features/TerrainShadows.h b/src/Features/TerrainShadows.h index fa929b6f9..ec7b675c4 100644 --- a/src/Features/TerrainShadows.h +++ b/src/Features/TerrainShadows.h @@ -3,6 +3,8 @@ #include "Buffer.h" #include "Feature.h" +#include + struct TerrainShadows : public Feature { static TerrainShadows* GetSingleton() @@ -66,6 +68,7 @@ struct TerrainShadows : public Feature bool IsHeightMapReady(); virtual void SetupResources() override; + void ParseHeightmapPath(std::filesystem::path p, bool xlodgen_style); void CompileComputeShaders(); virtual void DrawSettings() override;