nx_partloft_lib.nx
buildroot/runtime/nx_partloft_lib.nx
about
nx_partloft_lib.nx -- THE LOFTED PART: Infinigen's NurbsPart, replicated in NishiLang from the first byte up
(procgen PG59 / anatomy AN19, 2026-09-19). Operator standing order the same day: the estate uses the best-in-class
published method as its BASELINE and improves it piece by piece; the ellipsoid-union skull is retired. This file is
the first piece. ONE part = a skeleton polyline with a normalised profile at every station, DECOMPOSED into the genes
the Infinigen creature system mutates, RECOMPOSED into a grid of NURBS control handles, EVALUATED as a cubic B-spline
surface, and WRITTEN as NXMSH2 through the estate's one mesh layout (nx_nxmesh_lib). Read from the primary source,
mirrored under knowledge/fetched/ and pinned on procgen.refs:
infinigen/assets/creatures/parts/generic_nurbs.py decompose_nurbs_handles / recompose_nurbs_handles /
NurbsPart.sample_params (the gene noise STRUCTURE)
infinigen/assets/creatures/util/geometry/lofting.py factorize_nurbs_handles, skeleton_to_tangents,
compute_profile_verts (frames by rotate_match_directions)
infinigen/assets/creatures/util/geometry/nurbs.py geomdl_nurbs: degree (3,3), clamped uniform u knots, cyclic v
wrapping three control points, sample_size from face_size
infinigen/assets/creatures/util/part_util.py nurbs_to_part: the attachment skeleton is the INTERIOR rows
infinigen/assets/creatures/util/creature.py apply_attach_transform: (u, v, rad) surface coordinates
CONVENTIONS, THEIRS: a part runs along +x (profiles face +x), y is lateral, z is up; skeleton_yoffs is the lateral
drift per segment and thetas the pitch in the xz plane (degrees there, VM_ONE radians here).
UNITS, OURS, and there are exactly three: POSITIONS in tenths of a millimetre (u10, NM_UNIT_PER_M, the NXMSH2
ruler's unit); FRACTIONS in PL_FQ = 65536 (Q16) -- gene proportions, lateral drifts, station parameters, normalised
profiles, surface parameters, the attachment coordinates, the gene variance, and the B-spline knots and basis; and
ANGLES in VM_ONE radians (Q12), the estate's one trigonometric unit, for the pitch genes and the yaw. A radius is a
position with sixteen fractional bits (Q16 u10), because a profile normalised by a radius rounded to 0.1 mm was
measured 0.25 percent off at 20 mm and would be 2.5 percent off on a finger: MEASURED on the first run of the gate,
where Q12 proportions truncated to whole u10 per segment lost 0.5 percent of a part's length (995 for 1000). Every
division that lands on a stored value rounds to nearest (pl_rdiv); truncation is how that half-percent was lost.
No float anywhere: the file's float32 is encoded once, at the door, by nx_nxmesh_lib / nx_vecmath.
DECLARED DEVIATIONS (each a rung on procgen, never a silent difference):
1. np.random.normal is Irwin-Hall (twelve uniforms of a 31-bit LCG): same mean and variance, tails end at six
sigma. The STRUCTURE of the noise is the source's exactly: one size draw, one length draw, one shared radius
draw plus one per station, one per proportion, zero-meaned pitch noise, per-column times per-cell profile noise
mirrored across the profile.
2. The attachment ray-cast against a BVH is a parametric search: around the requested station the closed profile
is searched for the point nearest the ray (least perpendicular distance, in front of the origin), coarse then
bisected, over a one-segment window of u.
3. The attachment skeleton is the clamped cubic B-spline of the interior rows, where the source runs two
Catmull-Clark levels over the interior polyline (the limit of that subdivision IS the cubic B-spline).
4. The emitted mesh carries two fan caps so the part is a closed solid for the lattice fusion; the source leaves
the tube open and lets remesh close it. Winding is made outward per triangle here; the source runs
normals_make_consistent.
LIB, no main. license_tier: ORIGINAL (a re-implementation from a read of BSD-3 source; no source bytes copied; the
dependencies 4 imports · 2 importers
imports: nx_syscalls.nxnx_vecmath.nxnx_nxmesh_lib.nxnx_itoa_lib.nx
imported by: nx_partloft_capture_t319.nxnx_partloft_gate.nx
structs
| 106 | struct PlPart { nu: i64, nv: i64, root: *i64, length: i64, prop: *i64, theta: *i64, yoff: *i64, rad: *i64, ts: *i64, prof: *i64, skel: *i64, tang: *i64, hnd: *i64, ku: *i64, kv: *i64, ka: *i64, bu: *i64, bv: *i64, bl: *i64, br: *i64 } |
consts
| 47 | const PL_ONE: i64 = 4096 // VM_ONE spelled once here, the ANGLE and unit-vector unit; the gate asserts the two agree |
| 48 | const PL_FQ: i64 = 65536 // the FRACTION unit (Q16): genes, parameters, knots, basis |
| 49 | const PL_FQ2: i64 = 4294967296 // PL_FQ squared: the divisor that takes a Q16 profile times a Q16 radius back to u10 |
| 50 | const PL_FQ_SHIFT: i64 = 16 |
| 51 | const PL_FQ_HALF_SHIFT: i64 = 8 // sqrt(x << 16) << 8 = sqrt(x) << 16: a length with sixteen fractional bits |
| 52 | const PL_DEG: i64 = 3 // degree_u, degree_v = (3, 3): nurbs.py geomdl_nurbs |
| 53 | const PL_ORD: i64 = 4 // PL_DEG + 1 nonzero basis functions on any span |
| 54 | const PL_I64: i64 = 8 |
| 55 | const PL_V3: i64 = 3 |
| 56 | const PL_Q4: i64 = 4 |
| 57 | const PL_PART_BYTES: i64 = 256 // PlPart: 21 words, one page-rounded map |
| 58 | const PL_MIN_RAD: i64 = 65536 // rads clipped to at least one u10 (Q16): np.clip(rads, 1e-3 m, 1e5 m) |
| 59 | const PL_MIN_NU: i64 = 4 // a clamped cubic needs four control rows |
| 60 | const PL_MIN_NV: i64 = 3 // and a periodic cubic three columns |
| 61 | const PL_GAUSS_N: i64 = 12 // Irwin-Hall count: the variance of a sum of n uniforms is n/12, one at twelve |
| 62 | const PL_LCG_MUL: i64 = 1103515245 // the ANSI C rand() recurrence, a published constant |
| 63 | const PL_LCG_ADD: i64 = 12345 |
| 64 | const PL_LCG_MOD: i64 = 2147483648 // 2^31: state times multiplier stays under 2^62 |
| 65 | const PL_LCG_SHIFT: i64 = 16 // the low bits of an LCG are its weakest, discarded |
| 66 | const PL_LCG_BITS: i64 = 32768 // 2^15 output range after the shift |
| 70 | const PL_SD_SIZE: i64 = 6554 // sz = N(1, 0.1) |
| 71 | const PL_SD_LENGTH: i64 = 6554 // length *= sz * N(1, 0.1) |
| 72 | const PL_SD_RADS: i64 = 6554 // rads *= sz * N(1, 0.1) ... |
| 73 | const PL_SD_RAD_STATION: i64 = 9830 // ... * N(1, 0.15) per station |
| 74 | const PL_SD_PROP: i64 = 9830 // proportions *= N(1, 0.15) per segment |
| 75 | const PL_SD_THETA: i64 = 500 // thetas += N(0, 7 deg) per segment, zero-meaned (VM_ONE radians) |
| 76 | const PL_SD_PROF_COL: i64 = 4587 // profile noise N(1, 0.07) per column ... |
| 77 | const PL_SD_PROF_CELL: i64 = 9830 // ... times N(1, 0.15) per cell |
| 78 | const PL_SEARCH_COARSE: i64 = 64 // attachment search: samples around the ring before the bisection |
| 79 | const PL_SEARCH_REFINE: i64 = 12 // bisection steps after the coarse pass |
| 80 | const PL_SEARCH_UHALF: i64 = 2 // u window: this many quarter-segments either side of the station |
| 81 | const PL_SEARCH_UQUART: i64 = 4 // a segment is split in this many steps for the window |
| 82 | const PL_FD_STEP: i64 = 256 // finite-difference step for tangents and normals, Q16 (1/256 of the domain) |
| 83 | const PL_MAGIC_0: i64 = 78 // N |
| 84 | const PL_MAGIC_1: i64 = 88 // X |
| 85 | const PL_MAGIC_2: i64 = 77 // M |
| 86 | const PL_MAGIC_3: i64 = 83 // S |
| 87 | const PL_MAGIC_4: i64 = 72 // H |
| 88 | const PL_MAGIC_5: i64 = 50 // 2 |
| 89 | const PL_LAYER_START_OFF: i64 = 16 // within a 24-byte layer record: 16 name bytes, then start u32, then count u32 |
| 90 | const PL_LAYER_COUNT_OFF: i64 = 20 |
| 91 | const PL_OFF_NORMALS: i64 = 36 // byte offset of the three per-vertex normals within a triangle record |
| 92 | const PL_COL_BONE_R: i64 = 900 // the part's default colour, per-mille: a bone tint a viewer renders as bone |
| 93 | const PL_COL_BONE_G: i64 = 880 |
| 94 | const PL_COL_BONE_B: i64 = 840 |
| 95 | const PL_MIN_RING: i64 = 3 // a cap fan needs three ring points |
| 96 | const PL_SAVE_DIGITS: i64 = 16 // bytes reserved per integer on save: sign, 14 digits, separator |
| 97 | const PL_SAVE_HEADER: i64 = 64 |
| 98 | const PL_MODE644: i64 = 420 |
| 99 | const PL_LOAD_HDR: i64 = 16 // the two-word length record sys_read_file fills |
| 100 | const PL_FMT_VERSION: i64 = 2 // version 2: Q16 fractions and Q16 radii (version 1 was Q12, never shipped) |
| 101 | const PL_HEADER_INTS: i64 = 7 // version nu nv root(3) length |
| 102 | const PL_ASKEL_SPLINE: i64 = 1 // pl_askel took the cubic path (four or more interior rows) |
| 103 | const PL_ASKEL_LINEAR: i64 = 2 // pl_askel took the linear path (fewer) |
| 104 | const PL_POS_HUGE: i64 = 1000000000000000000 |
functions
| 108 | func pl_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } |
| 110 | func pl_rdiv(a: i64, b: i64) -> i64 { if a >= 0 { return (a + b/2) / b } return (a - b/2) / b } |
| 111 | func pl_len3(x: i64, y: i64, z: i64) -> i64 { return vm_isqrt(x*x + y*y + z*z) } |
| 113 | func pl_len3_fx(x: i64, y: i64, z: i64) -> i64 { return vm_isqrt((x*x + y*y + z*z) << PL_FQ_SHIFT) << PL_FQ_HALF_SHIFT } |
| 115 | func pl_unit(o: *i64, a: *i64) -> i64 |
| 122 | func pl_rad_u10(p: *PlPart, i: i64) -> i64 { return pl_rdiv(p.rad[i], PL_FQ) } |
| 129 | func pl_knots(p: *PlPart) -> i64 |
| 165 | func pl_new(nu: i64, nv: i64) -> *PlPart |
| 190 | func pl_copy(dst: *PlPart, src: *PlPart) -> i64 |
| 211 | func pl_rot_match(q: *i64, a: *i64, b: *i64) -> i64 |
| 224 | func pl_tangents(skel: *i64, n: i64, tang: *i64, edge: *i64) -> i64 |
| 258 | func pl_decompose(hnd: *i64, nu: i64, nv: i64, p: *PlPart) -> i64 |
| 332 | func pl_recompose(p: *PlPart) -> i64 |
| 401 | func pl_lcg(st: *i64) -> i64 called by 1: pl_urand |
| 406 | func pl_urand(st: *i64) -> i64 { return pl_lcg(st) * PL_FQ / PL_LCG_BITS } |
| 408 | func pl_nrand(st: *i64) -> i64 |
| 416 | func pl_normal(st: *i64, mean: i64, sd: i64, var_: i64) -> i64 |
| 423 | func pl_mutate(p: *PlPart, seed: i64, var_: i64) -> i64 |
| 485 | func pl_span(U: *i64, ncp: i64, x: i64) -> i64 |
| 494 | func pl_basis(U: *i64, k: i64, x: i64, N: *i64, left: *i64, right: *i64) -> i64 |
| 516 | func pl_surface(p: *PlPart, u: i64, v: i64, out: *i64) -> i64 |
| 554 | func pl_askel_point(p: *PlPart, t: i64, out: *i64) -> i64 |
| 591 | func pl_askel(p: *PlPart, t: i64, out: *i64, tan: *i64) -> i64 |
| 611 | func pl_ray_perp2(p: *PlPart, u: i64, v: i64, o: *i64, dw: *i64, s: *i64) -> i64 |
| 625 | func pl_surface_at(p: *PlPart, t: i64, yaw: i64, rad: i64, out: *i64, nrm: *i64, tan: *i64, info: *i64) -> i64 |
| 727 | func pl_mesh_counts(p: *PlPart, face: i64, out: *i64) -> i64 |
| 771 | func pl_put_tri(B: *u8, tb: i64, t: i64, V: *i64, ia: i64, ib: i64, ic: i64, ox: i64, oy: i64, oz: i64, xyz9: *i64) -> i64 |
| 806 | func pl_mesh_write(p: *PlPart, face: i64, path: *u8, rep: *i64) -> i64 |
| 908 | func pl_save_ints(fb: *u8, fo: i64, A: *i64, n: i64) -> i64 |
| 920 | func pl_save(path: *u8, p: *PlPart) -> i64 |
| 952 | func pl_tok(buf: *u8, n: i64, pos: *i64, out: *i64) -> i64 |
| 985 | func pl_load_ints(buf: *u8, n: i64, pos: *i64, A: *i64, cnt: i64, tok: *i64) -> i64 |
| 996 | func pl_load(path: *u8) -> *PlPart |