code wiki / (root) / nx_bvhfk.nx

nx_bvhfk.nx

buildroot/runtime/nx_bvhfk.nx

18534 B418 linesdepth 4pulls 7 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_bvhfk.nx -- BVH FORWARD KINEMATICS: joint tree + channel rotations -> WORLD-SPACE positions. WHY THIS IS THE RUNG THAT MATTERS: parsing a BVH gets you a hierarchy; PLAYING it is what DanceXR does. Our exceed is not playback -- it is that nx_pose_retarget already inverts our sovereign FK (joint POSITIONS -> our rig's FK angles), and nx_pose_coach / nx_pose_naturalness already SCORE a pose track. The one missing link was world-space positions out of a BVH. This organ is that link, so third-party mocap can drive OUR rig -- including VRM, which appears nowhere in DanceXR's format set. THE FK CORE (fk_eval + the integer matrix substrate) LIVES IN nx_bvhfk_lib.nx since 2026-08-13 -- extracted on the second consumer (nx_clipcheck's bvh self-clearance control). The KAT below is the extraction's value-identity proof: bone-length isometry on real third-party data. *THE HARDEST TOOTH IS BONE-LENGTH INVARIANCE. A rotation is an isometry: |child - parent| MUST equal |offset|, at every frame, for every joint. A rest-pose test passes even if the rotation path is a no-op; a length test fails the moment a matrix is mis-scaled, mis-composed, or drifts in fixed point. It is the implied hidden quantity that physics demands, and it is checked here against REAL third-party data, not only a fixture. UNITS: positions in file units x B_SCALE (1000) -- BVH does not state its unit; the convention is centimetres, so we do not claim mm. Angles arrive as millidegrees and are converted to the it_* integer-trig circle (25736 units) -- never to floats. usage: nx_bvhfk pos <file.bvh> <frame> world x y z per joint nx_bvhfk lens <file.bvh> <frame> measured bone length vs declared |offset| per joint nx_bvhfk --kat selftest: 6 teeth, 3 of them anti-vacuity license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0

dependencies 4 imports · 0 importers

nx_gate_verdict.nx nx_bvh_lib.nx nx_itrig.nx nx_bvhfk_lib.nx nx_bvhfk.nx

imports: nx_gate_verdict.nxnx_bvh_lib.nxnx_itrig.nxnx_bvhfk_lib.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main gv_puts sys_write fk_kat gv_ctr sys_mmap nxa_die sys_write ↻ sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ gv_head gv_puts ↻ fk_fixture fk_cat b_parse sys_mmap ↻ b_hierarchy sys_mmap ↻ b_token b_is_space b_tok_is b_slen b_parse_fx b_chan_code b_tok_is ↻ b_motion sys_mmap ↻ b_token ↻ b_tok_is ↻ b_parse_fx ↻

structs

none

consts

32const FK_MAGIC_8388607: i64 = 8388607
33const FK_MAGIC_4096: i64 = 4096
34const FK_MAGIC_5000: i64 = 5000
35const FK_MAGIC_4900: i64 = 4900
36const FK_MAGIC_5100: i64 = 5100
37const FK_MAGIC_4000: i64 = 4000
38const FK_MAGIC_1500: i64 = 1500
39const FK_MAGIC_7500: i64 = 7500
40const FK_MAGIC_3500: i64 = 3500
42const FK_KATBUF: i64 = 4096
43const FK_LENTOL: i64 = 40 // permitted |measured-declared| in file-units x1000 (fixed-point)
60const FK_MM_DIV: i64 = 100
61const FK_BONE_R: i64 = 14 // bone half-width in mm
62const FK_TRI_REC: i64 = 84
63const FK_HDR: i64 = 16
64const FK_COL_R: i64 = 900 // per-mille colour, per the heatmap convention
65const FK_COL_G: i64 = 620
66const FK_COL_B: i64 = 300

functions

69func fk_f32bits(v: i64) -> i64
called by 1: fk_tri
85func fk_w32(b: *u8, o: i64, v: i64) -> i64
called by 2: fk_trifk_emit_mesh
94func fk_tri(b: *u8, t: i64, p: *i64, nx: i64, ny: i64, nz: i64) -> i64
called by 1: fk_bone_box calls 2: fk_w32fk_f32bits
117func fk_bone_box(b: *u8, t0: i64, ax: i64, ay: i64, az: i64, bx: i64, by: i64, bz: i64) -> i64
called by 1: fk_emit_mesh calls 1: fk_tri
172func fk_emit_mesh(H: *i64, parent: *i64, pos: *i64, outp: *u8) -> i64
called by 1: main calls 4: fk_w32fk_bone_boxgv_putsgv_num
203func fk_cat(b: *u8, o: i64, s: *u8) -> i64
called by 1: fk_fixture
210func fk_fixture(b: *u8, row: *u8) -> i64
called by 1: fk_kat calls 1: fk_cat
225func fk_kat() -> i64
335func fk_load(path: *u8, H: *i64, names: *u8, parent: *i64, nchan: *i64, chan0: *i64,
348func main(argc: i64, argv: *i64) -> i64