code wiki / (root) / nx_vecmath.nx

nx_vecmath.nx

buildroot/runtime/nx_vecmath.nx

21762 B465 linesdepth 1pulls 1 transitivereach 1457 importersview sourcekind librarytopic vecmath
docsdependenciesstructsconstsfunctions

about

nx_vecmath.nx -- THE SHARED INTEGER LINEAR-ALGEBRA FOUNDATION (PG2, procgen.plan, 2026-08-24). WHY THIS EXISTS, MEASURED NOT ASSERTED: before this file the estate's entire shared math foundation was nx_itrig.nx at 1151 bytes -- it_sin4096 and it_cos4096 and nothing else. Every consumer above it re-rolled its own primitives: nx_gsplat carries gs_isqrt AND a private exp-LUT, nx_bodybench carries a private acos LUT. Three duplicate rulers for two operations. Worse, with no quaternion type nx_gsplat's gs_set_aniso had to settle for a normal-plus-tangent SURFEL where full 3D gaussian covariance needs quaternion-plus-3-axis scale -- a capability ceiling caused by a missing primitive, not by a design choice. SCALE IS DERIVED, NOT PICKED: VM_ONE = 4096 because that is already the estate's unit. nx_itrig emits fx4096 and measures angles in rad*4096; nx_vmd decodes quaternions at V_SCALE_ROT = 4096. Adopting any other scale would have made this file a converter instead of a foundation. Every other constant here is either derived from VM_ONE arithmetically or carries its derivation on its own line. COMPOSES THE INCUMBENT: sine and cosine come from nx_itrig by import. This file does NOT re-derive Taylor coefficients. VM_PI and VM_PI2 restate nx_itrig's angle constants because NishiLang const scope does not cross the import, so nx_vecmath_gate carries a tooth that FAILS if the two ever disagree -- a guarded duplicate, not a silent one. NO HEAP, NO LOCAL ARRAYS, NO ALLOCATION ANYWHERE. Every routine works in scalar locals and writes through caller-owned pointers. Two reasons, both estate law: this is hot-loop code and allocating in a hot loop is a measured defect; and the estate's only allocation idiom is sys_mmap, which a pure math lib must not need. Every routine that could alias its output with an input reads all operands into locals FIRST. ALL INTEGER. The language has no float type, so every result here is bit-exact and reproducible by construction. license_tier: ORIGINAL

dependencies 1 imports · 127 importers

nx_itrig.nx nx_vecmath.nx nx_anatstack.nx nx_atmosphere.nx nx_audio_enhance.nx nx_autorig.nx nx_body_rest_frame_candidate_t345. nx_bodyatlas.nx nx_bodybench.nx nx_boneheat_lib.nx nx_bvhfk_lib.nx nx_clipcap_lib.nx

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

imports: nx_itrig.nx

