nx_bvh_lib.nx
buildroot/runtime/nx_bvh_lib.nx
about
nx_bvh_lib.nx -- SHARED BVH (BioVision Hierarchy) PARSING SUBSTRATE.
Extracted 2026-08-07 when the second consumer appeared (nx_bvhfk, forward kinematics) rather than
copy-pasting the tokenizer into it -- Rule 15, and Rule 9: this library PARSES, it does not
interpret. Kinematics, census and rendering are separate organs on top of it.
NAMING: nx_bvh.nx is a BOUNDING VOLUME HIERARCHY for the slicer. This file and its consumers are
the MOTION-CAPTURE bvh. The collision already cost one false capability reading.
*THE FILE CARRIES ITS OWN ANSWER KEY: a BVH declares a joint tree whose CHANNELS sum to an exact
per-frame width, then prints rows of that width. b_motion PROVES that identity before returning,
so a hierarchy parse that is wrong by a single channel REFUSES instead of silently mis-slicing
every frame. Verified against two independent real files (19 joints/60 chan/455 frames = 27,300
values; 55 joints/168 chan/69 frames = 11,592 values), both exact.
UNITS ARE DECLARED, NEVER IMPLIED:
OFFSET + positional channels = file units x B_SCALE (1000). BVH does not state its unit in the
format; the convention is centimetres, so we do NOT claim mm.
rotational channels = degrees x B_SCALE (1000) = millidegrees.
frame time = MICROSECONDS (x B_TSCALE); fps is DERIVED, never assumed 30.
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 1 imports · 5 importers
imports: nx_syscalls.nx
imported by: nx_bvhfk.nxnx_bvhfk_lib.nxnx_bvhmotion.nxnx_clipcheck.nxnx_dance_emit.nx
structs
| none |
consts
| 25 | const B_SCALE: i64 = 1000 |
| 26 | const B_TSCALE: i64 = 1000000 |
| 27 | const B_MAX_JOINTS: i64 = 256 |
| 28 | const B_MAX_CHAN: i64 = 1024 |
| 29 | const B_NAMEW: i64 = 32 |
| 30 | const B_TOKW: i64 = 64 |
| 31 | const B_TEN: i64 = 10 |
| 33 | const B_CH_XPOS: i64 = 0 |
| 34 | const B_CH_YPOS: i64 = 1 |
| 35 | const B_CH_ZPOS: i64 = 2 |
| 36 | const B_CH_XROT: i64 = 3 |
| 37 | const B_CH_YROT: i64 = 4 |
| 38 | const B_CH_ZROT: i64 = 5 |
| 39 | const B_CH_BAD: i64 = 0 - 1 |
| 41 | const B_H_NJOINT: i64 = 0 |
| 42 | const B_H_NCHAN: i64 = 1 |
| 43 | const B_H_NFRAME: i64 = 2 |
| 44 | const B_H_FTIME: i64 = 3 |
| 45 | const B_H_MOTOFF: i64 = 4 |
| 46 | const B_H_WORDS: i64 = 8 |
| 48 | const B_R_NOHIER: i64 = 0 - 1 |
| 49 | const B_R_NOMOTION:i64 = 0 - 2 |
| 50 | const B_R_CAP: i64 = 0 - 3 |
| 51 | const B_R_WIDTH: i64 = 0 - 4 |
| 52 | const B_R_FRAMES: i64 = 0 - 5 |
| 53 | const B_R_CHAN: i64 = 0 - 6 |
| 54 | const B_R_FRAMEIDX:i64 = 0 - 7 |
functions
| 56 | func b_slen(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { i = i + 1 } return i } |
| 57 | func b_puts(s: *u8) -> i64 { sys_write(1, s, b_slen(s)); return 0 } |
| 59 | func b_num(v: i64) -> i64 |
| 74 | func b_is_space(c: i64) -> i64 called by 1: b_token |
| 86 | func b_token(buf: *u8, len: i64, pos: *i64, tok: *u8) -> i64 |
| 123 | func b_tok_is(tok: *u8, n: i64, s: *u8) -> i64 |
| 131 | func b_parse_fx(tok: *u8, n: i64, scale: i64) -> i64 |
| 201 | func b_chan_code(tok: *u8, n: i64) -> i64 |
| 211 | func b_hierarchy(buf: *u8, len: i64, pos: *i64, H: *i64, |
| 295 | func b_motion(buf: *u8, len: i64, pos: *i64, H: *i64) -> i64 |
| 328 | func b_refuse(code: i64) -> i64 |
| 341 | func b_parse(buf: *u8, len: i64, H: *i64, names: *u8, parent: *i64, |
| 351 | func b_frame_values(buf: *u8, len: i64, H: *i64, frame: i64, out: *i64) -> i64 |