From c63061419a24e566cdcd7e5d4b75610c4d4568ed Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:18:33 +0200 Subject: [PATCH] Recast: add ability to dump traverse link details Detour dump utilities. --- src/thirdparty/recast/CMakeLists.txt | 3 + .../recast/DebugUtils/Include/DetourDump.h | 8 + .../recast/DebugUtils/Include/FileIO.h | 31 ++++ .../recast/DebugUtils/Include/RecastDump.h | 9 +- .../recast/DebugUtils/Source/DetourDump.cpp | 151 ++++++++++++++++++ 5 files changed, 194 insertions(+), 8 deletions(-) create mode 100644 src/thirdparty/recast/DebugUtils/Include/DetourDump.h create mode 100644 src/thirdparty/recast/DebugUtils/Include/FileIO.h create mode 100644 src/thirdparty/recast/DebugUtils/Source/DetourDump.cpp diff --git a/src/thirdparty/recast/CMakeLists.txt b/src/thirdparty/recast/CMakeLists.txt index fcec4ede..8b7e9601 100644 --- a/src/thirdparty/recast/CMakeLists.txt +++ b/src/thirdparty/recast/CMakeLists.txt @@ -39,13 +39,16 @@ start_sources() add_sources( SOURCE_GROUP "Source" "DebugUtils/Source/DebugDraw.cpp" "DebugUtils/Source/DetourDebugDraw.cpp" + "DebugUtils/Source/DetourDump.cpp" "DebugUtils/Source/RecastDebugDraw.cpp" "DebugUtils/Source/RecastDump.cpp" ) add_sources( SOURCE_GROUP "Include" + "DebugUtils/Include/FileIO.h" "DebugUtils/Include/DebugDraw.h" "DebugUtils/Include/DetourDebugDraw.h" + "DebugUtils/Include/DetourDump.h" "DebugUtils/Include/RecastDebugDraw.h" "DebugUtils/Include/RecastDump.h" ) diff --git a/src/thirdparty/recast/DebugUtils/Include/DetourDump.h b/src/thirdparty/recast/DebugUtils/Include/DetourDump.h new file mode 100644 index 00000000..11f03a70 --- /dev/null +++ b/src/thirdparty/recast/DebugUtils/Include/DetourDump.h @@ -0,0 +1,8 @@ +#ifndef DETOUR_DUMP_H +#define DETOUR_DUMP_H + +#include "FileIO.h" + +bool duDumpTraverseLinkDetail(const dtNavMesh& mesh, const dtNavMeshQuery* query, const int traverseType, duFileIO* const io); + +#endif // DETOUR_DUMP_H diff --git a/src/thirdparty/recast/DebugUtils/Include/FileIO.h b/src/thirdparty/recast/DebugUtils/Include/FileIO.h new file mode 100644 index 00000000..8d22e58f --- /dev/null +++ b/src/thirdparty/recast/DebugUtils/Include/FileIO.h @@ -0,0 +1,31 @@ +// +// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#ifndef FILE_IO_H +#define FILE_IO_H + +struct duFileIO +{ + virtual ~duFileIO() = 0; + virtual bool isWriting() const = 0; + virtual bool isReading() const = 0; + virtual bool write(const void* ptr, const size_t size) = 0; + virtual bool read(void* ptr, const size_t size) = 0; +}; + +#endif // FILE_IO_H diff --git a/src/thirdparty/recast/DebugUtils/Include/RecastDump.h b/src/thirdparty/recast/DebugUtils/Include/RecastDump.h index 6a722fda..5b28b259 100644 --- a/src/thirdparty/recast/DebugUtils/Include/RecastDump.h +++ b/src/thirdparty/recast/DebugUtils/Include/RecastDump.h @@ -19,14 +19,7 @@ #ifndef RECAST_DUMP_H #define RECAST_DUMP_H -struct duFileIO -{ - virtual ~duFileIO() = 0; - virtual bool isWriting() const = 0; - virtual bool isReading() const = 0; - virtual bool write(const void* ptr, const size_t size) = 0; - virtual bool read(void* ptr, const size_t size) = 0; -}; +#include "FileIO.h" bool duDumpPolyMeshToObj(struct rcPolyMesh& pmesh, duFileIO* io); bool duDumpPolyMeshDetailToObj(struct rcPolyMeshDetail& dmesh, duFileIO* io); diff --git a/src/thirdparty/recast/DebugUtils/Source/DetourDump.cpp b/src/thirdparty/recast/DebugUtils/Source/DetourDump.cpp new file mode 100644 index 00000000..52e5870d --- /dev/null +++ b/src/thirdparty/recast/DebugUtils/Source/DetourDump.cpp @@ -0,0 +1,151 @@ +#include "Shared/Include/SharedMath.h" +#include "Shared/Include/SharedCommon.h" +#include "Detour/Include/DetourNavMesh.h" +#include "Detour/Include/DetourNavMeshQuery.h" +#include "DebugUtils/Include/DetourDump.h" + +bool duDumpTraverseLinkDetail(const dtNavMesh& mesh, const dtNavMeshQuery* query, const int traverseType, duFileIO* const io) +{ + if (!io) + { + printf("duDumpTraverseLinkDetail: input IO is null.\n"); + return false; + } + if (!io->isWriting()) + { + printf("duDumpTraverseLinkDetail: input IO not writing.\n"); + return false; + } + + char buf[2048]; + int bufCount = 0; + + rdTempVector distanceVec; + rdTempVector slopeVec; + + int totTraverseLinkCount = 0; + const int tileCount = mesh.getTileCount(); + + for (int i = 0; i < tileCount; i++) + { + const dtMeshTile* tile = mesh.getTile(i); + const dtMeshHeader* header = tile->header; + + bool writeTileDetail = false; + + for (int j = 0; j < header->polyCount; ++j) + { + const dtPoly* startPoly = &tile->polys[j]; + + if (startPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) // Skip off-mesh links. + continue; + + if (tile->links[j].ref == 0) + continue; + + // Iterate through links in the poly. + for (int k = startPoly->firstLink; k != DT_NULL_LINK; k = tile->links[k].next) + { + const dtLink* link = &tile->links[k]; + + // Skip "normal" links (non-jumping ones). + if (link->traverseType == DT_NULL_TRAVERSE_TYPE) + continue; + + // Filter out anything not matching input. + if (traverseType != -1 && link->traverseType != traverseType) + continue; + + const dtPoly* endPoly; + const dtMeshTile* endTile; + + if (dtStatusFailed(mesh.getTileAndPolyByRef(link->ref, &endTile, &endPoly))) + continue; + + if (endPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) // Skip off-mesh links. + continue; + + if (!writeTileDetail) + { + io->write("{\n", 2); + + bufCount = snprintf(buf, sizeof(buf), "\ttile: %d\n", i); + io->write(buf, bufCount); + + writeTileDetail = true; + } + + io->write("\t{\n", 3); + + float startPos[3]; + float endPos[3]; + + query->getEdgeMidPoint(mesh.getPolyRefBase(tile) | (dtPolyRef)j, link->ref, startPos); + query->getEdgeMidPoint(link->ref, mesh.getPolyRefBase(tile) | (dtPolyRef)j, endPos); + + // note(amos): the lowest slope is the highest slope in reverse + // as we always have a reverse link; store the absolute value!! + const float slopeAngle = rdMathFabsf(rdCalcSlopeAngle(startPos, endPos)); + + //const bool hasReverseLink = link->reverseLink != DT_NULL_TRAVERSE_REVERSE_LINK; + + bufCount = snprintf(buf, sizeof(buf), "\t\tlink: %d\n", k); + io->write(buf, bufCount); + bufCount = snprintf(buf, sizeof(buf), "\t\tstartPos: <%g, %g, %g>\n", startPos[0], startPos[1], startPos[2]); + io->write(buf, bufCount); + bufCount = snprintf(buf, sizeof(buf), "\t\tendPos: <%g, %g, %g>\n", endPos[0], endPos[1], endPos[2]); + io->write(buf, bufCount); + bufCount = snprintf(buf, sizeof(buf), "\t\tslopeAngle: %g\n", slopeAngle); + io->write(buf, bufCount); + bufCount = snprintf(buf, sizeof(buf), "\t\ttraverseType: %hhu\n", link->traverseType); + io->write(buf, bufCount); + bufCount = snprintf(buf, sizeof(buf), "\t\ttraverseDist: %hhu\n", link->traverseDist); + io->write(buf, bufCount); + bufCount = snprintf(buf, sizeof(buf), "\t\treverseLink: %hu\n", link->reverseLink); + io->write(buf, bufCount); + + io->write("\t}\n", 3); + + distanceVec.push_back(link->traverseDist); + slopeVec.push_back(slopeAngle); + + totTraverseLinkCount++; + } + } + + if (writeTileDetail) + io->write("}\n", 2); + } + + std::sort(distanceVec.begin(), distanceVec.end()); + std::sort(slopeVec.begin(), slopeVec.end()); + + if (distanceVec.size() > 0) + { + const int lowestDist = distanceVec[0]; + const int highestDist = distanceVec[distanceVec.size()-1]; + + bufCount = snprintf(buf, sizeof(buf), "lowestDist: %d\n", lowestDist); + io->write(buf, bufCount); + + bufCount = snprintf(buf, sizeof(buf), "highestDist: %d\n", highestDist); + io->write(buf, bufCount); + } + + if (slopeVec.size() > 0) + { + const float lowestSlope = slopeVec[0]; + const float highestSlope = slopeVec[slopeVec.size()-1]; + + bufCount = snprintf(buf, sizeof(buf), "lowestSlope: %g\n", lowestSlope); + io->write(buf, bufCount); + + bufCount = snprintf(buf, sizeof(buf), "highestSlope: %g\n", highestSlope); + io->write(buf, bufCount); + } + + bufCount = snprintf(buf, sizeof(buf), "totalLinkCount: %d\n", totTraverseLinkCount); + io->write(buf, bufCount); + + return true; +}