code wiki / _hdl_build / nx_obj_export_gate.nx

nx_obj_export_gate.nx source

↩ module page · 103 lines · 4931 B

1// nx_obj_export_gate.nx -- the bestiary also exports as OBJ+normals (game/DCC-friendly). Meshes 3 variants 2// (human/goblin/wolf) and writes knowledge/synth_<v>.obj, asserting: v-count == mesh verts, vn-count == verts, 3// f-count == tris, and the files are distinct. license_tier: ORIGINAL expect_exit: 0 4import "nx_syscalls.nx" 5import "nx_sdfrender.nx" 6import "nx_meshgen.nx" 7import "nx_assetvariant.nx" 8import "nx_obj_export.nx" 9 10func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 11func pn(v: i64) -> i64 { 12 let b: *u8 = sys_mmap(32) as *u8 13 var x: i64 = v; var neg: i64 = 0 14 if x < 0 { neg = 1; x = 0 - x } 15 var i: i64 = 31 16 if x == 0 { b[i] = 48 as u8; i = i - 1 } 17 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 } 18 if neg == 1 { b[i] = 45 as u8; i = i - 1 } 19 sys_write(1, (b as i64 + i + 1) as *u8, 31 - i) 20 return 0 21} 22// count occurrences of a 2-char line-prefix "<c0><c1> " at start-of-line in the file 23func count_prefix(path: *u8, c0: i64, c1: i64) -> i64 { 24 let szp: *i64 = sys_mmap(16) as *i64 25 let b: *u8 = sys_read_file(path, szp) 26 if (b as i64) == 0 { return 0 - 1 } 27 let n: i64 = szp[0] 28 var cnt: i64 = 0 29 var atbol: i64 = 1 30 var i: i64 = 0 31 while i < n { 32 if atbol == 1 { 33 if i + 1 < n { if (b[i]&0xff)==c0 { if (b[i+1]&0xff)==c1 { cnt = cnt + 1 } } } // "v "/"vn"/"f " don't alias (v+space vs v+n) 34 } 35 if (b[i]&0xff) == 10 { atbol = 1 } else { atbol = 0 } 36 i = i + 1 37 } 38 return cnt 39} 40func fsize(path: *u8) -> i64 { let lp: *i64 = sys_mmap(16) as *i64; let b: *u8 = sys_read_file(path, lp); if (b as i64)==0 { return 0 } return lp[0] } 41 42func main() -> i64 { 43 hw("=== nx_obj_export_gate -- bestiary -> OBJ + smooth normals (game/DCC reuse) ===\n" as *u8) 44 let base: i64 = sys_mmap(sdf_bytes()) as i64 45 let F: *i64 = sys_mmap((MG_N + 1) * (MG_N + 1) * (MG_N + 1) * 8) as *i64 46 let cv: *i64 = sys_mmap(MG_N * MG_N * MG_N * 8) as *i64 47 let vb: *i64 = sys_mmap(MG_MAXV * 3 * 8) as *i64 48 let fb: *i64 = sys_mmap(MG_MAXF * 3 * 8) as *i64 49 let out: *i64 = sys_mmap(16) as *i64 50 let vt: *i64 = sys_mmap(6 * 5 * 8) as *i64 51 var q: i64 = 0 52 vt[q]=0; vt[q+1]=0; vt[q+2]=0; vt[q+3]=0; vt[q+4]=100; q=q+5 // human 53 vt[q]=0; vt[q+1]=0; vt[q+2]=1; vt[q+3]=0; vt[q+4]=80; q=q+5 // elf 54 vt[q]=2; vt[q+1]=0; vt[q+2]=1; vt[q+3]=0; vt[q+4]=100; q=q+5 // goblin 55 vt[q]=2; vt[q+1]=0; vt[q+2]=1; vt[q+3]=0; vt[q+4]=125; q=q+5 // hobgoblin 56 vt[q]=1; vt[q+1]=0; vt[q+2]=1; vt[q+3]=1; vt[q+4]=100; q=q+5 // wolf 57 vt[q]=1; vt[q+1]=1; vt[q+2]=1; vt[q+3]=1; vt[q+4]=125; q=q+5 // dire wolf 58 let nvs: *i64 = sys_mmap(6 * 8) as *i64 59 var fails: i64 = 0 60 var v: i64 = 0 61 while v < 6 { 62 av_build(base, vt[v*5], vt[v*5+1], vt[v*5+2], vt[v*5+3], vt[v*5+4]) 63 mg_build(base, F, cv, vb, fb, out) 64 let nv2: i64 = out[0] 65 let nf: i64 = out[1] 66 nvs[v] = nv2 67 var nm: *u8 = "knowledge/synth_human.obj" as *u8 68 if v == 1 { nm = "knowledge/synth_elf.obj" as *u8 } 69 if v == 2 { nm = "knowledge/synth_goblin.obj" as *u8 } 70 if v == 3 { nm = "knowledge/synth_hobgoblin.obj" as *u8 } 71 if v == 4 { nm = "knowledge/synth_wolf.obj" as *u8 } 72 if v == 5 { nm = "knowledge/synth_direwolf.obj" as *u8 } 73 let wr: i64 = write_obj(vb, fb, nv2, nf, nm) 74 let vc: i64 = count_prefix(nm, 118, 32) // "v " 75 let vnc: i64 = count_prefix(nm, 118, 110) // "vn" 76 let fc: i64 = count_prefix(nm, 102, 32) // "f " 77 let sz: i64 = fsize(nm) 78 hw(" " as *u8); hw(nm); hw(" v=" as *u8); pn(vc); hw(" vn=" as *u8); pn(vnc); hw(" f=" as *u8); pn(fc); hw(" bytes=" as *u8); pn(sz); hw("\n" as *u8) 79 var ok: i64 = 1 80 if vc != nv2 { ok = 0 } 81 if vnc != nv2 { ok = 0 } 82 if fc != nf { ok = 0 } 83 if sz < 50000 { ok = 0 } 84 if ok == 0 { fails = fails + 1; hw(" [BAD counts]\n" as *u8) } 85 v = v + 1 86 } 87 if fails == 0 { hw("T1 PASS all 6 OBJ: v-count==verts, vn-count==verts, f-count==tris\n" as *u8) } 88 else { hw("T1 FAIL\n" as *u8) } 89 var distinct: i64 = 0 90 var a: i64 = 0 91 while a < 6 { 92 var seen: i64 = 0 93 var b: i64 = 0 94 while b < a { if nvs[b] == nvs[a] { seen = 1 } b = b + 1 } 95 if seen == 0 { distinct = distinct + 1 } 96 a = a + 1 97 } 98 if distinct >= 5 { hw("T2 PASS " as *u8); pn(distinct); hw("/6 distinct meshes (swap changes geometry)\n" as *u8) } 99 else { fails = fails + 1; hw("T2 FAIL only " as *u8); pn(distinct); hw(" distinct\n" as *u8) } 100 if fails == 0 { hw("OBJ-EXPORT-GATE 2/2 GREEN -- bestiary exports OBJ+normals (knowledge/synth_*.obj), game/DCC-ready\n" as *u8); sys_exit(0); return 0 } 101 hw("OBJ-EXPORT-GATE RED fails=" as *u8); pn(fails); hw("\n" as *u8) 102 sys_exit(1); return 1 103}