Honor point display geometry and sizing

This commit is contained in:
ramox81 committed 2026-08-22 17:18:30 +03:00
1 parent ba9f36adb2
commit c5fe70627a
10 files changed
+238 -60

No files matched your search

+13 -2
View File
@@ -1310,9 +1310,20 @@ pub fn tessellate(
} else {
(Vec::new(), Vec::new(), Vec::new())
};
let relative_marker =
crate::entities::point::relative_marker_spec(entity, document);
let (taper_widths, world_width) = if let Some((percent, normal)) = relative_marker {
// A negative width is reserved for viewport-relative
// point markers. The first three taper entries carry
// the marker-plane normal; normal taper processing is
// disabled for the sentinel by the wire uploader.
(normal.to_vec(), -percent)
} else {
(Vec::new(), polyline_band_width(entity))
};
out.push(WireModel {
taper_widths: Vec::new(),
world_width: polyline_band_width(entity),
taper_widths,
world_width,
depth_override: None,
display_visible: true,
plot_visible: true,
+56 -4
View File
@@ -111,7 +111,7 @@ impl WireInstance {
}
/// Per-wire constants shared by every segment of a wire (storage path). std430
/// layout: three vec4 then eight scalars = 80 B, matching `WireConst` in
/// layout: three vec4, eight scalars, then three vec4 = 128 B, matching `WireConst` in
/// wire_indexed.wgsl. `align_end` / `align_total` carry the "A"-type endpoint
/// alignment (see `wire_distances`); 0.0 total = no alignment.
#[repr(C)]
@@ -132,6 +132,11 @@ pub struct WireConst {
pub world_half_width: f32,
pub _pad1: f32,
pub _pad2: f32,
/// Point-marker origin as a double-single pair. `marker_normal_scale.w`
/// stores the viewport-height percentage; zero disables marker scaling.
pub marker_origin_high: [f32; 4],
pub marker_origin_low: [f32; 4],
pub marker_normal_scale: [f32; 4],
}
impl WireConst {
@@ -189,6 +194,9 @@ pub struct PackedWireInstance {
/// `world_half_width`). The shader interpolates across the segment.
pub world_hw_a: f32,
pub world_hw_b: f32,
pub marker_origin_high: [f32; 4],
pub marker_origin_low: [f32; 4],
pub marker_normal_scale: [f32; 4],
}
impl PackedWireInstance {
@@ -213,6 +221,9 @@ impl PackedWireInstance {
wgpu::VertexAttribute { offset: std::mem::offset_of!(PackedWireInstance, pos_b_low) as u64, shader_location: 8, format: wgpu::VertexFormat::Float32x3 },
// taper = (world_hw_a, world_hw_b)
wgpu::VertexAttribute { offset: std::mem::offset_of!(PackedWireInstance, world_hw_a) as u64, shader_location: 9, format: wgpu::VertexFormat::Float32x2 },
wgpu::VertexAttribute { offset: std::mem::offset_of!(PackedWireInstance, marker_origin_high) as u64, shader_location: 10, format: wgpu::VertexFormat::Float32x4 },
wgpu::VertexAttribute { offset: std::mem::offset_of!(PackedWireInstance, marker_origin_low) as u64, shader_location: 11, format: wgpu::VertexFormat::Float32x4 },
wgpu::VertexAttribute { offset: std::mem::offset_of!(PackedWireInstance, marker_normal_scale) as u64, shader_location: 12, format: wgpu::VertexFormat::Float32x4 },
];
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<PackedWireInstance>() as u64,
@@ -509,6 +520,33 @@ fn finite3(p: [f32; 3]) -> bool {
p[0].is_finite() && p[1].is_finite() && p[2].is_finite()
}
fn marker_metadata(wire: &WireModel) -> ([f32; 4], [f32; 4], [f32; 4]) {
if wire.world_width >= 0.0 {
return ([0.0; 4], [0.0; 4], [0.0; 4]);
}
let origin = wire
.snap_pts
.iter()
.find_map(|(point, hint)| {
matches!(hint, crate::scene::model::wire_model::SnapHint::Node).then_some(*point)
})
.unwrap_or(glam::DVec3::ZERO);
let (hx, lx) = WireModel::split_ds(origin.x);
let (hy, ly) = WireModel::split_ds(origin.y);
let (hz, lz) = WireModel::split_ds(origin.z);
let normal = glam::Vec3::new(
wire.taper_widths.first().copied().unwrap_or(0.0),
wire.taper_widths.get(1).copied().unwrap_or(0.0),
wire.taper_widths.get(2).copied().unwrap_or(1.0),
)
.normalize_or(glam::Vec3::Z);
(
[hx, hy, hz, 0.0],
[lx, ly, lz, 0.0],
[normal.x, normal.y, normal.z, -wire.world_width],
)
}
/// Emit packed per-segment instances (each carries the wire's constants).
pub(crate) fn emit_wire_packed(
wire: &WireModel,
@@ -525,8 +563,15 @@ pub(crate) fn emit_wire_packed(
return Vec::new();
}
let (dists, align_end, align_total) = wire_distances(wire);
let (marker_origin_high, marker_origin_low, marker_normal_scale) = marker_metadata(wire);
let low = |i: usize| -> [f32; 3] { wire.points_low.get(i).copied().unwrap_or([0.0; 3]) };
let tw = |i: usize| -> f32 { wire.taper_widths.get(i).copied().unwrap_or(0.0) * 0.5 };
let tw = |i: usize| -> f32 {
if wire.world_width < 0.0 {
0.0
} else {
wire.taper_widths.get(i).copied().unwrap_or(0.0) * 0.5
}
};
let mut instances: Vec<PackedWireInstance> = Vec::with_capacity(seg_count);
for i in 0..seg_count {
let a = wire.points[i];
@@ -549,9 +594,12 @@ pub(crate) fn emit_wire_packed(
draw_depth,
align_end,
align_total,
world_half_width: wire.world_width * 0.5,
world_half_width: wire.world_width.max(0.0) * 0.5,
world_hw_a: tw(i),
world_hw_b: tw(i + 1),
marker_origin_high,
marker_origin_low,
marker_normal_scale,
});
}
instances
@@ -566,6 +614,7 @@ pub(crate) fn emit_wire_native(
draw_depth: f32,
) -> (Vec<WireInstance>, WireConst) {
let (dists, align_end, align_total) = wire_distances(wire);
let (marker_origin_high, marker_origin_low, marker_normal_scale) = marker_metadata(wire);
let cst = WireConst {
color,
pat0: [wire.pattern[0], wire.pattern[1], wire.pattern[2], wire.pattern[3]],
@@ -575,9 +624,12 @@ pub(crate) fn emit_wire_native(
draw_depth,
align_end,
align_total,
world_half_width: wire.world_width * 0.5,
world_half_width: wire.world_width.max(0.0) * 0.5,
_pad1: 0.0,
_pad2: 0.0,
marker_origin_high,
marker_origin_low,
marker_normal_scale,
};
let n = wire.points.len();
let seg_count = n.saturating_sub(1);