{"record":{"id":"cc934ad3c0a739f6","repo":"egametang/ET","slug":"buildpolydetail-could-not-triangulate-polygon-n","errorCode":null,"errorMessage":"buildPolyDetail: Could not triangulate polygon ({nverts}) verts).","messagePattern":"buildPolyDetail: Could not triangulate polygon \\((.+?)\\) verts\\)\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.recast/Scripts/Core/Share/Recast/RecastMeshDetail.cs","lineNumber":1000,"sourceCode":"            }\n\n            // If the polygon minimum extent is small (sliver or small triangle), do not try to add internal points.\n            if (minExtent < sampleDist * 2)\n            {\n                TriangulateHull(nverts, verts, nhull, hull, nin, tris);\n                return nverts;\n            }\n\n            // Tessellate the base mesh.\n            // We're using the triangulateHull instead of delaunayHull as it tends to\n            // create a bit better triangulation for long thin triangles when there\n            // are no internal points.\n            TriangulateHull(nverts, verts, nhull, hull, nin, tris);\n\n            if (tris.Count == 0)\n            {\n                // Could not triangulate the poly, make sure there is some valid data there.\n                throw new Exception(\"buildPolyDetail: Could not triangulate polygon (\" + nverts + \") verts).\");\n            }\n\n            if (sampleDist > 0)\n            {\n                // Create sample locations in a grid.\n                RcVec3f bmin = new RcVec3f();\n                RcVec3f bmax = new RcVec3f();\n                RcVec3f.Copy(ref bmin, @in, 0);\n                RcVec3f.Copy(ref bmax, @in, 0);\n                for (int i = 1; i < nin; ++i)\n                {\n                    bmin.Min(@in, i * 3);\n                    bmax.Max(@in, i * 3);\n                }\n\n                int x0 = (int)Math.Floor(bmin.x / sampleDist);\n                int x1 = (int)Math.Ceiling(bmax.x / sampleDist);\n                int z0 = (int)Math.Floor(bmin.z / sampleDist);","sourceCodeStart":982,"sourceCodeEnd":1018,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.recast/Scripts/Core/Share/Recast/RecastMeshDetail.cs#L982-L1018","documentation":"buildPolyDetail triangulates the polygon hull via TriangulateHull; if the resulting triangle list is empty, the polygon could not be triangulated at all. Rather than emit empty/garbage detail data, it throws so the caller knows the detail mesh is incomplete.","triggerScenarios":"TriangulateHull(nverts, verts, nhull, hull, nin, tris) leaves tris.Count == 0. Happens with degenerate input polygons: zero-area hulls, collinear vertices, nverts < 3 after hull construction, or malformed contour winding.","commonSituations":"Corrupted or degenerate input contour passed to rcBuildPolyMeshDetail; very thin sliver polygons from aggressive simplification; near-zero-area regions produced by bad input geometry (duplicate vertices, T-junctions); floating-point edge cases at extremely small scales.","solutions":["Sanitize input geometry before baking: remove duplicate/colinear vertices and zero-area polygons.","Increase contour simplification tolerance only if geometry tolerates it; lower it if slivers appear.","Check the upstream polymesh for degenerate polygons (nverts < 3) and skip them before detail build.","Scale the world so coordinates aren't extremely small (avoids FP degeneracy in triangulation)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Skip degenerate polygons before detail build\nforeach (var poly in mesh.polys) {\n    int uniqueVerts = CountUniqueVerts(poly, nvp);\n    if (uniqueVerts < 3 || IsDegenerate(poly, nvp)) {\n        Log.Warning(\"Skipping degenerate polygon in detail build\");\n        continue;\n    }\n}","typeGuard":null,"tryCatchPattern":"// Wrap per-polygon detail build so one bad poly doesn't kill the whole mesh\nforeach (var poly in polys) {\n    try { rcBuildPolyMeshDetail(...); }\n    catch (Exception e) when (e.Message.Contains(\"Could not triangulate\")) {\n        Log.Warning($\"Skipping un-triangulatable poly: {e.Message}\");\n        continue;\n    }\n}","preventionTips":["Sanitize input geometry: remove duplicate/colinear vertices before baking.","Validate base polymesh polygons aren't degenerate before detail build.","Avoid extremely small world scales that cause FP triangulation issues."],"tags":["recast","navmesh","detail-mesh","triangulation","degenerate-geometry"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}