From 61e5271055c0a7924c2598c57a545bc1fe92962c Mon Sep 17 00:00:00 2001 From: ramox81 <184937705+ramox81@users.noreply.github.com> Date: Fri, 11 Sep 2026 17:27:34 +0300 Subject: [PATCH] Keep wipeout frames continuous --- src/modules/draw/draw/wipeout.rs | 4 ++-- src/scene/cache/block_cache.rs | 2 ++ src/scene/convert/tess.rs | 2 +- src/scene/model/wire_model.rs | 15 ++++++++++----- src/shaders/wire.wgsl | 3 ++- src/shaders/wire_indexed.wgsl | 3 ++- 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/modules/draw/draw/wipeout.rs b/src/modules/draw/draw/wipeout.rs index 994daaf52..56f60ca12 100644 --- a/src/modules/draw/draw/wipeout.rs +++ b/src/modules/draw/draw/wipeout.rs @@ -344,7 +344,7 @@ impl CadCommand for WipeoutCommand { WireModel::CYAN, false, ); - wire.line_weight_px = 1.5; + wire.set_fixed_screen_width(2.0); Some(wire) } WipeoutMode::Rectangular => { @@ -367,7 +367,7 @@ impl CadCommand for WipeoutCommand { WireModel::CYAN, false, ); - wire.line_weight_px = 1.5; + wire.set_fixed_screen_width(2.0); Some(wire) } WipeoutMode::Polyline | WipeoutMode::Frames | WipeoutMode::ErasePolyline => None, diff --git a/src/scene/cache/block_cache.rs b/src/scene/cache/block_cache.rs index 307a9a526..125c0dee8 100644 --- a/src/scene/cache/block_cache.rs +++ b/src/scene/cache/block_cache.rs @@ -2485,6 +2485,8 @@ fn emit_wire( let sx = ((ax.x - o.x).powi(2) + (ax.y - o.y).powi(2) + (ax.z - o.z).powi(2)).sqrt(); let sy = ((ay.x - o.x).powi(2) + (ay.y - o.y).powi(2) + (ay.z - o.z).powi(2)).sqrt(); lw.world_width * ((sx + sy) * 0.5) as f32 + } else if lw.world_width < 0.0 { + lw.world_width } else { 0.0 }; diff --git a/src/scene/convert/tess.rs b/src/scene/convert/tess.rs index ef5da490d..52bd87f11 100644 --- a/src/scene/convert/tess.rs +++ b/src/scene/convert/tess.rs @@ -1282,7 +1282,7 @@ fn tessellate_entity_inner( } if matches!(e, EntityType::Wipeout(_)) { b.depth_override = Some(0.5); - b.line_weight_px = b.line_weight_px.max(1.5); + b.set_fixed_screen_width(2.0); } } diff --git a/src/scene/model/wire_model.rs b/src/scene/model/wire_model.rs index 30905d7a3..deec10db2 100644 --- a/src/scene/model/wire_model.rs +++ b/src/scene/model/wire_model.rs @@ -407,11 +407,10 @@ pub struct WireModel { pub pattern: [f32; 8], /// Rendered line width in screen pixels (half-width = line_weight_px / 2). pub line_weight_px: f32, - /// World-space band width (drawing units). `0.0` = a normal wire whose - /// width comes from `line_weight_px` (screen pixels). Non-zero = a wide - /// polyline: the shader expands this centre-line to `world_width` world - /// units (scaling with zoom) so the band IS the wire — the linetype dash - /// pattern then applies to the band instead of a separate hatch fill. + /// World-space band width (drawing units). Positive values create a wide + /// polyline band that scales with zoom. Zero uses `line_weight_px` and the + /// drawing's lineweight display setting. A negative value encodes a fixed + /// screen-pixel width whose absolute value bypasses that display setting. pub world_width: f32, /// Per-point full band width (drawing units), aligned index-for-index with /// [`points`], for a polyline whose width VARIES (a taper). Empty = a @@ -553,6 +552,12 @@ impl WireModel { w } + pub fn set_fixed_screen_width(&mut self, width_px: f32) { + let width_px = width_px.max(1.0); + self.line_weight_px = width_px; + self.world_width = -width_px; + } + /// Create a solid wire (no dash pattern, 1px weight). pub fn solid(name: String, points: Vec<[f32; 3]>, color: [f32; 4], selected: bool) -> Self { Self { diff --git a/src/shaders/wire.wgsl b/src/shaders/wire.wgsl index f1622b691..6a458b1dd 100644 --- a/src/shaders/wire.wgsl +++ b/src/shaders/wire.wgsl @@ -104,6 +104,7 @@ struct VertexOut { fn resolve_hw(taper: f32, world_hw: f32, px_hw: f32) -> f32 { if taper >= 0.0 { return max(taper / u.world_per_pixel, 0.5); } if world_hw > 0.0 { return max(world_hw / u.world_per_pixel, 0.5); } + if world_hw < 0.0 { return max(-world_hw, 0.5); } var display_hw = max(px_hw * u.lineweight_scale, 0.5); if u.lineweight_scale < 0.0 { let scale = -u.lineweight_scale; @@ -227,7 +228,7 @@ fn marker_relative(position_high: vec3, position_low: vec3, instance: let clip_pos = mix(clip_a, clip_b, which_end); - let hw = resolve_hw(0.0, 0.0, in.dists.z); + let hw = resolve_hw(-1.0, in.misc.w, in.dists.z); let ext = which_end * 2.0 - 1.0; let offset_px = perp * hw * side + dir * hw * ext; let ndc_offset = offset_px / (u.viewport_size * 0.5); diff --git a/src/shaders/wire_indexed.wgsl b/src/shaders/wire_indexed.wgsl index a18ee51b6..8a3d099e3 100644 --- a/src/shaders/wire_indexed.wgsl +++ b/src/shaders/wire_indexed.wgsl @@ -83,6 +83,7 @@ fn resolve_hw(taper_ratio: f32, world_hw: f32, px_hw: f32) -> f32 { return max((taper_ratio * world_hw) / u.world_per_pixel, 0.5); } if world_hw > 0.0 { return max(world_hw / u.world_per_pixel, 0.5); } + if world_hw < 0.0 { return max(-world_hw, 0.5); } var display_hw = max(px_hw * u.lineweight_scale, 0.5); if u.lineweight_scale < 0.0 { let scale = -u.lineweight_scale; @@ -200,7 +201,7 @@ fn marker_relative(position_high: vec3, position_low: vec3, c: WireCon let clip_pos = mix(clip_a, clip_b, which_end); - let hw = resolve_hw(0.0, 0.0, c.half_width); + let hw = resolve_hw(0.0, c.world_half_width, c.half_width); let ext = which_end * 2.0 - 1.0; let offset_px = perp * hw * side + dir * hw * ext; let ndc_offset = offset_px / (u.viewport_size * 0.5);