code wiki / _hdl_build / nx_variant_mesh_gate.nx

nx_variant_mesh_gate.nx source

↩ module page · 131 lines · 6345 B

1// nx_variant_mesh_gate.nx -- close the DnD asset loop: bestiary variant TUPLES -> the SAME SDF base -> 2// nx_meshgen surface nets -> WATERTIGHT STL game assets. One recipe system now emits downloadable meshes 3// (person/elf/goblin/hobgoblin/wolf/direwolf), reusable by the game systems and printable. 4// T1 every variant meshes CLOSED (verts>=400, tris ~= 2*verts -- Euler genus-0 band) 5// T2 variant meshes are DISTINCT (>=5 distinct vert counts of 6 -- the swap slots change the geometry) 6// T3 STL files written + non-trivial size 7// Writes knowledge/synth_<variant>.stl. license_tier: ORIGINAL expect_exit: 0 8import "nx_syscalls.nx" 9import "nx_sdfrender.nx" 10import "nx_meshgen.nx" 11import "nx_assetvariant.nx" 12 13func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 14func hwf(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 15func pn(v: i64) -> i64 { 16 let b: *u8 = sys_mmap(32) as *u8 17 var x: i64 = v; var neg: i64 = 0 18 if x < 0 { neg = 1; x = 0 - x } 19 var i: i64 = 31 20 if x == 0 { b[i] = 48 as u8; i = i - 1 } 21 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 } 22 if neg == 1 { b[i] = 45 as u8; i = i - 1 } 23 sys_write(1, (b as i64 + i + 1) as *u8, 31 - i) 24 return 0 25} 26func stlnum(fd: i64, v: i64) -> i64 { 27 let b: *u8 = sys_mmap(32) as *u8 28 var x: i64 = v; var neg: i64 = 0 29 if x < 0 { neg = 1; x = 0 - x } 30 var i: i64 = 31 31 if x == 0 { b[i] = 48 as u8; i = i - 1 } 32 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 } 33 if neg == 1 { b[i] = 45 as u8; i = i - 1 } 34 sys_write(fd, (b as i64 + i + 1) as *u8, 31 - i); sys_write(fd, " " as *u8, 1); return 0 35} 36func wstl(vbuf: *i64, fbuf: *i64, nf: i64, path: *u8) -> i64 { 37 let fd: i64 = sys_openat_wr(path, 0x1a4) 38 if fd < 0 { return 0 - 1 } 39 hwf(fd, "solid nishi_variant\n" as *u8) 40 var t: i64 = 0 41 while t < nf { 42 let a: i64 = fbuf[t * 3]; let b: i64 = fbuf[t * 3 + 1]; let c: i64 = fbuf[t * 3 + 2] 43 hwf(fd, "facet normal 0 0 0\nouter loop\nvertex " as *u8) 44 stlnum(fd, vbuf[a*3]); stlnum(fd, vbuf[a*3+1]); stlnum(fd, vbuf[a*3+2]) 45 hwf(fd, "\nvertex " as *u8) 46 stlnum(fd, vbuf[b*3]); stlnum(fd, vbuf[b*3+1]); stlnum(fd, vbuf[b*3+2]) 47 hwf(fd, "\nvertex " as *u8) 48 stlnum(fd, vbuf[c*3]); stlnum(fd, vbuf[c*3+1]); stlnum(fd, vbuf[c*3+2]) 49 hwf(fd, "\nendloop\nendfacet\n" as *u8) 50 t = t + 1 51 } 52 hwf(fd, "endsolid nishi_variant\n" as *u8); sys_close(fd); return 0 53} 54func fsize(path: *u8) -> i64 { 55 let lp: *i64 = sys_mmap(16) as *i64 56 let b: *u8 = sys_read_file(path, lp) 57 if (b as i64) == 0 { return 0 } 58 return lp[0] 59} 60 61func main() -> i64 { 62 hw("=== nx_variant_mesh_gate -- bestiary tuples -> watertight STL game assets ===\n" as *u8) 63 let base: i64 = sys_mmap(sdf_bytes()) as i64 64 let F: *i64 = sys_mmap((MG_N + 1) * (MG_N + 1) * (MG_N + 1) * 8) as *i64 65 let cv: *i64 = sys_mmap(MG_N * MG_N * MG_N * 8) as *i64 66 let vb: *i64 = sys_mmap(MG_MAXV * 3 * 8) as *i64 67 let fb: *i64 = sys_mmap(MG_MAXF * 3 * 8) as *i64 68 let out: *i64 = sys_mmap(16) as *i64 69 // 6 grid-safe variants {sp,hv,ev,tv,build} (tall human horns would clip MG_GR=1500 -> excluded) 70 let vt: *i64 = sys_mmap(6 * 5 * 8) as *i64 71 var q: i64 = 0 72 vt[q]=0; vt[q+1]=0; vt[q+2]=0; vt[q+3]=0; vt[q+4]=100; q=q+5 // human 73 vt[q]=0; vt[q+1]=0; vt[q+2]=1; vt[q+3]=0; vt[q+4]=80; q=q+5 // elf 74 vt[q]=2; vt[q+1]=0; vt[q+2]=1; vt[q+3]=0; vt[q+4]=100; q=q+5 // goblin 75 vt[q]=2; vt[q+1]=0; vt[q+2]=1; vt[q+3]=0; vt[q+4]=125; q=q+5 // hobgoblin 76 vt[q]=1; vt[q+1]=0; vt[q+2]=1; vt[q+3]=1; vt[q+4]=100; q=q+5 // wolf 77 vt[q]=1; vt[q+1]=1; vt[q+2]=1; vt[q+3]=1; vt[q+4]=125; q=q+5 // dire wolf 78 let nvs: *i64 = sys_mmap(6 * 8) as *i64 79 let sizes: *i64 = sys_mmap(6 * 8) as *i64 80 var fails: i64 = 0 81 var v: i64 = 0 82 while v < 6 { 83 let sp: i64 = vt[v*5] 84 let hv: i64 = vt[v*5+1] 85 let ev: i64 = vt[v*5+2] 86 let tv: i64 = vt[v*5+3] 87 let bl: i64 = vt[v*5+4] 88 av_build(base, sp, hv, ev, tv, bl) 89 mg_build(base, F, cv, vb, fb, out) 90 let nv2: i64 = out[0] 91 let nf: i64 = out[1] 92 nvs[v] = nv2 93 var nm: *u8 = "knowledge/synth_human.stl" as *u8 94 if v == 1 { nm = "knowledge/synth_elf.stl" as *u8 } 95 if v == 2 { nm = "knowledge/synth_goblin.stl" as *u8 } 96 if v == 3 { nm = "knowledge/synth_hobgoblin.stl" as *u8 } 97 if v == 4 { nm = "knowledge/synth_wolf.stl" as *u8 } 98 if v == 5 { nm = "knowledge/synth_direwolf.stl" as *u8 } 99 wstl(vb, fb, nf, nm) 100 let sz: i64 = fsize(nm) 101 sizes[v] = sz 102 hw(" " as *u8); hw(nm); hw(" verts=" as *u8); pn(nv2); hw(" tris=" as *u8); pn(nf); hw(" bytes=" as *u8); pn(sz) 103 var closed: i64 = 1 104 if nv2 < 400 { closed = 0 } 105 if nf < nv2 * 3 / 2 { closed = 0 } 106 if nf > nv2 * 5 / 2 { closed = 0 } 107 if closed == 1 { hw(" [closed]\n" as *u8) } else { hw(" [BAD]\n" as *u8); fails = fails + 1 } 108 v = v + 1 109 } 110 if fails == 0 { hw("T1 PASS all 6 variants mesh CLOSED (watertight, printable)\n" as *u8) } 111 else { hw("T1 FAIL " as *u8); pn(fails); hw(" bad meshes\n" as *u8) } 112 var distinct: i64 = 0 113 var a: i64 = 0 114 while a < 6 { 115 var seen: i64 = 0 116 var b: i64 = 0 117 while b < a { if nvs[b] == nvs[a] { seen = 1 } b = b + 1 } 118 if seen == 0 { distinct = distinct + 1 } 119 a = a + 1 120 } 121 if distinct >= 5 { hw("T2 PASS " as *u8); pn(distinct); hw("/6 distinct vert counts -- the swap slots change the GEOMETRY, not just the render\n" as *u8) } 122 else { fails = fails + 1; hw("T2 FAIL only " as *u8); pn(distinct); hw(" distinct\n" as *u8) } 123 var t3: i64 = 1 124 a = 0 125 while a < 6 { if sizes[a] < 100000 { t3 = 0 } a = a + 1 } 126 if t3 == 1 { hw("T3 PASS all STL files non-trivial on disk\n" as *u8) } 127 else { fails = fails + 1; hw("T3 FAIL an STL is too small\n" as *u8) } 128 if fails == 0 { hw("VARIANT-MESH-GATE 3/3 verdict=GREEN -- the bestiary EXPORTS as watertight game assets (knowledge/synth_*.stl)\n" as *u8); sys_exit(0); return 0 } 129 hw("VARIANT-MESH-GATE RED fails=" as *u8); pn(fails); hw("\n" as *u8) 130 sys_exit(1); return 1 131}