forked from 1b-agent/opencadstudio-upstream
fix(render): draw 3D surface fills at their real depth, not draw order
PolyfaceMesh / PolygonMesh / SubDMesh fills and 3DFACE quads were classified as 2D fills and given the draw-order z-bias, so they were pulled toward the camera and drew over solids. The tessellator emits a mesh's edges and its fill as separate WireModels (points-only vs fill-only), so the old `!points.is_empty()` discriminator misrouted the fill. Classify a fill as a 3D surface by its double-single low residual (`fill_tris_low`) instead, and drop the draw-order bias from 3DFACE quads. 2D annotation fills (text greek, MultiLeader / dimension backgrounds) leave `fill_tris_low` empty and keep ordering by rank. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
8a69ef9de3
commit
7185f6e4fa
2 files changed
+25
-8
No files matched your search
@@ -93,9 +93,10 @@ impl Face3DGpu {
|
||||
/// - `face3d_wires`: Face3D entities — `key_vertices` holds 4 quad corners;
|
||||
/// emits 2 triangles per face into the 3D buffer.
|
||||
/// - `all_wires`: all entity wires — `fill_tris` holds pre-triangulated
|
||||
/// fill data. Wires with non-empty `points` (PolyfaceMesh / PolygonMesh
|
||||
/// face data) feed the 3D buffer; wires with empty `points` (2D fills)
|
||||
/// feed the 2D buffer.
|
||||
/// fill data. Fills with a non-empty `fill_tris_low` residual (real 3-D
|
||||
/// surfaces — PolyfaceMesh / PolygonMesh) feed the 3D buffer at their
|
||||
/// true depth; fills with empty `fill_tris_low` (2D fills — text greek,
|
||||
/// MultiLeader / dimension backgrounds) feed the 2D draw-order buffer.
|
||||
/// - `keep_3d_mesh_fills`: when false (wireframe modes), the 3D side
|
||||
/// is left empty; the 2D side is always populated.
|
||||
pub fn from_wires(
|
||||
@@ -124,7 +125,6 @@ impl Face3DGpu {
|
||||
}
|
||||
let [r, g, b, a] = wire.color;
|
||||
let fill_color = [r * 0.45, g * 0.45, b * 0.45, a];
|
||||
let depth = depth_of(wire);
|
||||
let p = &wire.key_vertices;
|
||||
// key_vertices are f64 (offset-relative); split into the
|
||||
// double-single (high, low) pair the face3d shader expects.
|
||||
@@ -134,7 +134,12 @@ impl Face3DGpu {
|
||||
Face3DVertex {
|
||||
position: h,
|
||||
color: fill_color,
|
||||
draw_depth: depth,
|
||||
// A 3DFACE is genuine 3D geometry: keep its real depth
|
||||
// (no draw-order bias), matching the PolyfaceMesh /
|
||||
// PolygonMesh path below. A non-zero draw-order rank
|
||||
// here yanked 3DFACEs toward the camera so they drew in
|
||||
// front of solids (which carry no such bias).
|
||||
draw_depth: 0.0,
|
||||
position_low: [
|
||||
(x - h[0] as f64) as f32,
|
||||
(y - h[1] as f64) as f32,
|
||||
@@ -165,7 +170,18 @@ impl Face3DGpu {
|
||||
if wire.fill_tris.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let is_3d_mesh_face = !wire.points.is_empty();
|
||||
// A real 3-D surface fill (PolyfaceMesh / PolygonMesh) carries a
|
||||
// double-single low residual paired with `fill_tris` — it lives at
|
||||
// true world coordinates and must keep its real depth. 2-D fills
|
||||
// (text greek, MultiLeader / dimension backgrounds) deliberately
|
||||
// leave `fill_tris_low` empty and order by draw rank instead.
|
||||
//
|
||||
// NOTE: classifying by `!points.is_empty()` is wrong here — the
|
||||
// tessellator emits a mesh's edges and its fill as *separate*
|
||||
// WireModels (points-only vs fill-only), so the fill model has no
|
||||
// points and was being misrouted to the 2-D (draw-order-biased)
|
||||
// buffer, which drew meshes in front of solids.
|
||||
let is_3d_mesh_face = !wire.fill_tris_low.is_empty();
|
||||
let [r, g, b, a] = wire.color;
|
||||
if is_3d_mesh_face {
|
||||
if !keep_3d_mesh_fills {
|
||||
|
||||
@@ -34,8 +34,9 @@ struct VertexOut {
|
||||
@location(0) color: vec4<f32>,
|
||||
};
|
||||
|
||||
// Draw-order depth bias (see wire.wgsl). Signed draw_depth; 0.0 (3D mesh
|
||||
// faces) leaves real depth untouched; 2D fills / 3DFACE quads order by rank.
|
||||
// Draw-order depth bias (see wire.wgsl). Signed draw_depth; 0.0 (all 3D
|
||||
// surface faces — 3DFACE, PolyfaceMesh, PolygonMesh) leaves real depth
|
||||
// untouched so they occlude against solids; only 2D fills order by rank.
|
||||
const DRAW_ORDER_BIAS: f32 = 0.001;
|
||||
|
||||
@vertex
|
||||
|
||||
Reference in new issue
Block a user