code wiki / (root) / nx_vpick_gate.nx

nx_vpick_gate.nx

buildroot/runtime/nx_vpick_gate.nx

60800 B882 linesdepth 4pulls 10 transitivereach 0 importersview sourcekind gate/proof
docsdependenciesstructsconstsfunctions

about

nx_vpick_gate.nx -- the gate for nx_vpick_lib (/compare/dcc DC4: ray-pick and a transform gizmo). THE CLAIM UNDER TEST is that a click in the sovereign viewport resolves to the RIGHT triangle and a drag resolves to an UNDOABLE operation. Both halves are asserted on values a wrong implementation cannot produce, never on a return code alone -- because the three cheapest wrong pickers in the world all return plausible codes: one that always misses, one that always returns triangle 0, and one that returns whichever triangle happens to be first in the buffer. THE FIXTURE CAMERA IS THE SHIPPED CAMERA. VG_W, VG_H, VG_DIST and VG_FOVH below are literally MV_W, MV_H, DIST and FOVH from nx_meshview_wasm. If the pick maths had drifted from the renderer's convention the exact-value teeth would fail, because they are the numbers that camera actually produces. ANTI-VACUITY, named where it lives, because most of these teeth are individually satisfiable by a stub: * a picker that ALWAYS MISSES passes every miss tooth -- killed by the exact-barycentric positive control, which pins u, v, w, t and the hit point to arithmetic worked out by hand. * a picker that ALWAYS RETURNS 0 passes the positive control -- killed by the named-miss tooth. * a picker that RETURNS THE FIRST HIT IN THE BUFFER passes a single depth test -- killed by running the SAME two triangles in both buffer orders and requiring DIFFERENT answers (1 then 0). A first-wins picker answers 0 twice, a last-wins picker answers 1 twice; only genuine depth sorting answers 1 then 0. * a degenerate-triangle guard that simply skips everything passes "degenerate is never picked" -- killed by putting the degenerate FIRST and requiring the valid triangle behind it to be found WITH its correct barycentrics. * a gizmo that returns ZERO is undoable, replayable and axis-constrained -- killed by comparing its magnitude against a closed form derived a DIFFERENT way (view half-width at the pivot plane), which also kills a gizmo that returns the raw pixel delta. * an edit stack that records nothing has a stable digest -- killed by requiring the digest to CHANGE and by reading the moved vertex back component by component. * a BENCH whose loop the compiler deleted times as FREE and reads as a very fast picker -- killed by accumulating the picked index and requiring the sum to equal the repetition count times what a single pick returns, a number no deleted loop can produce. * a LINEARITY verdict taken at ONE triangle count is not a verdict at all, because a quadratic curve and a linear one are the same number at a single N -- killed by four rungs spanning 64x, and by a bar derived from the two hypotheses being separated rather than tuned until the result passed. Every guard in the library is a gv_bite: it must fire on the bad input AND stay silent on the good one. THE SECOND HALF OF THE RUNG, ADDED 2026-08-25. A pick that is CORRECT is still not an interaction claim until it carries a COST at a stated triangle count -- dcc.plan's unit line says exactly that, and the rung's done-rule was half unmet while this file proved only correctness. Section 9 times vp_pick_screen over procedurally generated grids at four triangle counts, publishes nanoseconds per operation with its

dependencies 5 imports · 0 importers

nx_syscalls.nx nx_gate_verdict.nx nx_vpick_lib.nx nx_frame_budget.nx nx_oracleband_lib.nx nx_vpick_gate.nx

imports: nx_syscalls.nxnx_gate_verdict.nxnx_vpick_lib.nxnx_frame_budget.nxnx_oracleband_lib.nx

imported by: nobody (leaf or entry point)

structs

none

consts

