code wiki / (root) / nx_skeleton.nx

nx_skeleton.nx

buildroot/runtime/nx_skeleton.nx

10006 B216 linesdepth 2pulls 3 transitivereach 209 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_skeleton.nx -- SKELETON + LINEAR-BLEND SKINNING (the character-foundation rung everything Elara needs hangs off: morphs, IK, jiggle-region binding, posing -- VAMX ladder R3, rides nx_mesh3 + nx_itrig per the reuse law). BONES ARE DATA: a rig is rows {parent, local offset, yaw, pitch} a mod can ship. World pose = parent-composed integer 3x3 rotations (fx256) + offsets (fx256). Skinned vertex = sum of per-bone weighted transforms of the vertex's BONE-LOCAL position (LBS, weights fx256 summing 256). ALL INTEGER => deterministic, VM-vettable, wasm-ready (base-relative). license_tier: ORIGINAL --- 2026-08-23 CAPACITY IS NOW DERIVED FROM THE ASSET, NOT A COMPILE-TIME CEILING --------------- MEASURED DEFECT: this lib carried SK_MAXB=32 bones and SK_MAXV=2048 verts as hard constants while the estate's real rigged corpus is 104-370 joints and 14,164-423,919 vertices -- an 11.6x bone and 207x vertex overflow. The only in-engine skinning evaluator was therefore DIMENSIONALLY INCAPABLE of posing a single real character, which is the mechanical reason the served worlds render the visiting cast in static bind pose: there was nothing callable to pose them with. A cap that is smaller than its subject does not truncate loudly, it makes the whole capability unreachable. FIX (the banked law: a buffer cap is not a number to tune -- REMOVE it): there is no ceiling any more. The caller declares capacity from the ASSET'S OWN header counts via sk_init_cap, the arena size comes from sk_bytes_for, and every offset is computed from the stored capacity at runtime. SK_DEF_* below are NOT caps: they are the legacy constructor's defaults, kept so that every existing caller of sk_init/sk_bytes gets byte-identical behaviour (see the stride note). INFLUENCES ARE ALSO DERIVED: v1 hard-wired 2 bones per vertex; real SKIN sections carry their own per-vertex influence count, so the vertex record is now (2*ninf pairs + 3 position) slots. The stride is (2*ninf+4)*8 bytes -- one spare slot -- which at the legacy ninf=2 is EXACTLY the old 64-byte stride, so the legacy arena layout is reproduced bit-for-bit and prior gates are unaffected.

dependencies 2 imports · 51 importers

nx_syscalls.nx nx_itrig.nx nx_skeleton.nx nx_bodybind.nx nx_bodypose.nx nx_craft_before_placement_t316.nx nx_creature_motion.nx nx_creature_motion_gate.nx nx_figure_render.nx nx_gate_rig_motion_20260909.nx nx_gate_rig_motion_context_t140.nx nx_gate_rig_motion_palette_t140.nx nx_gate_rig_motion_stream_t140.nx

diagram shows first 10 each side; +0 more imports, +41 more importers in the complete lists below.

imports: nx_syscalls.nxnx_itrig.nx

imported by: nx_bodybind.nxnx_bodypose.nxnx_craft_before_placement_t316.nxnx_creature_motion.nxnx_creature_motion_gate.nxnx_figure_render.nxnx_gate_rig_motion_20260909.nxnx_gate_rig_motion_context_t140.nxnx_gate_rig_motion_palette_t140.nxnx_gate_rig_motion_stream_t140.nxnx_ik.nxnx_motion_neural_gate.nxnx_motion_photo_gate.nxnx_motion_video_gate.nxnx_movelib.nxnx_movement_base_engine_t139.nxnx_nxa_play.nxnx_nxa_retarget.nxnx_pose_retarget.nxnx_pose_retarget_gate.nxnx_skeleton_gate.nxnx_synth_serve.nxnx_text2motion_gate.nxnx_wasm_charlab.nxnx_wasm_craft.nxnx_wasm_craft_body_t137.nxnx_wasm_craft_contact_candidate.nxnx_wasm_craft_dunes_t70.nxnx_wasm_craft_gait_candidate.nxnx_wasm_craft_gait_candidate_t139.nxnx_wasm_craft_imported_body_t41.nxnx_wasm_craft_imported_body_t42.nxnx_wasm_craft_imported_body_t49.nxnx_wasm_craft_imported_t262.nxnx_wasm_craft_inspection_bounds_t181.nxnx_wasm_craft_inspection_distance_t218.nxnx_wasm_craft_inspection_t142.nxnx_wasm_craft_journal_index_t21.nxnx_wasm_craft_journal_index_t21_before_t44.nxnx_wasm_craft_lookup_candidate.nxnx_wasm_craft_move_t72.nxnx_wasm_craft_pre_inspection_t142.nxnx_wasm_craft_recovery_t20.nxnx_wasm_craft_relief_adopt_t143.nxnx_wasm_craft_relief_save_t143.nxnx_wasm_craft_relief_t143.nxnx_wasm_craft_residency_t44.nxnx_wasm_craft_turn_candidate_t139.nxnx_wasm_craft_visitors_canonical_t142.nxnx_wasm_craft_visitors_inspection_t142.nxnx_wasm_craft_visitors_t140.nx

