mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 10:57:49 +00:00
a4f2075c3d
Box select resolved hits by reading the depth-tested object_id MRT, so only the front-most surface in each pixel could ever come back. In x-ray that is wrong twice over: you can see the geometry behind, and you still cannot select it. Add a second box-pick path used only while x-ray is active. It runs the same vs_pick geometry through fs_boxpick with depth compare Always, no depth write and no colour targets, scissored to the marquee — so nothing culls a fragment behind another and the pass's only output is an atomicOr of one bit per object into a hit bitmask. Reading that back gives every object with geometry inside the box, occluded or not. The bitmask rides alongside sel_flags at group(0) binding 2, allocated and bound by ensureSelectionFlagsBuffer so the two can never disagree about how many object ids exist. The layout entry is FRAGMENT-visible only: WebGPU forbids a read_write storage buffer in the vertex stage, and every pipeline shares this layout. Back-face culling is off for the pass — a box landing inside a closed solid would otherwise see none of its faces and miss it. Outside x-ray the depth-tested read stands, so a plain marquee still takes only what is visible. A failure to build the pipeline falls back to that path rather than breaking box select. Tests cover the three properties worth having: x-ray selects strictly more, its result is a superset of the plain one (a bare count would wave through a wrong scissor or an off-by-one in the bit decode), and turning x-ray off restores front-most-only. They need a model with real self-occlusion, which sidecar_bake cannot currently produce — it segfaults on any input, including the pristine sample.ifc — so they skip with an explanation until a fixture is supplied. See the note at the top of the spec. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>