From 51911080f0ef023f347f6133e3a2dc8531c486a4 Mon Sep 17 00:00:00 2001 From: Alexander Krylov Date: Mon, 26 Oct 2026 05:58:53 +0300 Subject: [PATCH 1/2] Mob models: one skip lookup per part, not one per polygon Co-Authored-By: Hermes Agent (Nous Research) --- crates/horizon-client/src/mobs/render.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/horizon-client/src/mobs/render.rs b/crates/horizon-client/src/mobs/render.rs index cb21cec8c..4188c9c85 100644 --- a/crates/horizon-client/src/mobs/render.rs +++ b/crates/horizon-client/src/mobs/render.rs @@ -946,7 +946,11 @@ fn draw_normals( return; } let normals = normals.part(p); - for poly in part.polygons.iter().filter(|_| !poses.skips(part)) { + // `skips` is a name lookup: asking once per part, not once per polygon. + if poses.skips(part) { + return; + } + for poly in &part.polygons { let normal = poly.vertex_normal(normals); for v in poly.vertices { let pos = m.transform_point3(glam::Vec3::new(v[0], v[1], v[2]) / 16.0); From 77def1f2dd13fe5c7d3f96d6c745c74312409501 Mon Sep 17 00:00:00 2001 From: Alexander Krylov Date: Mon, 26 Oct 2026 08:40:00 +0300 Subject: [PATCH 2/2] Mob models: a skipped part still draws its children The early return skipped the child loop as well, while skipDraw only hides the part's own cubes. A rolled armadillo skips its body and still renders the parts below it. Co-Authored-By: Hermes Agent (Nous Research) --- crates/horizon-client/src/mobs/render.rs | 38 ++++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/horizon-client/src/mobs/render.rs b/crates/horizon-client/src/mobs/render.rs index 4188c9c85..ef18536d3 100644 --- a/crates/horizon-client/src/mobs/render.rs +++ b/crates/horizon-client/src/mobs/render.rs @@ -946,25 +946,25 @@ fn draw_normals( return; } let normals = normals.part(p); - // `skips` is a name lookup: asking once per part, not once per polygon. - if poses.skips(part) { - return; - } - for poly in &part.polygons { - let normal = poly.vertex_normal(normals); - for v in poly.vertices { - let pos = m.transform_point3(glam::Vec3::new(v[0], v[1], v[2]) / 16.0); - out.push(Vertex { - normal, - pos: pos.to_array(), - uv: [ - uv[0] + (uv[2] - uv[0]) * v[3], - uv[1] + (uv[3] - uv[1]) * v[4], - ], - layer: overlay, - color, - light, - }); + // `skips` is a name lookup: ask once per part, not once per polygon. A part + // hidden this way still draws its children, so only the polygons are gated. + if !poses.skips(part) { + for poly in &part.polygons { + let normal = poly.vertex_normal(normals); + for v in poly.vertices { + let pos = m.transform_point3(glam::Vec3::new(v[0], v[1], v[2]) / 16.0); + out.push(Vertex { + normal, + pos: pos.to_array(), + uv: [ + uv[0] + (uv[2] - uv[0]) * v[3], + uv[1] + (uv[3] - uv[1]) * v[4], + ], + layer: overlay, + color, + light, + }); + } } } for c in &part.children {