nx_softdyn.nx
buildroot/runtime/nx_softdyn.nx
about
nx_softdyn.nx -- LIB: SOVEREIGN SECONDARY DYNAMICS ("jiggle physics"), the general solver every animated
thing inherits. A driven ANCHOR (a bone from the rig, a weapon mount, a hair root) pulls a mass point through
a spring-damper; the mass LAGS under acceleration, OVERSHOOTS when the anchor stops, oscillates, and damps to
rest. The SAME solver serves: soft-tissue inertia on a moving body, firearm RECOIL (impulse), cloth and hair
sway, vehicle suspension. 100% integer + deterministic -> the same motion replays bit-identically.
State stride 6 per point: [px,py,pz, vx,vy,vz] all Q8 (model-units * 256).
Semi-implicit Euler: a = K*(anchor-p)/1024 - C*v/1024 ; v += a ; p += v
K = stiffness per-1024 (how hard tissue is bound to bone), C = damping per-1024 (how fast wobble dies).
Underdamped (C < 2*sqrt(K)) => visible jiggle. Critically/over-damped => rigid, no wobble.
A hard displacement CLAMP makes divergence impossible BY CONSTRUCTION (tissue can never fly off the body).
license_tier: ORIGINAL
dependencies 1 imports · 4 importers
imports: nx_syscalls.nx
imported by: nx_fascia.nxnx_softbind.nxnx_softdyn_gate.nxnx_tissue.nx
structs
| none |
consts
| 15 | const SD_Q8: i64 = 256 |
| 16 | const SD_G: i64 = 1024 |
| 17 | const SD_STRIDE: i64 = 6 |
| 20 | const SD_CAPC: i64 = 1000 |
| 21 | const SD_CAPK: i64 = 3600 |
functions
| 23 | func sd_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } |
| 24 | func sd_isqrt(v: i64) -> i64 { if v <= 0 { return 0 } var x: i64 = v; var y: i64 = (x+1)/2; while y < x { x = y; y = (x + v/x)/2 } return x } |
| 27 | func sd_alloc(n: i64) -> *i64 { return sys_mmap(n*SD_STRIDE*8) as *i64 } |
| 30 | func sd_seat(st: *i64, i: i64, ax: i64, ay: i64, az: i64) -> i64 |
| 38 | func sd_impulse(st: *i64, i: i64, ix: i64, iy: i64, iz: i64) -> i64 |
| 56 | func sd_deadsnap(st: *i64, b: i64, axis: i64, q: i64, kk: i64, cc: i64) -> i64 |
| 66 | func sd_step(st: *i64, i: i64, ax: i64, ay: i64, az: i64, K: i64, C: i64, maxd: i64) -> i64 |
| 101 | func sd_disp(st: *i64, i: i64, ax: i64, ay: i64, az: i64) -> i64 |
| 107 | func sd_disp_y(st: *i64, i: i64, ay: i64) -> i64 { return (st[i*SD_STRIDE+1] - ay*SD_Q8)/SD_Q8 } |
| 110 | func sd_disp_y_q8(st: *i64, i: i64, ay: i64) -> i64 { return st[i*SD_STRIDE+1] - ay*SD_Q8 } |
| 111 | func sd_disp_q8(st: *i64, i: i64, ax: i64, ay: i64, az: i64) -> i64 |
| 117 | func sd_energy(st: *i64, i: i64) -> i64 |