diff --git a/RecastDemo/Include/InputGeom.h b/RecastDemo/Include/InputGeom.h index 93d93cea..3a95a79f 100644 --- a/RecastDemo/Include/InputGeom.h +++ b/RecastDemo/Include/InputGeom.h @@ -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 offmeshConnVerts; + std::vector offmeshConnRadius; + std::vector offmeshConnBidirectional; + std::vector offmeshConnArea; + std::vector offmeshConnFlags; + std::vector offmeshConnId; ///@} std::vector 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(); + } }; diff --git a/RecastDemo/Source/InputGeom.cpp b/RecastDemo/Source/InputGeom.cpp index dc46b8b1..0b8e30bb 100644 --- a/RecastDemo/Source/InputGeom.cpp +++ b/RecastDemo/Source/InputGeom.cpp @@ -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(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(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(); diff --git a/RecastDemo/Source/Sample_SoloMesh.cpp b/RecastDemo/Source/Sample_SoloMesh.cpp index 10579e9c..0fc65c43 100644 --- a/RecastDemo/Source/Sample_SoloMesh.cpp +++ b/RecastDemo/Source/Sample_SoloMesh.cpp @@ -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(inputGeometry->offmeshConnArea.size()); params.walkableHeight = agentHeight; params.walkableRadius = agentRadius; params.walkableClimb = agentMaxClimb; diff --git a/RecastDemo/Source/Sample_TempObstacles.cpp b/RecastDemo/Source/Sample_TempObstacles.cpp index ae8fdf8b..cfc81f2f 100644 --- a/RecastDemo/Source/Sample_TempObstacles.cpp +++ b/RecastDemo/Source/Sample_TempObstacles.cpp @@ -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(inputGeometry->offmeshConnArea.size()); } } }; diff --git a/RecastDemo/Source/Sample_TileMesh.cpp b/RecastDemo/Source/Sample_TileMesh.cpp index 074a461a..53e25968 100644 --- a/RecastDemo/Source/Sample_TileMesh.cpp +++ b/RecastDemo/Source/Sample_TileMesh.cpp @@ -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(inputGeometry->offmeshConnArea.size()); params.walkableHeight = agentHeight; params.walkableRadius = agentRadius; params.walkableClimb = agentMaxClimb; diff --git a/RecastDemo/Source/Tool_OffMeshConnection.cpp b/RecastDemo/Source/Tool_OffMeshConnection.cpp index 0bacc519..999d8224 100644 --- a/RecastDemo/Source/Tool_OffMeshConnection.cpp +++ b/RecastDemo/Source/Tool_OffMeshConnection.cpp @@ -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 verts = geom->offmeshConnVerts; + for (int i = 0; i < static_cast(geom->offmeshConnId.size()) * 2; ++i) { const float distance = rcVdistSqr(rayHitPos, &verts[i * 3]); if (distance < nearestDist)