54const VG_I64: i64 = 8
55const VG_NV: i64 = 9 // 3 triangles worth of vertices: far, near, degenerate
56const VG_MESH_WORDS: i64 = 27 // VG_NV * 3
57const VG_NCELLS: i64 = 27 // vp_cells_needed(VG_NV)
58const VG_CAP: i64 = 8 // op capacity; no fixture here pushes more than one
61const VG_W: i64 = 64 // MV_W
62const VG_H: i64 = 64 // MV_H
63const VG_YAW0: i64 = 0
64const VG_YAW90: i64 = 90
65const VG_DIST: i64 = 65536 // DIST (4.0 in Q14)
66const VG_FOVH: i64 = 30 // FOVH (half field of view, degrees)
67const VG_FOV90: i64 = 90 // a half-fov with no forward-facing frustum: cot(90) is 0
71const VG_CX: i64 = 32 // VG_W / 2
72const VG_CY: i64 = 32 // VG_H / 2
73const VG_DPX: i64 = 8 // the drag length used everywhere, in pixels
74const VG_BX_R: i64 = 40 // VG_CX + VG_DPX
75const VG_BX_L: i64 = 24 // VG_CX - VG_DPX
76const VG_BX_BIG: i64 = 48 // VG_CX + 2*VG_DPX
77const VG_BY_D: i64 = 40 // VG_CY + VG_DPX (screen y grows DOWNWARD)
78const VG_EDGE_X: i64 = 63 // VG_W - 1, the last legal column
79const VG_OFF_X: i64 = 64 // VG_W, the first illegal column
87const VG_SLACK: i64 = 12
94const VG_SLACK_MEASURED: i64 = 3
102const VG_NOT_PIXELS_MULT: i64 = 100
106const VG_SUM_MUL: i64 = 131
108const VG_BAD_AXIS: i64 = 3 // one past VP_AXIS_Z
109const VG_BAD_VERT: i64 = 9 // == VG_NV, the first out-of-range vertex index
116const VG_VERT_C: i64 = 3 // i64 components per fixture vertex: x, y, z
117const VG_TRI_I: i64 = 3 // i64 vertex indices per fixture triangle: a, b, c
118const VG_IX_1TRI: i64 = VG_TRI_I // a one-triangle index buffer
119const VG_IX_2TRI: i64 = VG_TRI_I + VG_TRI_I // the two-triangle fixtures (near/far pairs)
129const VB_CONF: *u8 = "knowledge/gamefeel_oracle.conf\x00"
130const VB_FPS_VR: i64 = 90 // the rate frame_budget_ms_90hz is cited at; identical to TB_FPS_VR
131const VB_MS_US: i64 = 1000 // microseconds in a millisecond -- the conf states its rows in ms
148const VB_LADDER: i64 = 4
149const VB_G0: i64 = 4
150const VB_G1: i64 = 8
151const VB_G2: i64 = 16
152const VB_G3: i64 = 32
153const VB_GMAX: i64 = 32 // the largest rung; the buffers are sized from it and a tooth checks it
158const VB_STEP: i64 = 4
164const VB_PX: i64 = 41
165const VB_PY: i64 = 27
176const VB_RESOLVE_US: i64 = 1000
177const VB_REPS_MIN: i64 = 1000
178const VB_REPS0: i64 = 1024 // first attempt, the smallest power of two at or above VB_REPS_MIN
179const VB_REPS_CAP: i64 = 4194304 // refuse to spin forever: ANNOUNCED, never silent (same shape as TB_TICKS_CAP)
185const VB_SAMPLES: i64 = 2

functions

187func vg_eq(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 }
188func vg_ne(a: i64, b: i64) -> i64 { if a != b { return 1 } return 0 }
189func vg_gt(a: i64, b: i64) -> i64 { if a > b { return 1 } return 0 }
190func vg_lt(a: i64, b: i64) -> i64 { if a < b { return 1 } return 0 }
191func vg_near(a: i64, b: i64, slack: i64) -> i64
197func vg_absd(a: i64, b: i64) -> i64
202func vg_setv(m: *i64, k: i64, x: i64, y: i64, z: i64) -> i64 { m[k*VG_VERT_C+VP_AXIS_X]=x; m[k*VG_VERT_C+VP_AXIS_Y]=y; m[k*VG_VERT_C+VP_AXIS_Z]=z; return 0 }
203func vg_seti(p: *i64, k: i64, a: i64, b: i64, c: i64) -> i64 { p[k*VG_TRI_I+0]=a; p[k*VG_TRI_I+1]=b; p[k*VG_TRI_I+2]=c; return 0 }
204func vg_setray(r: *i64, ox: i64, oy: i64, oz: i64, dx: i64, dy: i64, dz: i64) -> i64
209func vg_setcam(c: *i64, w: i64, h: i64, yaw: i64, dist: i64, fovh: i64) -> i64
214func vg_setdrag(d: *i64, ax: i64, ay: i64, bx: i64, by: i64) -> i64
218func vg_sum(p: *i64, n: i64) -> i64
225func vg_show(label: *u8, v: i64) -> i64
248func vb_measure(cam: *i64, mesh: *i64, nverts: i64, idx: *i64, ntris: i64, scratch: *i64, pout: *i64, out: *i64) -> i64
280func main(argc: i64, argv: *i64) -> i64