nx_nxa_joints.nx
buildroot/runtime/nx_nxa_joints.nx
about
nx_nxa_joints.nx -- SOVEREIGN STRUCTURAL JOINT IDENTIFICATION over an NXA SKEL.
WHY: NXA's SKEL carries NO JOINT NAMES, by design (nx_nxa_rig_emit: "SKEL carries no names by
design"; nx_nxa_anim: "names exist in the FBX even though SKEL stays nameless by design"). So a
consumer that needs "where is the head / a breast / a thigh" must derive it from GEOMETRY.
That derivation already exists -- but ONLY as JavaScript emitted into the browser viewer by
nx_nxa_rig_emit. There is no NishiLang function for it, so nothing server-side can ask the
question. This is that function, and it is meant to be the CANONICAL one: the JS emitter can
later emit the indices this computes instead of re-deriving them in the browser, which removes
the cross-language duplicate rather than adding to it (rule 15).
METHOD (same shape as the proven JS): height fraction over the rig's own extent + laterality.
h01(j) = (y - ymin) / (ymax - ymin) in permil, so 0 = lowest joint, 1000 = highest
lat(j) = x relative to the midline, in permil of height (sign = side)
Nothing here is a magic anatomical constant: the bands are derived from THIS rig's extent, so a
taller/shorter/differently-scaled rig lands in the same normalised space.
OUTPUT is the anchor set for nx_arousal_skin_lib's sk_thresh_field_rig -- (x, y, site) triples --
so skin optics can run over a real imported rig instead of only the hardcoded SDF body.
Sites (Masters & Johnson propagation order): 0 submammary 1 breast 2 torso 3 face 4 extremities
5 genital. knowledge/arousal_rig_anchors.conf documents the anatomy->site truth this must AGREE
WITH; it is the ORACLE for these rules, not their input (it is name-keyed and NXA has no names).
usage: nx_nxa_joints <file.nxa>
license_tier: ORIGINAL expect_exit: 0
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_nxa.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 30 | const NJ_MAGIC_1000: i64 = 1000 |
| 31 | const NJ_WORDS_PER_JOINT: i64 = 8 // [parent][x][y][z][qx][qy][qz][qw] |
functions
| 33 | func njw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 34 | func njn(v: i64) -> i64 |
| 50 | func nj_push(ax: *i64, ay: *i64, st: *i64, n: *i64, x: i64, y: i64, site: i64) -> i64 called by 1: main |
| 59 | func main(argc: i64, argv: *i64) -> i64 |