code wiki / _hdl_build / nx_skelgen.nx
nx_skelgen.nx
buildroot/runtime/_hdl_build/nx_skelgen.nx
about
nx_skelgen.nx -- PIPELINE STAGE 1: SKELETAL GENERATION with JOINT CONSTRAINTS.
The industry's first stage is "algorithms define bone lengths and joint constraints from height and
proportion parameters". An audit of our stack found stage 1 PARTIAL: a rig existed but ran on BORROWED
scanned bones, and nothing generated lengths from parameters or constrained a joint at all.
★WHAT ALREADY EXISTED, AND WHY THIS DOES NOT DUPLICATE IT: runtime/nx_skeleton.nx is a skeleton + linear
blend skinning system -- bones as data rows {parent, local offset, yaw, pitch}, world pose by parent
composition, all integer. That is a rig FORMAT and a poser. It does not GENERATE lengths from
anthropometry and it has no joint limits. This organ produces what that one consumes: generated bone
rows plus the constraint table the pipeline requires. Compose, do not reimplement.
★JOINT CONSTRAINTS ARE THE POINT, and they are fail-closed. A knee that can bend backwards is not a
skeleton, it is a bag of segments. Every joint carries an anatomical range, and a pose outside it is
REFUSED rather than clamped silently -- because a silently clamped pose looks like a working animation
while lying about what the body did.
nx_skelgen <out.dat> [stature_mm] [sex 0-1000] [seed]
nx_skelgen check <joint_index> <angle_deg> -> is this pose anatomically legal
nx_skelgen selftest
license_tier: ORIGINAL expect_exit: 0 No hw writes (Rule 26).
dependencies 2 imports · 0 importers
imports: nx_gate_verdict.nxnx_itoa_lib.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
| 25 | const SG_NB: i64 = 16 |
| 26 | const SG_MODE: i64 = 420 |
| 27 | const SG_BUF: i64 = 16384 |
| 28 | const SG_MM: i64 = 1000 |
| 31 | const SG_PN: i64 = 13 |
| 32 | const SG_PSTRIDE: i64 = 12 |
| 33 | const SG_PPAR: i64 = 0 |
| 34 | const SG_PSIDE: i64 = 1 |
| 35 | const SG_PXB: i64 = 2 |
| 36 | const SG_PXS: i64 = 3 |
| 37 | const SG_PXD: i64 = 4 |
| 38 | const SG_PYB: i64 = 5 |
| 39 | const SG_PYS: i64 = 6 |
| 40 | const SG_PYD: i64 = 7 |
| 41 | const SG_PZB: i64 = 8 |
| 42 | const SG_PLO: i64 = 9 |
| 43 | const SG_PHI: i64 = 10 |
| 251 | const SG_NJ: i64 = 21 |
| 252 | const SG_HIP: i64 = 530 |
| 253 | const SG_ANKLE: i64 = 39 |
| 254 | const SG_L5: i64 = 80 |
| 255 | const SG_C7: i64 = 260 |
| 256 | const SG_ATLAS: i64 = 60 |
| 257 | const SG_VERTEX: i64 = 70 |
| 266 | const SG_ACR: i64 = 52 |
| 267 | const SG_ACR_H: i64 = 818 |
| 268 | const SG_CANON_ACR: i64 = 808 |
| 269 | const SG_GIRDLE_TOL: i64 = 15 |
| 270 | const SG_HIPW: i64 = 48 |
| 271 | const SG_MIRROR: i64 = 8 |
| 274 | const SG_REF_H: i64 = 1750 |
| 275 | const SG_REF_H2: i64 = 3500 |
| 276 | const SG_SWEEP_LO: i64 = 1200 |
| 277 | const SG_SWEEP_HI: i64 = 2100 |
| 278 | const SG_SWEEP_STEP: i64 = 150 |
| 279 | const SG_SEX_MAX: i64 = 1000 |
| 280 | const SG_SEX_STEP: i64 = 250 |
| 281 | const SG_PERTURB: i64 = 50 |
| 282 | const SG_CANON_NECK: i64 = 892 |
| 283 | const SG_CANON_CROWN: i64 = 1010 |
| 286 | const SG_AXIAL: i64 = 5 |
functions
| 45 | func sg_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } called by 1: main |
| 50 | func sg_pn(v: i64) -> i64 { nxi_out(v); return 0 } |
| 51 | func sg_streq(a: *u8, b: *u8) -> i64 called by 1: main |
| 56 | func sg_atoi(s: *u8) -> i64 called by 1: main |
| 62 | func sg_wint(b: *u8, pos: *i64, v: i64, c: i64) -> i64 called by 1: sg_write |
| 88 | func sg_bone_joint(bone: i64) -> i64 |
| 103 | func sg_bone_axis(bone: i64) -> i64 |
| 108 | func sg_len_permil(bone: i64, sexf: i64, P: *i64) -> i64 |
| 121 | func sg_len(joint: i64, stature: i64, sexf: i64, P: *i64) -> i64 |
| 140 | func sg_prox_joint(bone: i64, P: *i64) -> i64 |
| 150 | func sg_lo(joint: i64, P: *i64) -> i64 |
| 156 | func sg_hi(joint: i64, P: *i64) -> i64 |
| 162 | func sg_legal(joint: i64, deg: i64, P: *i64) -> i64 |
| 187 | func sg_prow(P: *i64, j: i64, f: i64) -> i64 { return P[j*SG_PSTRIDE + f] } |
| 188 | func sg_pset(P: *i64, j: i64, par: i64, side: i64, xb: i64, xs: i64, xd: i64, called by 1: sg_plan_human |
| 198 | func sg_plan_human(P: *i64) -> i64 |
| 216 | func sg_pcomp(base: i64, sexc: i64, div: i64, sexf: i64) -> i64 |
| 289 | func sg_mm(permil: i64, stature: i64) -> i64 |
| 295 | func sg_jbase(j: i64) -> i64 { if j >= 13 { return j - SG_MIRROR } return j } |
| 296 | func sg_jside(j: i64) -> i64 |
| 301 | func sg_jparent(j: i64, P: *i64) -> i64 |
| 309 | func sg_jdx(j: i64, sexf: i64, P: *i64) -> i64 |
| 313 | func sg_jdy(j: i64, sexf: i64, P: *i64) -> i64 |
| 317 | func sg_jdz(j: i64, sexf: i64, P: *i64) -> i64 |
| 324 | func sg_fk(stature: i64, sexf: i64, wx: *i64, wy: *i64, wz: *i64, P: *i64) -> i64 |
| 342 | func sg_closure(stature: i64, sexf: i64, perturb: i64, P: *i64) -> i64 |
| 349 | func sg_write(path: *u8, stature: i64, sexf: i64, seed: i64, P: *i64) -> i64 |
| 386 | func sg_gate() -> i64 |
| 587 | func main(argc: i64, argv: *i64) -> i64 |