Recast: add ability to dump traverse link details

Detour dump utilities.
This commit is contained in:
Kawe Mazidjatari 2024-08-09 14:18:33 +02:00
parent 35b465d6c6
commit c63061419a
5 changed files with 194 additions and 8 deletions

View File

@ -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"
)

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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<unsigned char> distanceVec;
rdTempVector<float> 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;
}