diff --git a/src/naveditor/Editor_TileMesh.cpp b/src/naveditor/Editor_TileMesh.cpp index adca116e..e3576fb2 100644 --- a/src/naveditor/Editor_TileMesh.cpp +++ b/src/naveditor/Editor_TileMesh.cpp @@ -1267,8 +1267,9 @@ unsigned char* Editor_TileMesh::buildTileMesh(const int tx, const int ty, const params.verts = m_pmesh->verts; params.vertCount = m_pmesh->nverts; params.polys = m_pmesh->polys; - params.polyAreas = m_pmesh->areas; params.polyFlags = m_pmesh->flags; + params.polyAreas = m_pmesh->areas; + params.surfAreas = m_pmesh->surfa; params.polyCount = m_pmesh->npolys; params.nvp = m_pmesh->nvp; params.cellResolution = m_polyCellRes; diff --git a/src/thirdparty/recast/Detour/Include/DetourNavMesh.h b/src/thirdparty/recast/Detour/Include/DetourNavMesh.h index 863316aa..9cbc74c0 100644 --- a/src/thirdparty/recast/Detour/Include/DetourNavMesh.h +++ b/src/thirdparty/recast/Detour/Include/DetourNavMesh.h @@ -85,9 +85,6 @@ static const unsigned short DT_FIRST_USABLE_POLY_GROUP = 2; /// are even on the same (or connected) poly island before trying to compute a path). static const int DT_MIN_POLY_GROUP_COUNT = 3; -/// The cached poly surface area quantization factor. -static const float DT_POLY_AREA_QUANT_FACTOR = 0.01f; - /// The maximum number of traversal tables per navmesh that will be used for static pathing. static const int DT_MAX_TRAVERSE_TABLES = 5; @@ -268,13 +265,6 @@ struct dtPoly inline unsigned char getType() const { return areaAndtype >> 6; } }; -/// Calculates the surface area of the polygon. -/// @param[in] poly The polygon. -/// @param[in] verts The polygon vertices. -/// @return The total surface are of the polygon. -float dtCalcPolySurfaceArea(const dtPoly* poly, const float* verts); -unsigned short dtQuantPolySurfaceArea(const float area); - /// Defines the location of detail sub-mesh data within a dtMeshTile. struct dtPolyDetail { diff --git a/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h b/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h index 7db4a2f0..81908db6 100644 --- a/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h +++ b/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h @@ -36,6 +36,7 @@ struct dtNavMeshCreateParams const unsigned short* polys; ///< The polygon data. [Size: #polyCount * 2 * #nvp] const unsigned short* polyFlags; ///< The user defined flags assigned to each polygon. [Size: #polyCount] const unsigned char* polyAreas; ///< The user defined area ids assigned to each polygon. [Size: #polyCount] + const unsigned short* surfAreas; ///< The surface area amount for each polygon. [Size: #polyCount] int polyCount; ///< Number of polygons in the mesh. [Limit: >= 1] int nvp; ///< Maximum number of vertices per polygon. [Limit: >= 3] int cellResolution; ///< The resolution of the diamond cell grid [Limit: >= 1] diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp index 6d450f75..1bbb282c 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp @@ -1868,28 +1868,6 @@ unsigned char dtQuantLinkDistance(const float distance) return (unsigned char)(rdMathRoundf(distance * DT_TRAVERSE_DIST_QUANT_FACTOR)); } -float dtCalcPolySurfaceArea(const dtPoly* poly, const float* verts) -{ - float polyArea = 0.0f; - - // Only run if we have more than 2 verts since poly's with 2 verts - // (off-mesh connections) don't have any surface area. - for (int i = 2; i < poly->vertCount; ++i) - { - const float* va = &verts[poly->verts[0]*3]; - const float* vb = &verts[poly->verts[i]*3]; - const float* vc = &verts[poly->verts[i-1]*3]; - polyArea += rdTriArea2D(va,vb,vc); - } - - return polyArea; -} - -unsigned short dtQuantPolySurfaceArea(const float area) -{ - return (unsigned short)rdMathRoundf(area * DT_POLY_AREA_QUANT_FACTOR); -} - float dtCalcOffMeshRefYaw(const float* spos, const float* epos) { const float dx = epos[0]-spos[0]; diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp index 53756c2f..31aaf184 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp @@ -960,10 +960,11 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, for (int i = 0; i < params->polyCount; ++i) { dtPoly* p = &navPolys[i]; - p->vertCount = 0; p->flags = params->polyFlags[i]; + p->vertCount = 0; p->setArea(params->polyAreas[i]); p->setType(DT_POLYTYPE_GROUND); + p->surfaceArea = params->surfAreas[i]; for (int j = 0; j < nvp; ++j) { if (src[j] == MESH_NULL_IDX) break; @@ -992,8 +993,6 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, p->vertCount++; } rdVscale(p->center, p->center, 1 / (float)(p->vertCount)); - p->surfaceArea = dtQuantPolySurfaceArea(dtCalcPolySurfaceArea(p,navVerts)); - src += nvp*2; } diff --git a/src/thirdparty/recast/Recast/Include/Recast.h b/src/thirdparty/recast/Recast/Include/Recast.h index 502291af..95874480 100644 --- a/src/thirdparty/recast/Recast/Include/Recast.h +++ b/src/thirdparty/recast/Recast/Include/Recast.h @@ -457,6 +457,7 @@ struct rcPolyMesh unsigned short* regs; ///< The region id assigned to each polygon. [Length: #maxpolys] unsigned short* flags; ///< The user defined flags for each polygon. [Length: #maxpolys] unsigned char* areas; ///< The area id assigned to each polygon. [Length: #maxpolys] + unsigned short* surfa; ///< The surface area amount for each polygon. [Length: #maxpolys] int nverts; ///< The number of vertices. int npolys; ///< The number of polygons. int maxpolys; ///< The number of allocated polygons. @@ -633,6 +634,10 @@ static const unsigned char RC_NULL_AREA = 0; /// recognized by some steps in the build process. static const unsigned char RC_WALKABLE_AREA = 63; +/// The cached polygon surface area quantization factor. +/// @see rcPolyMesh::surfa +static const float RC_POLY_SURFAREA_QUANT_FACTOR = 0.01f; + /// The value returned by #rcGetCon if the specified direction is not connected /// to another span. (Has no neighbor.) static const int RC_NOT_CONNECTED = 0x3f; diff --git a/src/thirdparty/recast/Recast/Source/Recast.cpp b/src/thirdparty/recast/Recast/Source/Recast.cpp index 3592d947..503b450b 100644 --- a/src/thirdparty/recast/Recast/Source/Recast.cpp +++ b/src/thirdparty/recast/Recast/Source/Recast.cpp @@ -225,6 +225,7 @@ rcPolyMesh::rcPolyMesh() , regs() , flags() , areas() +, surfa() , nverts() , npolys() , maxpolys() @@ -245,6 +246,7 @@ rcPolyMesh::~rcPolyMesh() rdFree(regs); rdFree(flags); rdFree(areas); + rdFree(surfa); } rcPolyMeshDetail* rcAllocPolyMeshDetail() diff --git a/src/thirdparty/recast/Recast/Source/RecastMesh.cpp b/src/thirdparty/recast/Recast/Source/RecastMesh.cpp index fe195f18..9a6d55a7 100644 --- a/src/thirdparty/recast/Recast/Source/RecastMesh.cpp +++ b/src/thirdparty/recast/Recast/Source/RecastMesh.cpp @@ -1110,6 +1110,12 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMe ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.areas' (%d).", maxTris); return false; } + mesh.surfa = (unsigned short*)rdAlloc(sizeof(unsigned short)*maxTris, RD_ALLOC_PERM); + if (!mesh.surfa) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.surfa' (%d).", maxTris); + return false; + } mesh.nverts = 0; mesh.npolys = 0; @@ -1355,6 +1361,36 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMe } } + // Calculate polygon surface area's. + for (int i = 0; i < mesh.npolys; i++) + { + const unsigned short* p = &mesh.polys[i*2*nvp]; + unsigned short vi[3]; + float fv[3][2]; + float polyArea = 0.0f; + for (int j = 2; j < nvp; ++j) + { + if (p[j] == RC_MESH_NULL_IDX) + break; + + vi[0] = p[0]; + vi[1] = p[j]; + vi[2] = p[j-1]; + + for (int k = 0; k < 3; k++) + { + const unsigned short* v = &mesh.verts[vi[k]*3]; + + fv[k][0] = mesh.bmin[0] + v[0]*mesh.cs; + fv[k][1] = mesh.bmin[1] + v[1]*mesh.cs; + } + + polyArea += rdTriArea2D(fv[0], fv[1], fv[2]); + } + + mesh.surfa[i] = (unsigned short)rdMathRoundf(polyArea*RC_POLY_SURFAREA_QUANT_FACTOR); + } + // Just allocate the mesh flags array. The user is responsible to fill it. mesh.flags = (unsigned short*)rdAlloc(sizeof(unsigned short)*mesh.npolys, RD_ALLOC_PERM); if (!mesh.flags)