code wiki / (root) / nx_nxa_dyna.nx

nx_nxa_dyna.nx

buildroot/runtime/nx_nxa_dyna.nx

14208 B303 linesdepth 2pulls 3 transitivereach 0 importersview sourcekind tooltopic nxa
docsdependenciesstructsconstsfunctions

about

nx_nxa_dyna.nx -- WRITE THE DYNA SECTION: per-bone soft-tissue physics DECLARED IN THE ASSET, with the lateral breast-bone pair DERIVED FROM THE MESH'S OWN GEOMETRY. WHY THIS EXISTS. nx_asset_floor_gate measured our shipped character and found 5 midline chest joints and ZERO lateral pair. Real breast bones come in L/R pairs OFF the midline; midline joints at chest height ARE THE SPINE CHAIN, so driving them swings the whole torso -- the wobble the operator kept reporting. With no bone to drive, chest motion had to be faked at the shader vertex band, and the engine's own joint picker (|bind.x| < 9000, i.e. near-midline) was selecting spine joints as stand-ins using a superseded height normalisation (z/171530, which ignores the mesh origin -- the same error that once put the nipples below the legs). THE FIX IS A FORMAT CAPABILITY, NOT ANOTHER SHADER PATCH. FBX and its class carry no physics at all: a rig travels as geometry plus a joint tree, and every consumer re-invents the dynamics in engine code. DYNA makes the ASSET carry its own soft-tissue contract -- anchor, axis, stiffness, damping, travel clamp, influence radius, falloff -- so the engine DRIVES DECLARED DATA instead of hardcoding bands. That is the difference between a mannequin and a body. ANCHORS ARE MEASURED, NEVER GUESSED. For each side we take the CENTROID of the front-hemisphere vertices inside the bust band. Anatomy therefore comes from the mesh in front of us, so a different body type yields different anchors -- and the firm/bouncy RANGE the operator asked for falls out of geometry rather than a table of magic numbers. Physics constants are NOT invented here: they are the banked, in-band values already proven by the chest-motion oracle (2.5 Hz, 3.2 cm travel, 0.0 cm torso, 0.89 coherence) and by nx_softbind (chest K base 60 step 25, C base 100 step 16). Moving them out of code and into the asset is the point -- rule 11, and the recombinator wants them as data. nx_nxa_dyna <in.nxa> <out.nxa> ADDITIVE AND IDEMPOTENT: the input is never modified; an existing DYNA is REPLACED, not doubled, so running twice is identical to running once. DYNA payload (i64 words): [0]=n_bones [1]=stride(12), then per bone: 0 side(-1 L,+1 R,0 mid) 1 anchor_x 2 anchor_y 3 anchor_z 4 k_q8 5 c_q8 6 max_disp 7 influence_radius 8 falloff_q8 9 axis_mask(1=x,2=y,4=z) 10 k_step_q8 11 c_step_q8 license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0

dependencies 2 imports · 0 importers

nx_syscalls.nx nx_nxa.nx nx_nxa_dyna.nx

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

main nd_werr sys_write nd_slen sys_exit sys_mmap sys_read_file sys_openat_rd sys_lseek sys_mmap ↻ sys_read sys_close nd_rd64 nxa_magic nd_tageq nd_wr64 nxa_check2 nxa_tag4 sys_openat_wr sys_write ↻ sys_close ↻ nd_out sys_write ↻ nd_slen ↻ nd_num sys_write ↻ sys_mmap ↻

structs

none

consts

40const ND_MAGIC_1710: i64 = 1710
41const ND_MAGIC_4096: i64 = 4096
43const ND_HDR: i64 = 32
44const ND_TOCE: i64 = 32
45const ND_STRIDE: i64 = 12
46const ND_MAXSEC: i64 = 64
47const ND_MODE: i64 = 0x1a4
48const ND_ERRFD: i64 = 2
49const ND_EXIT_USAGE: i64 = 2
50const ND_EXIT_BAD: i64 = 3
51const ND_EXIT_IO: i64 = 1
52const ND_EXIT_NOPAIR: i64 = 4
56const ND_NIP_PERMIL: i64 = 744
57const ND_BAND_PERMIL: i64 = 40
59const ND_K_BASE: i64 = 60
60const ND_K_STEP: i64 = 25
61const ND_C_BASE: i64 = 100
62const ND_C_STEP: i64 = 16
63const ND_FALLOFF_Q8: i64 = 256
64const ND_AXIS_ALL: i64 = 7

functions

66func nd_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
called by 2: nd_werrnd_out
67func nd_werr(s: *u8) -> i64 { sys_write(ND_ERRFD, s, nd_slen(s)); return 0 }
called by 1: main calls 2: sys_writend_slen
68func nd_out(s: *u8) -> i64 { sys_write(1, s, nd_slen(s)); return 0 }
called by 1: main calls 2: sys_writend_slen
69func nd_num(v: i64) -> i64
called by 1: main calls 2: sys_writesys_mmap
82func nd_rd64(b: *u8, off: i64) -> i64
called by 1: main
88func nd_wr64(b: *u8, off: i64, v: i64) -> i64
called by 1: main
94func nd_tageq(b: *u8, off: i64, t: *u8) -> i64
called by 1: main
100func main(argc: i64, argv: *i64) -> i64