{"record":{"id":"92d17ed25955c3bb","repo":"FyroxEngine/Fyrox","slug":"mesh-has-a-triangle-with-edge-length","errorCode":null,"errorMessage":"{}: Mesh has a triangle with edge length: {}","messagePattern":"(.+?): Mesh has a triangle with edge length: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fyrox-impl/src/resource/gltf/mod.rs","lineNumber":477,"sourceCode":"            result.push(import_mesh(mesh, mats, bufs, &mut stats)?);\n        }\n    }\n    if cfg!(feature = \"mesh_analysis\") {\n        if stats.repeated_index_count > 0 {\n            Log::err(format!(\n                \"{}: Model has triangles with repeated vertices: {}\",\n                path.to_string_lossy(),\n                stats.repeated_index_count\n            ));\n        }\n        let min_length = stats.min_edge_length();\n        if min_length == 0.0 {\n            Log::err(format!(\n                \"{}: Mesh has a triangle with a zero-length edge!\",\n                path.to_string_lossy()\n            ));\n        } else if min_length <= f32::EPSILON {\n            Log::err(format!(\n                \"{}: Mesh has a triangle with edge length: {}\",\n                path.to_string_lossy(),\n                min_length\n            ));\n        } else {\n            Log::info(format!(\n                \"{}: Smallest triangle edge: {}\",\n                path.to_string_lossy(),\n                min_length\n            ));\n        }\n    }\n    Ok(result)\n}\n\nfn import_mesh(\n    mesh: gltf::Mesh,\n    mats: &[MaterialResource],","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/FyroxEngine/Fyrox/blob/76c91aad8eca488ce527b1af707be8b3b24ad72d/fyrox-impl/src/resource/gltf/mod.rs#L459-L495","documentation":"Same degenerate-triangle check as the zero-length case, but for edges that are non-zero yet still at or below f32::EPSILON (~1.19e-7). Such near-degenerate triangles cause floating-point instability in normals and physics, so the glTF importer warns with the measured edge length.","triggerScenarios":"Loading a glTF/GLB where the minimum triangle edge length is > 0.0 but <= f32::EPSILON, detected during import_meshes (called from import_from_slice).","commonSituations":"Highly subdivided or heavily scaled-down meshes, unit-mismatch exports (e.g. model authored in millimeters then scaled by 0.001), or LOD generators producing micro-triangles.","solutions":["Scale the model to sane world units in the DCC tool before export so triangle edges are far above float epsilon.","Apply a decimate/remesh pass to remove sub-epsilon micro-triangles, then re-export.","Increase the mesh's export scale in the glTF exporter settings (e.g. Blender's scene unit scale)."],"exampleFix":"// before: model scaled 0.001 in exporter, edges ~1e-6 but authored mm\nexport_scale = 0.001\n\n// after: bake scale into mesh and use meters\n# Blender: Apply Scale (Ctrl+A) before glTF export","handlingStrategy":"validation","validationCode":"// Validate min edge length in authored units before export:\nfn min_edge_ok(positions: &[[f32; 3]], indices: &[u32]) -> bool {\n    const EPS: f32 = 1e-5; // well above f32::EPSILON\n    indices.chunks(3).all(|t| {\n        let d = |a: usize, b: usize| {\n            let (p, q) = (positions[t[a] as usize], positions[t[b] as usize]);\n            ((q[0]-p[0]).powi(2)+(q[1]-p[1]).powi(2)+(q[2]-p[2]).powi(2)).sqrt()\n        };\n        d(0,1) > EPS && d(1,2) > EPS && d(0,2) > EPS\n    })\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Author meshes in meters and apply scale (Ctrl+A in Blender) before export.","Avoid extreme subdivision that creates sub-micron triangles.","Validate exported assets with a mesh-lint script in the asset pipeline."],"tags":["gltf","asset-import","mesh","floating-point"],"backgroundTag":"value-out-of-range","analyzedSha":"76c91aad8eca488ce527b1af707be8b3b24ad72d","analyzedAt":"2026-09-10T16:04:01.633Z","contentChangedAt":"2026-09-10T16:04:01.633Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}