imported by: nx_anatstack.nxnx_atmosphere.nxnx_audio_enhance.nxnx_autorig.nxnx_body_rest_frame_candidate_t345.nxnx_bodyatlas.nxnx_bodybench.nxnx_boneheat_lib.nxnx_bvhfk_lib.nxnx_clipcap_lib.nxnx_contour_print.nxnx_cornell.nxnx_creature_render.nxnx_dataframe.nxnx_devpaint_gate.nxnx_devpaint_lib.nxnx_dr_semjudge.nxnx_essential3d.nxnx_explode3d.nxnx_fbx_affine_math_gate_t32.nxnx_fbx_affine_t32.nxnx_fin_metrics.nxnx_fixq30_lib.nxnx_fluid.nxnx_gi_path_lib.nxnx_glbnorm_gate.nxnx_glbnorm_lib.nxnx_gltf2mesh.nxnx_gltf2mesh_normal_candidate_t337.nxnx_gltf2mesh_preserve_t145.nxnx_gltf_export.nxnx_gltf_export_material_candidate_t340.nxnx_gltf_export_multipart_candidate_t345.nxnx_gltf_inventory_candidate_t180.nxnx_gltf_pose_math_t316.nxnx_glyph_stroke.nxnx_gsplat.nxnx_haircollide_gate.nxnx_hairdyn_lib.nxnx_hairdyn_pose_candidate_t263.nxnx_hairdyn_transport_candidate_t284.nxnx_ik.nxnx_indoor.nxnx_isosurf.nxnx_isosurf_orientation_candidate_t343.nxnx_jam_check.nxnx_lensdist.nxnx_math.nxnx_meshrender.nxnx_meshtex.nxnx_meshthick.nxnx_meshview_wasm.nxnx_microscan_lib.nxnx_mmdev_gate.nxnx_mmdev_lib.nxnx_motion_plan.nxnx_natstat.nxnx_nofloat_autograd.nxnx_nofloat_k3stack.nxnx_nofloat_llm.nxnx_nofloat_muon_ns.nxnx_nxmesh_lib.nxnx_obj_export.nxnx_part_solver_lib.nxnx_partloft_lib.nxnx_pcb_cam.nxnx_phys3d.nxnx_pose_coach.nxnx_pose_retarget.nxnx_ppmi_lib.nxnx_procgen_gtlabels_gate.nxnx_qlayer.nxnx_quality_metric.nxnx_rec_grade.nxnx_recon3d.nxnx_register3d.nxnx_render_core.nxnx_robot_timing.nxnx_rot_health.nxnx_sdfrender.nxnx_sdfrender_attribution_candidate_t344.nxnx_sketch_ams.nxnx_sketch_correlation.nxnx_sketch_count_sketch.nxnx_sketch_cpc.nxnx_sketch_cpc_dense.nxnx_sketch_epsilon_greedy.nxnx_sketch_kmeans1d.nxnx_sketch_moments.nxnx_sketch_stream_stats.nxnx_sketch_ucb1.nxnx_soda_carbonation.nxnx_softbody_region.nxnx_softdyn.nxnx_softjiggle.nxnx_softtissue.nxnx_subdiv.nxnx_survey_stats.nxnx_swgpu.nxnx_texpaint_gate.nx +27 more (shown cap 100 declared)

structs

none

consts

31const VM_ONE: i64 = 4096 // fixed-point unit. DERIVED: nx_itrig fx4096 and nx_vmd V_SCALE_ROT.
32const VM_PI: i64 = 12868 // round(PI * VM_ONE). Guarded by tooth pi-agrees-with-itrig.
33const VM_PI2: i64 = 6434 // round(PI/2 * VM_ONE)
34const VM_TAU: i64 = 25736 // 2 * VM_PI
40const VM_ATAN_KN: i64 = 9
41const VM_ATAN_KD: i64 = 32
48const VM_SLERP_PARALLEL: i64 = 4095 // VM_ONE - 1
50const VM_V3: i64 = 3
51const VM_M3: i64 = 9
105const VM_CAP_Q: i64 = 256
162const VM_F32_MANT_MASK: i64 = 8388607 // 2^23 - 1
163const VM_F32_IMPLICIT: i64 = 8388608 // 2^23
164const VM_F32_EXP_BIAS: i64 = 127
165const VM_F32_MANT_BITS: i64 = 23
166const VM_F32_EXP_MASK: i64 = 255
167const VM_F32_SHIFT_MAX: i64 = 62 // a shift at or beyond this cannot be represented in i64

functions

