@par @note If the mesh data is to be used to construct a Detour navigation mesh, then the upper limit must be retricted to <= #DT_VERTS_PER_POLYGON. @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig
| 987 | /// |
| 988 | /// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig |
| 989 | bool rcBuildPolyMesh(rcContext* ctx, const rcContourSet& cset, const int nvp, rcPolyMesh& mesh) |
| 990 | { |
| 991 | rcAssert(ctx); |
| 992 | |
| 993 | rcScopedTimer timer(ctx, RC_TIMER_BUILD_POLYMESH); |
| 994 | |
| 995 | rcVcopy(mesh.bmin, cset.bmin); |
| 996 | rcVcopy(mesh.bmax, cset.bmax); |
| 997 | mesh.cs = cset.cs; |
| 998 | mesh.ch = cset.ch; |
| 999 | mesh.borderSize = cset.borderSize; |
| 1000 | mesh.maxEdgeError = cset.maxError; |
| 1001 | |
| 1002 | int maxVertices = 0; |
| 1003 | int maxTris = 0; |
| 1004 | int maxVertsPerCont = 0; |
| 1005 | for (int i = 0; i < cset.nconts; ++i) |
| 1006 | { |
| 1007 | // Skip null contours. |
| 1008 | if (cset.conts[i].nverts < 3) continue; |
| 1009 | maxVertices += cset.conts[i].nverts; |
| 1010 | maxTris += cset.conts[i].nverts - 2; |
| 1011 | maxVertsPerCont = rcMax(maxVertsPerCont, cset.conts[i].nverts); |
| 1012 | } |
| 1013 | |
| 1014 | if (maxVertices >= 0xfffe) |
| 1015 | { |
| 1016 | ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Too many vertices %d.", maxVertices); |
| 1017 | return false; |
| 1018 | } |
| 1019 | |
| 1020 | rcScopedDelete<unsigned char> vflags((unsigned char*)rcAlloc(sizeof(unsigned char)*maxVertices, RC_ALLOC_TEMP)); |
| 1021 | if (!vflags) |
| 1022 | { |
| 1023 | ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'vflags' (%d).", maxVertices); |
| 1024 | return false; |
| 1025 | } |
| 1026 | memset(vflags, 0, maxVertices); |
| 1027 | |
| 1028 | mesh.verts = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVertices*3, RC_ALLOC_PERM); |
| 1029 | if (!mesh.verts) |
| 1030 | { |
| 1031 | ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices); |
| 1032 | return false; |
| 1033 | } |
| 1034 | mesh.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxTris*nvp*2, RC_ALLOC_PERM); |
| 1035 | if (!mesh.polys) |
| 1036 | { |
| 1037 | ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.polys' (%d).", maxTris*nvp*2); |
| 1038 | return false; |
| 1039 | } |
| 1040 | mesh.regs = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxTris, RC_ALLOC_PERM); |
| 1041 | if (!mesh.regs) |
| 1042 | { |
| 1043 | ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.regs' (%d).", maxTris); |
| 1044 | return false; |
| 1045 | } |
| 1046 | mesh.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxTris, RC_ALLOC_PERM); |
no test coverage detected