code wiki / (root) / nx_nxa_anim_gate.nx

nx_nxa_anim_gate.nx source

↩ module page · 126 lines · 8760 B

1// nx_nxa_anim_gate.nx -- GATE for the one NXA clip evaluator (nx_nxa_anim_lib), driven IN-PROCESS on PLANTED 2// keys whose answers are known by arithmetic: lane sign-extension, track indexing that skips legacy channels 3// and refuses a truncated section by name, the bracketing-key nlerp at a known midpoint, the shortest-path 4// flip on a pair whose unflipped blend has the opposite sign, the root rule, the linear drift fit, the walk 5// cadence default, drift-removed rows that read zero on the root, an untracked joint's identity rows, and a 6// full idle hold that reproduces the pose. Every fixture asserts its own condition before its outcome. 7// license_tier: ORIGINAL No hw writes (Rule 26). 8import "nx_syscalls.nx" 9import "nx_nxa_anim_lib.nx" 10import "nx_gate_verdict.nx" 11 12const G_I64: i64 = 8 13const G_NJ: i64 = 3 14const G_ANIM_W: i64 = 24 15const G_SKEL_W: i64 = 24 16const G_SCR_W: i64 = 64 17const G_ROOT_J: i64 = 2 18const G_HEAD_Z: i64 = 150000 19const G_MID_Z: i64 = 50000 20const G_DUR: i64 = 1000 21const G_TMID: i64 = 500 22const G_Q45: i64 = 2896 // the q12 half-root of two: nlerp of identity and a half-turn, normalised 23const G_Q_TOL: i64 = 2 24const G_MM_END: i64 = 300 // joint 0 dt lane at the last key, mm -> 30000 model units 25const G_ROOT_MM: i64 = 100 // root dt lane at the last key, mm -> 10000 model units over 1000 ms 26const G_ROOT_VX16: i64 = 655360 // 10000 units / 1000 ms x 65536 27const G_DUAL_X_J0: i64 = 14480000 // ((15000 - 5000) x 2896)/2: joint 0's midpoint dt 15000 MINUS the root's fitted drift 28 // at t=500 (x0 + vx*t = 5000), which is subtracted from EVERY joint exactly as the 29 // page's animEval did; T = (10000,0,0) under a z-rotation of bind (0,0,150000). 30 // FIRST RUN OF THIS GATE READ 14480000 AGAINST A HAND-COMPUTED 21720000: the 31 // implementation was right and the expectation had forgotten the drift term. 32const G_A_QZ: i64 = 2896 33const G_A_QW: i64 = 2896 34const G_B_QZ: i64 = 0 - 3547 35const G_B_QW: i64 = 2048 36 37func g_lane(v: i64) -> i64 { return v & NA_LANE_MASK } 38func g_key(a: *i64, o: i64, t: i64, qx: i64, qy: i64, qz: i64, qw: i64, dx: i64, dy: i64, dz: i64) -> i64 { 39 a[o] = g_lane(t) | (g_lane(qx) << NA_LANE_B1) | (g_lane(qy) << NA_LANE_B2) | (g_lane(qz) << NA_LANE_B3) 40 a[o + 1] = g_lane(qw) | (g_lane(dx) << NA_LANE_B1) | (g_lane(dy) << NA_LANE_B2) | (g_lane(dz) << NA_LANE_B3) 41 return 0 42} 43 44func main() -> i64 { 45 gv_head("=== nx_nxa_anim_gate -- the NXA clip evaluator proven on planted keys ===" as *u8) 46 let c: *i64 = gv_ctr() 47 // T1 lanes 48 gv_check_eq("i16-lane-sign-extends (planted 0xFFFE at bits 16 reads -2)" as *u8, na_i16(g_lane(0 - 2) << NA_LANE_B1, NA_LANE_B1), 0 - 2, c) 49 gv_check_eq("i16-lane-positive-passes-through (planted 4096 at bits 32)" as *u8, na_i16(4096 << NA_LANE_B2, NA_LANE_B2), 4096, c) 50 // T2 a planted ANIM payload: three tracks -- joint 0 ch2 (identity -> half turn about z, dt 0 -> 300 mm x), 51 // joint 1 ch0 (a legacy verbose track that must be SKIPPED), joint 2 = the root, ch2, linear x drift 52 let anim: *i64 = sys_mmap(G_ANIM_W * G_I64) as *i64 53 anim[0] = 3 54 anim[1] = 0; anim[2] = NA_CH2; anim[3] = 2 55 g_key(anim, 4, 0, 0, 0, 0, NA_Q12, 0, 0, 0) 56 g_key(anim, 6, G_DUR, 0, 0, NA_Q12, 0, G_MM_END, 0, 0) 57 anim[8] = 1; anim[9] = 0; anim[10] = 1 58 anim[11] = 0; anim[12] = 0; anim[13] = 0; anim[14] = 0 59 anim[15] = G_ROOT_J; anim[16] = NA_CH2; anim[17] = 3 60 g_key(anim, 18, 0, 0, 0, 0, NA_Q12, 0, 0, 0) 61 g_key(anim, 20, G_TMID, 0, 0, 0, NA_Q12, G_ROOT_MM/2, 0, 0) 62 g_key(anim, 22, G_DUR, 0, 0, 0, NA_Q12, G_ROOT_MM, 0, 0) 63 let tidx: *i64 = sys_mmap(G_NJ * NA_IDX_W * G_I64) as *i64 64 let dur: i64 = na_index(anim, G_ANIM_W, G_NJ, tidx) 65 gv_check_eq("index-clip-duration-is-the-latest-last-key" as *u8, dur, G_DUR, c) 66 gv_check_eq("index-joint0-key-offset" as *u8, tidx[0], 4, c) 67 gv_check_eq("index-joint0-nkeys" as *u8, tidx[1], 2, c) 68 gv_check_eq("index-skips-a-legacy-channel-0-track (joint 1 untracked)" as *u8, tidx[2], 0 - 1, c) 69 gv_check_eq("index-root-nkeys" as *u8, tidx[5], 3, c) 70 let tidx2: *i64 = sys_mmap(G_NJ * NA_IDX_W * G_I64) as *i64 71 gv_check_eq("neg-control-a-truncated-section-is-REFUSED-by-name (overrun)" as *u8, na_index(anim, G_ANIM_W - 4, G_NJ, tidx2), NA_RC_OVERRUN, c) 72 // T3 the midpoint sample of joint 0: nlerp(identity, half-turn) normalised, dt halfway in model units 73 let q: *i64 = sys_mmap(8 * G_I64) as *i64 74 let d: *i64 = sys_mmap(8 * G_I64) as *i64 75 let scr: *i64 = sys_mmap(G_SCR_W * G_I64) as *i64 76 na_eval_track(anim, tidx[0], tidx[1], G_TMID, q, d, scr) 77 gv_check_near("nlerp-midpoint-qz (q12 half-root-two)" as *u8, q[2], G_Q45, G_Q_TOL, c) 78 gv_check_near("nlerp-midpoint-qw" as *u8, q[3], G_Q45, G_Q_TOL, c) 79 gv_check_eq("dt-lerp-midpoint-in-model-units (mm x 100)" as *u8, d[0], G_MM_END*NA_DT_MM_TO_MODEL/2, c) 80 // T4 shortest path: a = 90 deg about z, b = the NEGATED -120 deg key; dot < 0 so b is flipped and the 81 // blend lands on the short arc with qz POSITIVE; the long arc (no flip) lands with qz NEGATIVE 82 let anim2: *i64 = sys_mmap(8 * G_I64) as *i64 83 anim2[0] = 1; anim2[1] = 0; anim2[2] = NA_CH2; anim2[3] = 2 84 g_key(anim2, 4, 0, 0, 0, G_A_QZ, G_A_QW, 0, 0, 0) 85 g_key(anim2, 6, G_DUR, 0, 0, G_B_QZ, G_B_QW, 0, 0, 0) 86 na_eval_track(anim2, 4, 2, G_TMID, q, d, scr) 87 gv_check("fixture-reached-the-condition: the planted pair has a negative dot (a flip is required)" as *u8, ((G_A_QZ*G_B_QZ + G_A_QW*G_B_QW) < 0) as i64, c) 88 gv_check("shortest-path-flip-fires: the blend takes the short arc (qz > 0)" as *u8, (q[2] > 0) as i64, c) 89 // T5 the root rule, the drift fit and the cadence default on a planted skeleton 90 let skel: *i64 = sys_mmap(G_SKEL_W * G_I64) as *i64 91 var z: i64 = 0 92 while z < G_SKEL_W { skel[z] = 0; z = z + 1 } 93 skel[0*NA_SKEL_W + NA_SKEL_TZ] = G_HEAD_Z 94 skel[1*NA_SKEL_W + NA_SKEL_TZ] = G_MID_Z 95 skel[2*NA_SKEL_W + NA_SKEL_TZ] = NA_ROOT_Z 96 let rj: i64 = na_root_joint(skel, G_NJ) 97 gv_check_eq("root-joint-is-the-bind-nearest-the-pelvis-height" as *u8, rj, G_ROOT_J, c) 98 let rv: *i64 = sys_mmap(NA_RV_W * G_I64) as *i64 99 na_fit_root(anim, tidx, rj, rv, scr) 100 gv_check_eq("drift-fit-vx16 (10000 units over 1000 ms x 65536)" as *u8, rv[2], G_ROOT_VX16, c) 101 gv_check_eq("drift-fit-span" as *u8, rv[5], G_DUR, c) 102 gv_check_eq("cadence-default-when-root-travel-is-under-1.5-blocks" as *u8, na_mpb(anim, tidx, rj, dur, scr), NA_MPB_DEFAULT, c) 103 // T6 rows at the midpoint, no hold: root dual is ZERO (its drift is the fitted line), joint 1 untracked 104 // reads identity, joint 0 carries the known dual 105 let pq: *i64 = sys_mmap(G_NJ * 4 * G_I64) as *i64 106 let pd: *i64 = sys_mmap(G_NJ * 3 * G_I64) as *i64 107 var j: i64 = 0 108 while j < G_NJ { pq[j*4] = 0; pq[j*4 + 1] = 0; pq[j*4 + 2] = 0; pq[j*4 + 3] = NA_Q12; pd[j*3] = 0; pd[j*3 + 1] = 0; pd[j*3 + 2] = 0; j = j + 1 } 109 let out: *i64 = sys_mmap(G_NJ * NA_ROW_W * G_I64) as *i64 110 na_rows(anim, tidx, G_NJ, skel, pq, pd, 0, rv, G_TMID, 0, out, scr) 111 gv_check_eq("root-drift-removed: root dual x is zero at the midpoint" as *u8, out[G_NJ*4 + G_ROOT_J*4], 0, c) 112 gv_check_eq("root-drift-removed: root dual w is zero at the midpoint" as *u8, out[G_NJ*4 + G_ROOT_J*4 + 3], 0, c) 113 gv_check_eq("untracked-joint-real-is-identity" as *u8, out[1*4 + 3], NA_Q12, c) 114 gv_check_eq("untracked-joint-dual-is-zero" as *u8, out[G_NJ*4 + 1*4], 0, c) 115 gv_check_eq("joint0-dual-x-is-the-known-answer" as *u8, out[G_NJ*4], G_DUAL_X_J0, c) 116 gv_check_eq("joint0-dual-y-is-minus-the-known-answer" as *u8, out[G_NJ*4 + 1], 0 - G_DUAL_X_J0, c) 117 // T7 a full idle hold toward the identity pose reproduces the pose rows: real identity, dual zero 118 na_rows(anim, tidx, G_NJ, skel, pq, pd, 1, rv, G_TMID, NA_Q12, out, scr) 119 gv_check_eq("full-idle-hold-joint0-real-is-the-pose" as *u8, out[3], NA_Q12, c) 120 gv_check_eq("full-idle-hold-joint0-dual-is-zero" as *u8, out[G_NJ*4], 0, c) 121 gv_values_head() 122 gv_kv("dur_ms" as *u8, dur) 123 gv_kv("root_vx16" as *u8, rv[2]) 124 gv_kv("dual_x_j0" as *u8, G_DUAL_X_J0) 125 return gv_verdict("nx_nxa_anim_gate" as *u8, c, "the NXA clip evaluator proven on planted keys: lanes sign-extend, the index skips legacy channels and refuses a truncated section by name, the midpoint nlerp and dt lerp land on their arithmetic, the shortest-path flip takes the short arc, the root rule and drift fit and cadence default read their planted values, drift-removed root rows are zero, untracked joints read identity, and a full idle hold reproduces the pose" as *u8) 126}