From c0f4b96c585c75e0bf5c5043b4e858ae4cf9f0b1 Mon Sep 17 00:00:00 2001 From: namreeb Date: Thu, 25 Jul 2024 14:26:54 -1000 Subject: [PATCH 1/2] Allow Z query for global WMO maps --- MapViewer/main.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/MapViewer/main.cpp b/MapViewer/main.cpp index 5c916e2..75bc4c5 100644 --- a/MapViewer/main.cpp +++ b/MapViewer/main.cpp @@ -621,6 +621,10 @@ void ChangeMap(const std::string& cn) // 300.f); gRenderer->m_camera.LookAt(avgX, avgY, avgZ); } + // enable these buttons even for a global WMO map to allow for Z queries + gControls->Enable(Controls::PositionX, true); + gControls->Enable(Controls::PositionY, true); + // if the loaded map has no ADTs, but instead a global WMO, load it now, // including all mesh tiles if (auto const wmo = gMap->GetGlobalWmoInstance()) @@ -647,8 +651,6 @@ void ChangeMap(const std::string& cn) gRenderer->m_camera.Move(cx + 300.f, cy + 300.f, cz + 300.f); gRenderer->m_camera.LookAt(cx, cy, cz); - gControls->Enable(Controls::PositionX, false); - gControls->Enable(Controls::PositionY, false); gControls->Enable(Controls::Load, false); if (gNavMesh) @@ -663,11 +665,7 @@ void ChangeMap(const std::string& cn) } } else - { - gControls->Enable(Controls::PositionX, true); - gControls->Enable(Controls::PositionY, true); gControls->Enable(Controls::Load, true); - } } void LoadPositionFromGUI() @@ -794,7 +792,7 @@ void SearchZValues() for (auto const h : output) { result << h << "\n"; - gRenderer->AddSphere({posX, posY, h}, 0.25f); + gRenderer->AddSphere({posX, posY, h}, 0.75f); } MessageBoxA(nullptr, result.str().c_str(), "Z Search Results", 0); From e6b8a0e0b73f480f6d706f303035c67d146599a2 Mon Sep 17 00:00:00 2001 From: namreeb Date: Thu, 25 Jul 2024 14:27:38 -1000 Subject: [PATCH 2/2] Correctly locate tiles in global WMO maps --- pathfind/Map.cpp | 44 ++++++++++++++++++++++++-------------------- pathfind/Map.hpp | 6 ++++++ 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/pathfind/Map.cpp b/pathfind/Map.cpp index 55405f3..d9e4d9f 100644 --- a/pathfind/Map.cpp +++ b/pathfind/Map.cpp @@ -95,7 +95,8 @@ float random_between_0_and_1() { namespace pathfind { Map::Map(const std::filesystem::path& dataPath, const std::string& mapName) - : m_dataPath(dataPath), m_bvhLoader(dataPath), m_mapName(mapName) + : m_dataPath(dataPath), m_bvhLoader(dataPath), m_mapName(mapName), + m_globalWmoOriginX(0.f), m_globalWmoOriginY(0.f) { utility::BinaryStream in(m_dataPath / (mapName + ".map")); @@ -114,6 +115,8 @@ Map::Map(const std::filesystem::path& dataPath, const std::string& mapName) if (hasTerrain) { + m_hasADTs = true; + std::uint8_t has_adt[MeshSettings::Adts * MeshSettings::Adts / 8]; in.ReadBytes(has_adt, sizeof(has_adt)); @@ -204,6 +207,7 @@ Map::Map(const std::filesystem::path& dataPath, const std::string& mapName) else { // no ADTs in this map + m_hasADTs = false; ::memset(m_hasADT, 0, sizeof(m_hasADT)); WmoFileInstance globalWmo; @@ -239,6 +243,9 @@ Map::Map(const std::filesystem::path& dataPath, const std::string& mapName) (globalWmo.m_bounds.MaxCorner.Y - globalWmo.m_bounds.MinCorner.Y) / MeshSettings::TileSize)); + m_globalWmoOriginX = globalWmo.m_bounds.MaxCorner.X; + m_globalWmoOriginY = globalWmo.m_bounds.MaxCorner.Y; + params.maxTiles = tileWidth * tileHeight; params.maxPolys = 1 << DT_POLY_BITS; @@ -409,14 +416,7 @@ std::shared_ptr Map::EnsureWmoModelLoaded(const std::string& mpq_path) bool Map::HasADTs() const { - for (int y = 0; y < MeshSettings::Adts; ++y) - for (int x = 0; x < MeshSettings::Adts; ++x) { - if (m_hasADT[x][y]) { - return true; - } - } - - return false; + return m_hasADTs; } bool Map::HasADT(int x, int y) const @@ -588,7 +588,15 @@ const Tile* Map::GetTile(float x, float y) const { // find the tile corresponding to this (x, y) int tileX, tileY; - math::Convert::WorldToTile({x, y, 0.f}, tileX, tileY); + + // maps based on a global WMO have their tiles positioned differently + if (HasADTs()) + math::Convert::WorldToTile({x, y, 0.f}, tileX, tileY); + else + { + tileX = (m_globalWmoOriginY - y) / MeshSettings::TileSize; + tileY = (m_globalWmoOriginX - x) / MeshSettings::TileSize; + } auto const tile = m_tiles.find({tileX, tileY}); @@ -900,19 +908,16 @@ bool Map::ZoneAndArea(const math::Vertex& position, unsigned int& zone, unsigned int& area) const { // find the tile corresponding to this (x, y) - int tileX, tileY; - math::Convert::WorldToTile({position.X, position.Y, 0.f}, tileX, tileY); + auto const tile = GetTile(position.X, position.Y); - auto const tile = m_tiles.find({tileX, tileY}); - - if (tile == m_tiles.end()) + if (!tile) return false; - std::vector tiles {tile->second.get()}; + std::vector tiles {tile}; math::Ray ray { {position.X, position.Y, position.Z}, - {position.X, position.Y, tile->second->m_bounds.getMinimum().Z}}; + {position.X, position.Y, tile->m_bounds.getMinimum().Z}}; unsigned int localZone, localArea; auto const rayResult = RayCast(ray, tiles, false, &localZone, &localArea); @@ -924,9 +929,8 @@ bool Map::ZoneAndArea(const math::Vertex& position, unsigned int& zone, float adtHeight; unsigned int adtZone, adtArea; - auto const adtResult = - GetADTHeight(tile->second.get(), position.X, position.Y, adtHeight, - &adtZone, &adtArea); + auto const adtResult = GetADTHeight(tile, position.X, position.Y, adtHeight, + &adtZone, &adtArea); if (adtResult && adtHeight > ray.GetHitPoint().Z) { diff --git a/pathfind/Map.hpp b/pathfind/Map.hpp index b25ded0..1bb5951 100644 --- a/pathfind/Map.hpp +++ b/pathfind/Map.hpp @@ -41,6 +41,12 @@ class Map BVH m_bvhLoader; + // this is false when the map is based on a global wmo + bool m_hasADTs; + + float m_globalWmoOriginX; + float m_globalWmoOriginY; + bool m_hasADT[MeshSettings::Adts][MeshSettings::Adts]; bool m_loadedADT[MeshSettings::Adts][MeshSettings::Adts];