{"record":{"id":"5326b8f8e2a2d31f","repo":"egametang/ET","slug":"rcbuildpolymeshdetail-shrinking-triangle-count-fr","errorCode":null,"errorMessage":"rcBuildPolyMeshDetail: Shrinking triangle count from {ntris} to max {MAX_TRIS}","messagePattern":"rcBuildPolyMeshDetail: Shrinking triangle count from (.+?) to max (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.recast/Scripts/Core/Share/Recast/RecastMeshDetail.cs","lineNumber":1109,"sourceCode":"                    // Mark sample as added.\n                    samples[besti * 4 + 3] = 1;\n                    // Add the new sample point.\n                    RcVec3f.Copy(verts, nverts * 3, bestpt, 0);\n                    nverts++;\n\n                    // Create new triangulation.\n                    // TODO: Incremental add instead of full rebuild.\n                    DelaunayHull(ctx, nverts, verts, nhull, hull, tris);\n                }\n            }\n\n            int ntris = tris.Count / 4;\n            if (ntris > MAX_TRIS)\n            {\n                List<int> subList = tris.GetRange(0, MAX_TRIS * 4);\n                tris.Clear();\n                tris.AddRange(subList);\n                throw new Exception(\n                    \"rcBuildPolyMeshDetail: Shrinking triangle count from \" + ntris + \" to max \" + MAX_TRIS);\n            }\n\n            return nverts;\n        }\n\n        static void SeedArrayWithPolyCenter(RcTelemetry ctx, RcCompactHeightfield chf, int[] meshpoly, int poly, int npoly,\n            int[] verts, int bs, RcHeightPatch hp, List<int> array)\n        {\n            // Note: Reads to the compact heightfield are offset by border size (bs)\n            // since border size offset is already removed from the polymesh vertices.\n\n            int[] offset = { 0, 0, -1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, };\n\n            // Find cell closest to a poly vertex\n            int startCellX = 0, startCellY = 0, startSpanIndex = -1;\n            int dmin = RC_UNSET_HEIGHT;\n            for (int j = 0; j < npoly && dmin > 0; ++j)","sourceCodeStart":1091,"sourceCodeEnd":1127,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.recast/Scripts/Core/Share/Recast/RecastMeshDetail.cs#L1091-L1127","documentation":"rcBuildPolyMeshDetail caps the per-polygon detail triangle count at MAX_TRIS (255). If Delaunay triangulation yields more, it silently truncates the list to 255*4 ints and then throws to signal the truncation. The data is usable but the highest-detail triangles were dropped.","triggerScenarios":"After DelaunayHull rebuild, ntris = tris.Count/4 exceeds MAX_TRIS (255). The code takes a sub-range of the first 255 triangles and throws. This fires when a single polygon's detail triangulation (with internal sample points) generates more than 255 triangles.","commonSituations":"Very large base polygons combined with small detailSampleDist (dense internal sampling); polygons spanning large walkable areas that produce hundreds of detail triangles. The truncated mesh loses fine detail at the polygon's edges.","solutions":["Reduce detail sampling density: increase rcConfig.detailSampleDist (larger spacing between samples).","Reduce the base polygon size by lowering rcConfig.maxVertsPerPoly or raising cellSize so individual polys are smaller.","Disable internal sampling entirely (detailSampleDist = 0) if fine detail isn't needed.","Accept the truncation by catching the exception if lossy detail is tolerable — but prefer reducing sampling."],"exampleFix":"// before: per-poly detail exceeds 255 tris\ncfg.detailSampleDist = 1f;\n// after: coarser sampling keeps detail tris under 255\ncfg.detailSampleDist = 6f;","handlingStrategy":"try-catch","validationCode":"// Estimate detail triangle count; warn if likely to exceed 255\n// Heuristic: detail tris scale with sample density * poly area\nif (cfg.detailSampleDist > 0 && estimatedDetailTris > MAX_TRIS)\n    Log.Warning($\"Polygon likely to exceed {MAX_TRIS} detail tris; raising detailSampleDist\");","typeGuard":null,"tryCatchPattern":"// The mesh is truncated but usable; log and continue if lossy detail is acceptable\ntry { nverts = buildPolyDetail(...); }\ncatch (Exception e) when (e.Message.Contains(\"Shrinking triangle count\")) {\n    Log.Warning($\"Detail truncated to {MAX_TRIS} tris: {e.Message}\");\n    // tris list is valid (first 255 tris), proceed with lossy detail\n}","preventionTips":["Set detailSampleDist large enough to keep per-poly detail tris under 255.","For huge polygons, reduce base poly size via maxVertsPerPoly/cellSize.","If lossy truncation is acceptable, catch and continue — but log it."],"tags":["recast","navmesh","detail-mesh","capacity-limit","truncation"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}