diff --git a/src/thirdparty/recast/Recast/Include/Recast.h b/src/thirdparty/recast/Recast/Include/Recast.h index 6a612c73..364800ca 100644 --- a/src/thirdparty/recast/Recast/Include/Recast.h +++ b/src/thirdparty/recast/Recast/Include/Recast.h @@ -934,6 +934,17 @@ bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf); /// @returns True if the operation completed successfully. bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf); +/// Helper function to offset voncex polygons for rcMarkConvexPolyArea. +/// @ingroup recast +/// @param[in] verts The vertices of the polygon [Form: (x, y, z) * @p nverts] +/// @param[in] nverts The number of vertices in the polygon. +/// @param[in] offset How much to offset the polygon by. [Units: wu] +/// @param[out] outVerts The offset vertices (should hold up to 2 * @p nverts) [Form: (x, y, z) * return value] +/// @param[in] maxOutVerts The max number of vertices that can be stored to @p outVerts. +/// @returns Number of vertices in the offset polygon or 0 if too few vertices in @p outVerts. +int rcOffsetPoly(const float* verts, const int nverts, const float offset, + float* outVerts, const int maxOutVerts); + /// Applies an area id to all spans within the specified bounding box. (AABB) /// @ingroup recast /// @param[in,out] ctx The build context to use during the operation. @@ -961,17 +972,6 @@ void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts, unsigned short flags, unsigned char areaId, rcCompactHeightfield& chf); -/// Helper function to offset voncex polygons for rcMarkConvexPolyArea. -/// @ingroup recast -/// @param[in] verts The vertices of the polygon [Form: (x, y, z) * @p nverts] -/// @param[in] nverts The number of vertices in the polygon. -/// @param[in] offset How much to offset the polygon by. [Units: wu] -/// @param[out] outVerts The offset vertices (should hold up to 2 * @p nverts) [Form: (x, y, z) * return value] -/// @param[in] maxOutVerts The max number of vertices that can be stored to @p outVerts. -/// @returns Number of vertices in the offset polygon or 0 if too few vertices in @p outVerts. -int rcOffsetPoly(const float* verts, const int nverts, const float offset, - float* outVerts, const int maxOutVerts); - /// Applies the area id to all spans within the specified cylinder. /// @ingroup recast /// @param[in,out] ctx The build context to use during the operation. diff --git a/src/thirdparty/recast/Recast/Source/RecastArea.cpp b/src/thirdparty/recast/Recast/Source/RecastArea.cpp index 5aacfdc2..e8139cee 100644 --- a/src/thirdparty/recast/Recast/Source/RecastArea.cpp +++ b/src/thirdparty/recast/Recast/Source/RecastArea.cpp @@ -302,6 +302,83 @@ bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf) return true; } +int rcOffsetPoly(const float* verts, const int nverts, const float offset, + float* outVerts, const int maxOutVerts) +{ + const float MITER_LIMIT = 1.20f; + + int n = 0; + + for (int i = 0; i < nverts; i++) + { + const int a = (i+nverts-1) % nverts; + const int b = i; + const int c = (i+1) % nverts; + const float* va = &verts[a*3]; + const float* vb = &verts[b*3]; + const float* vc = &verts[c*3]; + float dx0 = vb[0] - va[0]; + float dy0 = vb[1] - va[1]; + float d0 = dx0*dx0 + dy0*dy0; + if (d0 > RD_EPS) + { + d0 = 1.0f/rdMathSqrtf(d0); + dx0 *= d0; + dy0 *= d0; + } + float dx1 = vc[0] - vb[0]; + float dy1 = vc[1] - vb[1]; + float d1 = dx1*dx1 + dy1*dy1; + if (d1 > RD_EPS) + { + d1 = 1.0f/rdMathSqrtf(d1); + dx1 *= d1; + dy1 *= d1; + } + const float dlx0 = -dy0; + const float dly0 = dx0; + const float dlx1 = -dy1; + const float dly1 = dx1; + float cross = dx1*dy0 - dx0*dy1; + float dmx = (dlx0 + dlx1) * 0.5f; + float dmy = (dly0 + dly1) * 0.5f; + float dmr2 = dmx*dmx + dmy*dmy; + bool bevel = dmr2 * MITER_LIMIT*MITER_LIMIT < 1.0f; + if (dmr2 > RD_EPS) + { + const float scale = 1.0f / dmr2; + dmx *= scale; + dmy *= scale; + } + + if (bevel && cross < 0.0f) + { + if (n+2 > maxOutVerts) + return 0; + float d = (1.0f - (dx0*dx1 + dy0*dy1))*0.5f; + outVerts[n*3+0] = vb[0] + (-dlx0+dx0*d)*offset; + outVerts[n*3+1] = vb[1] + (-dly0+dy0*d)*offset; + outVerts[n*3+2] = vb[2]; + n++; + outVerts[n*3+0] = vb[0] + (-dlx1-dx1*d)*offset; + outVerts[n*3+1] = vb[1] + (-dly1-dy1*d)*offset; + outVerts[n*3+2] = vb[2]; + n++; + } + else + { + if (n+1 > maxOutVerts) + return 0; + outVerts[n*3+0] = vb[0] - dmx*offset; + outVerts[n*3+1] = vb[1] - dmy*offset; + outVerts[n*3+2] = vb[2]; + n++; + } + } + + return n; +} + /// @par /// /// The value of spacial parameters are in world units. @@ -428,83 +505,6 @@ void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts, } } -int rcOffsetPoly(const float* verts, const int nverts, const float offset, - float* outVerts, const int maxOutVerts) -{ - const float MITER_LIMIT = 1.20f; - - int n = 0; - - for (int i = 0; i < nverts; i++) - { - const int a = (i+nverts-1) % nverts; - const int b = i; - const int c = (i+1) % nverts; - const float* va = &verts[a*3]; - const float* vb = &verts[b*3]; - const float* vc = &verts[c*3]; - float dx0 = vb[0] - va[0]; - float dy0 = vb[1] - va[1]; - float d0 = dx0*dx0 + dy0*dy0; - if (d0 > RD_EPS) - { - d0 = 1.0f/rdMathSqrtf(d0); - dx0 *= d0; - dy0 *= d0; - } - float dx1 = vc[0] - vb[0]; - float dy1 = vc[1] - vb[1]; - float d1 = dx1*dx1 + dy1*dy1; - if (d1 > RD_EPS) - { - d1 = 1.0f/rdMathSqrtf(d1); - dx1 *= d1; - dy1 *= d1; - } - const float dlx0 = -dy0; - const float dly0 = dx0; - const float dlx1 = -dy1; - const float dly1 = dx1; - float cross = dx1*dy0 - dx0*dy1; - float dmx = (dlx0 + dlx1) * 0.5f; - float dmy = (dly0 + dly1) * 0.5f; - float dmr2 = dmx*dmx + dmy*dmy; - bool bevel = dmr2 * MITER_LIMIT*MITER_LIMIT < 1.0f; - if (dmr2 > RD_EPS) - { - const float scale = 1.0f / dmr2; - dmx *= scale; - dmy *= scale; - } - - if (bevel && cross < 0.0f) - { - if (n+2 > maxOutVerts) - return 0; - float d = (1.0f - (dx0*dx1 + dy0*dy1))*0.5f; - outVerts[n*3+0] = vb[0] + (-dlx0+dx0*d)*offset; - outVerts[n*3+1] = vb[1] + (-dly0+dy0*d)*offset; - outVerts[n*3+2] = vb[2]; - n++; - outVerts[n*3+0] = vb[0] + (-dlx1-dx1*d)*offset; - outVerts[n*3+1] = vb[1] + (-dly1-dy1*d)*offset; - outVerts[n*3+2] = vb[2]; - n++; - } - else - { - if (n+1 > maxOutVerts) - return 0; - outVerts[n*3+0] = vb[0] - dmx*offset; - outVerts[n*3+1] = vb[1] - dmy*offset; - outVerts[n*3+2] = vb[2]; - n++; - } - } - - return n; -} - /// @par ///