structs

none

consts

34const SK_DEF_B: i64 = 32
35const SK_DEF_V: i64 = 2048
36const SK_DEF_INF: i64 = 2

functions

42func sk_hdr(base: i64) -> *i64 { return base as *i64 }
43func sk_lr(base: i64) -> *i64 { return (base + 16) as *i64 }
called by 1: sk_update
44func sk_vs(base: i64) -> *i64 { return (base + 88) as *i64 }
45func sk_capb(base: i64) -> i64 { let h: *i64 = sk_hdr(base); return h[14] }
called by 3: sk_vertsk_outsk_add_bone calls 1: sk_hdr
46func sk_capv(base: i64) -> i64 { let h: *i64 = sk_hdr(base); return h[15] }
47func sk_ninf(base: i64) -> i64 { let h: *i64 = sk_hdr(base); return h[16] }
49func sk_vstride(base: i64) -> i64 { return (2 * sk_ninf(base) + 4) * 8 }
called by 2: sk_vertsk_out calls 1: sk_ninf
50func sk_bone(base: i64, i: i64) -> *i64 { return (base + 256 + i * 256) as *i64 }
51func sk_vert(base: i64, i: i64) -> *i64 { return (base + 256 + sk_capb(base) * 256 + i * sk_vstride(base)) as *i64 }
52func sk_out(base: i64, i: i64) -> *i64 { return (base + 256 + sk_capb(base) * 256 + sk_capv(base) * sk_vstride(base) + i * 24) as *i64 }
54func sk_bytes_for(capb: i64, capv: i64, ninf: i64) -> i64 { return 256 + capb * 256 + capv * ((2 * ninf + 4) * 8) + capv * 24 + 64 }
called by 3: mainmainsk_bytes
55func sk_bytes() -> i64 { return sk_bytes_for(SK_DEF_B, SK_DEF_V, SK_DEF_INF) }
called by 17: mainmainmainmainmainmain+11 calls 1: sk_bytes_for
60func sk_init_cap(base: i64, capb: i64, capv: i64, ninf: i64) -> i64
called by 3: mainmainsk_init calls 1: sk_hdr
72func sk_init(base: i64) -> i64 { return sk_init_cap(base, SK_DEF_B, SK_DEF_V, SK_DEF_INF) }
74func sk_add_bone(base: i64, parent: i64, ox: i64, oy: i64, oz: i64) -> i64
85func sk_pose(base: i64, bone: i64, yaw: i64, pitch: i64) -> i64
92func sk_add_vert(base: i64, b0: i64, w0: i64, b1: i64, w1: i64, lx: i64, ly: i64, lz: i64) -> i64
called by 1: mk_tube calls 4: sk_hdrsk_capvsk_vertsk_ninf
107func sk_add_vert_n(base: i64, bs: *i64, ws: *i64, n: i64, lx: i64, ly: i64, lz: i64) -> i64
127func sk_localrot(yaw: i64, elev: i64, out: *i64) -> i64
143func sk_matmul(a: *i64, b: *i64, out: *i64) -> i64
155func sk_matvec(m: *i64, x: i64, y: i64, z: i64, out: *i64) -> i64
163func sk_update(base: i64) -> i64
190func sk_skin(base: i64) -> i64