nx_softtissue.nx
buildroot/runtime/nx_softtissue.nx
about
nx_softtissue.nx -- SOVEREIGN soft-tissue solver: XPBD over a tetrahedral physics cage
with per-layer compliance. THE tier our body physics did not have.
WHY THIS EXISTS (measured, 2026-07-30): the rigmesh viewer drives breasts with a 2-mass
EMA spring (a damped oscillator with a calibrated gain). An oscillator has no VOLUME, no
LAYERS and no relationship to gravity DIRECTION -- so it physically cannot reproduce the
one behavior a human notices instantly: when a woman lies down, soft heavy tissue FLATTENS
and spreads toward the chest wall, and firm tissue does so much less. Our own ecosystem
already MEASURES that behavior -- nx_breast_drape_pose.nx bands LAYING_BACK at
aspect 716..921 / centroid 410..614 against STANDING_FACING 1024..1331 / 614..768 -- so a
ruler existed for a simulator that did not. This organ is the simulator; that validator is
its oracle (see nx_softtissue_gate.nx). Same solver serves buttocks, thigh and abdomen:
the tissue differs only by PROFILE ROWS, never by code (rule 11, rule 25).
METHOD (XPBD, Macklin et al. -- position-based, so it cannot blow up like a force solver):
per substep: predict -> solve constraints N times -> derive velocity -> damp
constraints: distance (edges) | volume (Neo-Hookean incompressibility, C = 6V - 6V0)
| contact (sphere/capsule = a finger or a surgical instrument)
| attachment (chest-wall particles pinned, inverse mass 0)
compliance: alpha_tilde = alpha / dt^2, per LAYER, from data rows. alpha 0 = rigid
(muscle, Cooper's ligament), alpha large = soft (adipose).
WHY IT CANNOT INVERT: the volume constraint's correction magnitude scales as 1/(6V) as the
element collapses, so resistance rises without bound as det F -> 0. Tissue gets HARDER the
harder it is pressed -- the same qualitative guarantee the Neo-Hookean strain-energy
barrier gives, which is why a deep press dimples instead of exploding. Proven by tooth, not
asserted: the gate presses a capsule 60% into the cage and asserts every 6V stays > 0.
UNITS: positions in cmm (0.01 mm) -- the NXA VERT unit, so cage and mesh share a frame.
H=171530 cmm = 1.7153 m. Scalars q12 (4096=1.0), compliance q20 (1048576=1.0).
Velocity cmm/s. dt in microseconds. Frame: +x lateral, +y cranial, +z anterior.
Gravity is a UNIT VECTOR in that body frame -- standing (0,-1,0), supine (0,0,-1).
That single input is what makes lying-down flattening emergent, not scripted.
QUANTIZATION (honest): positions are integer cmm, so one substep's displacement carries
~1 cmm of rounding. st_div_r rounds to NEAREST (not toward zero) so the error does
not bias into fake damping -- a truncating divide would silently drain energy and
read as viscosity we did not model.
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 2 imports · 4 importers
imports: nx_syscalls.nxnx_proportion_guard.nx
imported by: nx_proportion_guard_gate.nxnx_softtissue_diss_gate.nxnx_softtissue_gate.nxnx_softtissue_rot_gate.nx
structs
| none |
consts
| 41 | const ST_MAGIC_1229: i64 = 1229 |
| 42 | const ST_MAGIC_12288: i64 = 12288 |
| 43 | const ST_MAGIC_20972: i64 = 20972 |
| 44 | const ST_MAGIC_1434: i64 = 1434 |
| 45 | const ST_MAGIC_2654435761: i64 = 2654435761 |
| 46 | const ST_MAGIC_1013904223: i64 = 1013904223 |
| 47 | const ST_MAGIC_1442695040888963407: i64 = 1442695040888963407 |
| 48 | const ST_MAGIC_2246822519: i64 = 2246822519 |
| 49 | const ST_MAGIC_288230376151711743: i64 = 288230376151711743 |
| 50 | const ST_MAGIC_1050: i64 = 1050 |
| 51 | const ST_MAGIC_9216: i64 = 9216 |
| 52 | const ST_MAGIC_1024: i64 = 1024 |
| 53 | const ST_MAGIC_4096: i64 = 4096 |
| 54 | const ST_MAGIC_22528: i64 = 22528 |
| 55 | const ST_MAGIC_2048: i64 = 2048 |
| 56 | const ST_MAGIC_8192: i64 = 8192 |
| 57 | const ST_MAGIC_24576: i64 = 24576 |
| 58 | const ST_MAGIC_20480: i64 = 20480 |
| 59 | const ST_MAGIC_1000000: i64 = 1000000 |
| 60 | const ST_MAGIC_999999999: i64 = 999999999 |
| 61 | const ST_MAGIC_999999999999999: i64 = 999999999999999 |
| 64 | const ST_MAXP: i64 = 8192 |
| 65 | const ST_MAXT: i64 = 16384 |
| 66 | const ST_MAXE: i64 = 49152 |
| 69 | const ST_LAY_MUSCLE: i64 = 0 |
| 70 | const ST_LAY_GLAND: i64 = 1 |
| 71 | const ST_LAY_ADIPOSE: i64 = 2 |
| 72 | const ST_LAY_SKIN: i64 = 3 |
| 73 | const ST_LAY_LIGAMENT: i64 = 4 |
| 74 | const ST_LAY_N: i64 = 5 |
| 77 | const ST_W_NP: i64 = 0 |
| 78 | const ST_W_NT: i64 = 1 |
| 79 | const ST_W_NE: i64 = 2 |
| 80 | const ST_W_PX: i64 = 3 |
| 81 | const ST_W_PY: i64 = 4 |
| 82 | const ST_W_PZ: i64 = 5 |
| 83 | const ST_W_QX: i64 = 6 |
| 84 | const ST_W_QY: i64 = 7 |
| 85 | const ST_W_QZ: i64 = 8 |
| 86 | const ST_W_VX: i64 = 9 |
| 87 | const ST_W_VY: i64 = 10 |
| 88 | const ST_W_VZ: i64 = 11 |
| 89 | const ST_W_IW: i64 = 12 |
| 90 | const ST_W_LAY: i64 = 13 |
| 91 | const ST_W_TET: i64 = 14 |
| 92 | const ST_W_TRV: i64 = 15 |
| 93 | const ST_W_TLA: i64 = 16 |
| 94 | const ST_W_TLM: i64 = 17 |
| 95 | const ST_W_EDG: i64 = 18 |
| 96 | const ST_W_ERL: i64 = 19 |
| 97 | const ST_W_ELA: i64 = 20 |
| 98 | const ST_W_ELM: i64 = 21 |
| 99 | const ST_W_SRF: i64 = 22 |
| 100 | const ST_W_TON: i64 = 23 |
| 101 | const ST_W_TCX: i64 = 24 |
| 102 | const ST_W_TCY: i64 = 25 |
| 103 | const ST_W_TCZ: i64 = 26 |
| 104 | const ST_W_TR: i64 = 27 |
| 105 | const ST_W_PROF:i64 = 28 |
| 106 | const ST_W_SLOTS: i64 = 40 |
| 109 | const ST_PF_A_MM: i64 = 0 |
| 110 | const ST_PF_B_MM: i64 = 1 |
| 111 | const ST_PF_C_MM: i64 = 2 |
| 112 | const ST_PF_GLAND_PCT: i64 = 3 |
| 113 | const ST_PF_LIG_ALPHA: i64 = 4 |
| 114 | const ST_PF_FAT_ALPHA: i64 = 5 |
| 115 | const ST_PF_FAT_DAMP: i64 = 6 |
| 116 | const ST_PF_RIB_R_MM: i64 = 7 |
| 125 | const ST_PF_SKIN_ALPHA: i64 = 8 |
| 126 | const ST_PF_N: i64 = 9 |
| 128 | const ST_PROF_LARGE_SOFT: i64 = 0 |
| 129 | const ST_PROF_SMALL_FIRM: i64 = 1 |
| 130 | const ST_PROF_GLUTE: i64 = 2 |
| 133 | const ST_PROF_SOFT_TAUT: i64 = 3 |
| 140 | const ST_PROF_SEED_BASE: i64 = 1000 |
| 142 | const ST_Q12: i64 = 4096 |
| 143 | const ST_Q20: i64 = 1048576 |
| 144 | const ST_GRAV_CMM: i64 = 981000 |
| 150 | const ST_GRAD_SHIFT: i64 = 1 |
| 154 | const ST_DT_REF_US: i64 = 4167 |
| 950 | const ST_M_ASPECT: i64 = 0 |
| 951 | const ST_M_CENTROID: i64 = 1 |
| 952 | const ST_M_MINVOL: i64 = 2 |
| 953 | const ST_M_SUMVOL: i64 = 3 |
| 954 | const ST_M_KIN: i64 = 4 |
| 955 | const ST_M_NSURF: i64 = 5 |
| 956 | const ST_M_PROJ: i64 = 6 |
| 957 | const ST_M_N: i64 = 8 |
functions
| 157 | func st_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } |
| 158 | func st_min(a: i64, b: i64) -> i64 { if a < b { return a } return b } |
| 159 | func st_max(a: i64, b: i64) -> i64 { if a > b { return a } return b } |
| 163 | func st_div_r(a: i64, b: i64) -> i64 |
| 169 | func st_isqrt(n: i64) -> i64 |
| 189 | func st_layer_alpha_dist(l: i64) -> i64 |
| 200 | func st_layer_alpha_vol(l: i64) -> i64 called by 1: st_new |
| 210 | func st_layer_damp(l: i64) -> i64 called by 1: st_eff_damp |
| 228 | func st_hash(seed: i64, salt: i64) -> i64 |
| 238 | func st_span(seed: i64, salt: i64, lo: i64, hi: i64) -> i64 |
| 251 | func st_profile_seeded(seed: i64, field: i64) -> i64 |
| 277 | func st_profile(prof: i64, field: i64) -> i64 called by 6: mainst_profilest_eff_alpha_distst_eff_dampst_newmain calls 2: st_profile_seededst_profile |
| 324 | func st_wall_drop(xm: i64, rib_r: i64) -> i64 |
| 333 | func st_eff_alpha_dist(W: *i64, layer: i64) -> i64 |
| 340 | func st_eff_damp(W: *i64, layer: i64) -> i64 |
| 353 | func st_alpha_tilde(alpha_q12: i64, dsum: i64, dt_us: i64) -> i64 |
| 365 | func st_inside(xm: i64, ym: i64, zm: i64, a: i64, b: i64, c: i64) -> i64 called by 1: st_new |
| 373 | func st_six_vol(W: *i64, i0: i64, i1: i64, i2: i64, i3: i64) -> i64 |
| 390 | func st_six_vol_q(W: *i64, i0: i64, i1: i64, i2: i64, i3: i64) -> i64 calls 1: st_div_r |
| 406 | func st_add_edge(W: *i64, htab: *i64, hidx: *i64, hmask: i64, |
| 453 | func st_new(prof: i64, h_mm: i64) -> *i64 called by 4: mainsg_settlemainmain calls 7: sys_mmapst_profilest_insidest_wall_dropst_six_volst_layer_alpha_vol+1 |
| 716 | func st_reset_state(W: *i64) -> i64 |
| 725 | func st_set_touch(W: *i64, on: i64, cx: i64, cy: i64, cz: i64, r: i64) -> i64 called by 1: main |
| 735 | func st_substep(W: *i64, gx: i64, gy: i64, gz: i64, dt_us: i64, iters: i64) -> i64 |
| 943 | func st_run(W: *i64, gx: i64, gy: i64, gz: i64, steps: i64, dt_us: i64, iters: i64) -> i64 |
| 963 | func st_measure(W: *i64, out: *i64) -> i64 |