53func vm_one() -> i64 { return VM_ONE }
called by 1: main
54func vm_pi() -> i64 { return VM_PI }
called by 2: vg_angdevmain
55func vm_pi2() -> i64 { return VM_PI2 }
called by 1: main
56func vm_tau() -> i64 { return VM_TAU }
called by 2: vg_angdevmain
60func vm_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
61func vm_sgn(v: i64) -> i64 { if v > 0 { return 1 } if v < 0 { return 0 - 1 } return 0 }
called by 1: gn_unit3
62func vm_min(a: i64, b: i64) -> i64 { if a < b { return a } return b }
63func vm_max(a: i64, b: i64) -> i64 { if a > b { return a } return b }
64func vm_clamp(v: i64, lo: i64, hi: i64) -> i64 { if v < lo { return lo } if v > hi { return hi } return v }
68func vm_isqrt(v: i64) -> i64
84func vm_sqrt_fx(v: i64) -> i64
called by 2: vm_v3_lenvm_q_len calls 1: vm_isqrt
106func vm_capsule_push(px: i64, py: i64, pz: i64,
169func vm_f32_to_int(bits: i64, scale: i64) -> i64
187func vm_int_to_f32(v: i64, scale: i64) -> i64
203func vm_mul_fx(a: i64, b: i64) -> i64 { return a * b / VM_ONE }
204func vm_div_fx(a: i64, b: i64) -> i64 { if b == 0 { return 0 } return a * VM_ONE / b }
206func vm_sin(a: i64) -> i64 { return it_sin4096(a) }
207func vm_cos(a: i64) -> i64 { return it_cos4096(a) }
211func vm_tan(a: i64) -> i64
218func vm_atan_core(z: i64) -> i64
called by 1: vm_atan2
227func vm_atan2(y: i64, x: i64) -> i64
245func vm_acos(c0: i64) -> i64
253func vm_asin(s0: i64) -> i64
263func vm_v3_set(o: *i64, x: i64, y: i64, z: i64) -> i64 { o[0] = x; o[1] = y; o[2] = z; return 0 }
called by 1: main
264func vm_v3_copy(o: *i64, a: *i64) -> i64 { o[0] = a[0]; o[1] = a[1]; o[2] = a[2]; return 0 }
265func vm_v3_add(o: *i64, a: *i64, b: *i64) -> i64 { o[0] = a[0]+b[0]; o[1] = a[1]+b[1]; o[2] = a[2]+b[2]; return 0 }
266func vm_v3_sub(o: *i64, a: *i64, b: *i64) -> i64 { o[0] = a[0]-b[0]; o[1] = a[1]-b[1]; o[2] = a[2]-b[2]; return 0 }
267func vm_v3_scale(o: *i64, a: *i64, s: i64) -> i64 { o[0] = a[0]*s/VM_ONE; o[1] = a[1]*s/VM_ONE; o[2] = a[2]*s/VM_ONE; return 0 }
269func vm_v3_dot(a: *i64, b: *i64) -> i64 { return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]) / VM_ONE }
called by 1: main
272func vm_v3_cross(o: *i64, a: *i64, b: *i64) -> i64
called by 1: main
281func vm_v3_len2(a: *i64) -> i64 { return (a[0]*a[0] + a[1]*a[1] + a[2]*a[2]) / VM_ONE }
called by 1: vm_v3_len
282func vm_v3_len(a: *i64) -> i64 { return vm_sqrt_fx(vm_v3_len2(a)) }
286func vm_v3_norm(o: *i64, a: *i64) -> i64
called by 1: main calls 1: vm_v3_len
300func vm_q_ident(o: *i64) -> i64 { o[0] = 0; o[1] = 0; o[2] = 0; o[3] = VM_ONE; return 0 }
301func vm_q_copy(o: *i64, a: *i64) -> i64 { o[0]=a[0]; o[1]=a[1]; o[2]=a[2]; o[3]=a[3]; return 0 }
302func vm_q_conj(o: *i64, a: *i64) -> i64
306func vm_q_len(a: *i64) -> i64
called by 3: vm_q_normvm_q_to_m3main calls 1: vm_sqrt_fx
310func vm_q_norm(o: *i64, a: *i64) -> i64
322func vm_q_mul(o: *i64, a: *i64, b: *i64) -> i64
called by 1: main
333func vm_q_from_axis(o: *i64, axis: *i64, angle: i64) -> i64
349func vm_q_rotate_v3(o: *i64, q: *i64, v: *i64) -> i64
365func vm_q_slerp(o: *i64, a: *i64, b: *i64, t: i64) -> i64
called by 1: main calls 3: vm_acosvm_sinvm_q_norm
389func vm_m3_ident(o: *i64) -> i64
called by 2: vm_q_to_m3main
397func vm_m3_mul(o: *i64, a: *i64, b: *i64) -> i64
called by 1: main
416func vm_m3_mulv(o: *i64, m: *i64, v: *i64) -> i64
called by 1: main
424func vm_m3_transpose(o: *i64, m: *i64) -> i64
called by 1: main
435func vm_q_to_m3(o: *i64, q: *i64) -> i64
459func vm_q_scale_to_m3(o: *i64, q: *i64, sx: i64, sy: i64, sz: i64) -> i64
called by 1: main calls 1: vm_q_to_m3