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}