mirror of
https://github.com/recastnavigation/recastnavigation.git
synced 2026-11-01 13:35:43 +00:00
Use vectors to store offmesh connection data rather than arrays
This commit is contained in:
@@ -105,14 +105,12 @@ public:
|
||||
|
||||
/// @name Off-Mesh connections.
|
||||
///@{
|
||||
static constexpr int MAX_OFFMESH_CONNECTIONS = 256;
|
||||
float offMeshConVerts[MAX_OFFMESH_CONNECTIONS * 3 * 2];
|
||||
float offMeshConRads[MAX_OFFMESH_CONNECTIONS];
|
||||
unsigned char offMeshConDirs[MAX_OFFMESH_CONNECTIONS];
|
||||
unsigned char offMeshConAreas[MAX_OFFMESH_CONNECTIONS];
|
||||
unsigned short offMeshConFlags[MAX_OFFMESH_CONNECTIONS];
|
||||
unsigned int offMeshConId[MAX_OFFMESH_CONNECTIONS];
|
||||
int offMeshConCount = 0;
|
||||
std::vector<float> offmeshConnVerts;
|
||||
std::vector<float> offmeshConnRadius;
|
||||
std::vector<unsigned char> offmeshConnBidirectional;
|
||||
std::vector<unsigned char> offmeshConnArea;
|
||||
std::vector<unsigned short> offmeshConnFlags;
|
||||
std::vector<unsigned int> offmeshConnId;
|
||||
///@}
|
||||
|
||||
std::vector<ConvexVolume> convexVolumes;
|
||||
@@ -151,5 +149,15 @@ private:
|
||||
bool loadMesh(rcContext* ctx, const std::string& filepath);
|
||||
bool loadGeomSet(rcContext* ctx, const std::string& filepath);
|
||||
bool loadGeomSet(rcContext* ctx, char* buffer, size_t bufferLen);
|
||||
|
||||
void clearOffmeshConnections()
|
||||
{
|
||||
offmeshConnVerts.clear();
|
||||
offmeshConnRadius.clear();
|
||||
offmeshConnBidirectional.clear();
|
||||
offmeshConnArea.clear();
|
||||
offmeshConnFlags.clear();
|
||||
offmeshConnId.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -367,7 +367,8 @@ bool InputGeom::loadMesh(rcContext* ctx, const std::string& filepath)
|
||||
}
|
||||
|
||||
filename = filepath;
|
||||
offMeshConCount = 0;
|
||||
clearOffmeshConnections();
|
||||
|
||||
convexVolumes.clear();
|
||||
|
||||
mesh.reset();
|
||||
@@ -406,7 +407,7 @@ bool InputGeom::loadGeomSet(rcContext* ctx, const std::string& filepath)
|
||||
|
||||
bool InputGeom::loadGeomSet(rcContext* ctx, char* buffer, size_t bufferLen)
|
||||
{
|
||||
offMeshConCount = 0;
|
||||
clearOffmeshConnections();
|
||||
convexVolumes.clear();
|
||||
|
||||
char* src = buffer;
|
||||
@@ -437,32 +438,26 @@ bool InputGeom::loadGeomSet(rcContext* ctx, char* buffer, size_t bufferLen)
|
||||
else if (row[0] == 'c')
|
||||
{
|
||||
// Off-mesh connection
|
||||
if (offMeshConCount < MAX_OFFMESH_CONNECTIONS)
|
||||
{
|
||||
float* v = &offMeshConVerts[offMeshConCount * 3 * 2];
|
||||
int bidir;
|
||||
int area;
|
||||
int flags;
|
||||
float rad;
|
||||
sscanf(
|
||||
row + 1,
|
||||
"%f %f %f %f %f %f %f %d %d %d",
|
||||
&v[0],
|
||||
&v[1],
|
||||
&v[2],
|
||||
&v[3],
|
||||
&v[4],
|
||||
&v[5],
|
||||
&rad,
|
||||
&bidir,
|
||||
&area,
|
||||
&flags);
|
||||
offMeshConRads[offMeshConCount] = rad;
|
||||
offMeshConDirs[offMeshConCount] = (unsigned char)bidir;
|
||||
offMeshConAreas[offMeshConCount] = (unsigned char)area;
|
||||
offMeshConFlags[offMeshConCount] = (unsigned short)flags;
|
||||
offMeshConCount++;
|
||||
}
|
||||
float startPos[3];
|
||||
float endPos[3];
|
||||
int bidir;
|
||||
int area;
|
||||
int flags;
|
||||
float rad;
|
||||
sscanf(
|
||||
row + 1,
|
||||
"%f %f %f %f %f %f %f %d %d %d",
|
||||
&startPos[0],
|
||||
&startPos[1],
|
||||
&startPos[2],
|
||||
&endPos[0],
|
||||
&endPos[1],
|
||||
&endPos[2],
|
||||
&rad,
|
||||
&bidir,
|
||||
&area,
|
||||
&flags);
|
||||
addOffMeshConnection(startPos, endPos, rad, bidir, area, flags);
|
||||
}
|
||||
else if (row[0] == 'v')
|
||||
{
|
||||
@@ -588,13 +583,14 @@ bool InputGeom::saveGeomSet(const BuildSettings* settings)
|
||||
}
|
||||
|
||||
// Store off-mesh links.
|
||||
int offMeshConCount = static_cast<int>(offmeshConnId.size());
|
||||
for (int i = 0; i < offMeshConCount; ++i)
|
||||
{
|
||||
const float* v = &offMeshConVerts[i * 3 * 2];
|
||||
const float rad = offMeshConRads[i];
|
||||
const int bidir = offMeshConDirs[i];
|
||||
const int area = offMeshConAreas[i];
|
||||
const int flags = offMeshConFlags[i];
|
||||
const float* v = &offmeshConnVerts[i * 3 * 2];
|
||||
const float rad = offmeshConnRadius[i];
|
||||
const int bidir = offmeshConnBidirectional[i];
|
||||
const int area = offmeshConnArea[i];
|
||||
const int flags = offmeshConnFlags[i];
|
||||
fprintf(fp, "c %f %f %f %f %f %f %f %d %d %d\n", v[0], v[1], v[2], v[3], v[4], v[5], rad, bidir, area, flags);
|
||||
}
|
||||
|
||||
@@ -667,32 +663,25 @@ void InputGeom::addOffMeshConnection(
|
||||
unsigned char area,
|
||||
unsigned short flags)
|
||||
{
|
||||
if (offMeshConCount >= MAX_OFFMESH_CONNECTIONS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float* v = &offMeshConVerts[offMeshConCount * 3 * 2];
|
||||
offMeshConRads[offMeshConCount] = rad;
|
||||
offMeshConDirs[offMeshConCount] = bidir;
|
||||
offMeshConAreas[offMeshConCount] = area;
|
||||
offMeshConFlags[offMeshConCount] = flags;
|
||||
offMeshConId[offMeshConCount] = 1000 + offMeshConCount;
|
||||
offmeshConnVerts.resize(offmeshConnVerts.size() + 3 * 2);
|
||||
float* v = &offmeshConnVerts[offmeshConnVerts.size() - 3 * 2];
|
||||
rcVcopy(&v[0], spos);
|
||||
rcVcopy(&v[3], epos);
|
||||
offMeshConCount++;
|
||||
offmeshConnRadius.emplace_back(rad);
|
||||
offmeshConnBidirectional.emplace_back(bidir);
|
||||
offmeshConnArea.emplace_back(area);
|
||||
offmeshConnFlags.emplace_back(flags);
|
||||
offmeshConnId.emplace_back(1000 + (offmeshConnArea.size() - 1));
|
||||
}
|
||||
|
||||
void InputGeom::deleteOffMeshConnection(int i)
|
||||
{
|
||||
offMeshConCount--;
|
||||
float* src = &offMeshConVerts[offMeshConCount * 3 * 2];
|
||||
float* dst = &offMeshConVerts[i * 3 * 2];
|
||||
rcVcopy(&dst[0], &src[0]);
|
||||
rcVcopy(&dst[3], &src[3]);
|
||||
offMeshConRads[i] = offMeshConRads[offMeshConCount];
|
||||
offMeshConDirs[i] = offMeshConDirs[offMeshConCount];
|
||||
offMeshConAreas[i] = offMeshConAreas[offMeshConCount];
|
||||
offMeshConFlags[i] = offMeshConFlags[offMeshConCount];
|
||||
offmeshConnVerts.erase(offmeshConnVerts.begin() + 3 * 2 * i);
|
||||
offmeshConnRadius.erase(offmeshConnRadius.begin() + i);
|
||||
offmeshConnBidirectional.erase(offmeshConnBidirectional.begin() + i);
|
||||
offmeshConnArea.erase(offmeshConnArea.begin() + i);
|
||||
offmeshConnFlags.erase(offmeshConnFlags.begin() + i);
|
||||
offmeshConnId.erase(offmeshConnId.begin() + i);
|
||||
}
|
||||
|
||||
void InputGeom::drawOffMeshConnections(duDebugDraw* dd, bool highlight)
|
||||
@@ -702,9 +691,10 @@ void InputGeom::drawOffMeshConnections(duDebugDraw* dd, bool highlight)
|
||||
dd->depthMask(false);
|
||||
|
||||
dd->begin(DU_DRAW_LINES, 2.0f);
|
||||
int offMeshConCount = static_cast<int>(offmeshConnId.size());
|
||||
for (int i = 0; i < offMeshConCount; ++i)
|
||||
{
|
||||
float* v = &offMeshConVerts[i * 3 * 2];
|
||||
float* v = &offmeshConnVerts[i * 3 * 2];
|
||||
|
||||
dd->vertex(v[0], v[1], v[2], baseColor);
|
||||
dd->vertex(v[0], v[1] + 0.2f, v[2], baseColor);
|
||||
@@ -712,12 +702,12 @@ void InputGeom::drawOffMeshConnections(duDebugDraw* dd, bool highlight)
|
||||
dd->vertex(v[3], v[4], v[5], baseColor);
|
||||
dd->vertex(v[3], v[4] + 0.2f, v[5], baseColor);
|
||||
|
||||
duAppendCircle(dd, v[0], v[1] + 0.1f, v[2], offMeshConRads[i], baseColor);
|
||||
duAppendCircle(dd, v[3], v[4] + 0.1f, v[5], offMeshConRads[i], baseColor);
|
||||
duAppendCircle(dd, v[0], v[1] + 0.1f, v[2], offmeshConnRadius[i], baseColor);
|
||||
duAppendCircle(dd, v[3], v[4] + 0.1f, v[5], offmeshConnRadius[i], baseColor);
|
||||
|
||||
if (highlight)
|
||||
{
|
||||
duAppendArc(dd, v[0], v[1], v[2], v[3], v[4], v[5], 0.25f, (offMeshConDirs[i] & 1) ? 0.6f : 0.0f, 0.6f, conColor);
|
||||
duAppendArc(dd, v[0], v[1], v[2], v[3], v[4], v[5], 0.25f, (offmeshConnBidirectional[i] & 1) ? 0.6f : 0.0f, 0.6f, conColor);
|
||||
}
|
||||
}
|
||||
dd->end();
|
||||
|
||||
@@ -701,13 +701,13 @@ bool Sample_SoloMesh::build()
|
||||
params.detailVertsCount = detailMesh->nverts;
|
||||
params.detailTris = detailMesh->tris;
|
||||
params.detailTriCount = detailMesh->ntris;
|
||||
params.offMeshConVerts = inputGeometry->offMeshConVerts;
|
||||
params.offMeshConRad = inputGeometry->offMeshConRads;
|
||||
params.offMeshConDir = inputGeometry->offMeshConDirs;
|
||||
params.offMeshConAreas = inputGeometry->offMeshConAreas;
|
||||
params.offMeshConFlags = inputGeometry->offMeshConFlags;
|
||||
params.offMeshConUserID = inputGeometry->offMeshConId;
|
||||
params.offMeshConCount = inputGeometry->offMeshConCount;
|
||||
params.offMeshConVerts = inputGeometry->offmeshConnVerts.data();
|
||||
params.offMeshConRad = inputGeometry->offmeshConnRadius.data();
|
||||
params.offMeshConDir = inputGeometry->offmeshConnBidirectional.data();
|
||||
params.offMeshConAreas = inputGeometry->offmeshConnArea.data();
|
||||
params.offMeshConFlags = inputGeometry->offmeshConnFlags.data();
|
||||
params.offMeshConUserID = inputGeometry->offmeshConnId.data();
|
||||
params.offMeshConCount = static_cast<int>(inputGeometry->offmeshConnArea.size());
|
||||
params.walkableHeight = agentHeight;
|
||||
params.walkableRadius = agentRadius;
|
||||
params.walkableClimb = agentMaxClimb;
|
||||
|
||||
@@ -463,13 +463,13 @@ struct MeshProcess : dtTileCacheMeshProcess
|
||||
// Pass in off-mesh connections.
|
||||
if (inputGeometry)
|
||||
{
|
||||
params->offMeshConVerts = inputGeometry->offMeshConVerts;
|
||||
params->offMeshConRad = inputGeometry->offMeshConRads;
|
||||
params->offMeshConDir = inputGeometry->offMeshConDirs;
|
||||
params->offMeshConAreas = inputGeometry->offMeshConAreas;
|
||||
params->offMeshConFlags = inputGeometry->offMeshConFlags;
|
||||
params->offMeshConUserID = inputGeometry->offMeshConId;
|
||||
params->offMeshConCount = inputGeometry->offMeshConCount;
|
||||
params->offMeshConVerts = inputGeometry->offmeshConnVerts.data();
|
||||
params->offMeshConRad = inputGeometry->offmeshConnRadius.data();
|
||||
params->offMeshConDir = inputGeometry->offmeshConnBidirectional.data();
|
||||
params->offMeshConAreas = inputGeometry->offmeshConnArea.data();
|
||||
params->offMeshConFlags = inputGeometry->offmeshConnFlags.data();
|
||||
params->offMeshConUserID = inputGeometry->offmeshConnId.data();
|
||||
params->offMeshConCount = static_cast<int>(inputGeometry->offmeshConnArea.size());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1191,13 +1191,13 @@ unsigned char* Sample_TileMesh::buildTileMesh(
|
||||
params.detailVertsCount = detailPolyMesh->nverts;
|
||||
params.detailTris = detailPolyMesh->tris;
|
||||
params.detailTriCount = detailPolyMesh->ntris;
|
||||
params.offMeshConVerts = inputGeometry->offMeshConVerts;
|
||||
params.offMeshConRad = inputGeometry->offMeshConRads;
|
||||
params.offMeshConDir = inputGeometry->offMeshConDirs;
|
||||
params.offMeshConAreas = inputGeometry->offMeshConAreas;
|
||||
params.offMeshConFlags = inputGeometry->offMeshConFlags;
|
||||
params.offMeshConUserID = inputGeometry->offMeshConId;
|
||||
params.offMeshConCount = inputGeometry->offMeshConCount;
|
||||
params.offMeshConVerts = inputGeometry->offmeshConnVerts.data();
|
||||
params.offMeshConRad = inputGeometry->offmeshConnRadius.data();
|
||||
params.offMeshConDir = inputGeometry->offmeshConnBidirectional.data();
|
||||
params.offMeshConAreas = inputGeometry->offmeshConnArea.data();
|
||||
params.offMeshConFlags = inputGeometry->offmeshConnFlags.data();
|
||||
params.offMeshConUserID = inputGeometry->offmeshConnId.data();
|
||||
params.offMeshConCount = static_cast<int>(inputGeometry->offmeshConnArea.size());
|
||||
params.walkableHeight = agentHeight;
|
||||
params.walkableRadius = agentRadius;
|
||||
params.walkableClimb = agentMaxClimb;
|
||||
|
||||
@@ -70,8 +70,8 @@ void OffMeshConnectionTool::onClick(const float* /*rayStartPos*/, const float* r
|
||||
// Find nearest link end-point
|
||||
float nearestDist = FLT_MAX;
|
||||
int nearestIndex = -1;
|
||||
const float* verts = geom->offMeshConVerts;
|
||||
for (int i = 0; i < geom->offMeshConCount * 2; ++i)
|
||||
const std::vector<float> verts = geom->offmeshConnVerts;
|
||||
for (int i = 0; i < static_cast<int>(geom->offmeshConnId.size()) * 2; ++i)
|
||||
{
|
||||
const float distance = rcVdistSqr(rayHitPos, &verts[i * 3]);
|
||||
if (distance < nearestDist)
|
||||
|
||||
Reference in New Issue
Block a user