forked from 1b-agent/opencadstudio-upstream
Honor point display geometry and sizing
This commit is contained in:
1 parent
ba9f36adb2
commit
c5fe70627a
10 files changed
+238
-60
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user