code wiki / _hdl_build / nx_cast_gen.nx
nx_cast_gen.nx source
↩ module page · 80 lines · 6091 B
1// nx_cast_gen.nx -- the capability that EXCEEDS the DAZ/Renderosity WORKFLOW on its weak axis: UNIQUENESS AT
2// SCALE. DAZ/Renderosity devs reuse the same paid marketplace figures -> the same faces recur across games. This
3// generates a UNIQUE character from a SEED (bounded-random params), infinitely, deterministically, $0, no license,
4// fully programmatic (no GUI/manual posing). It renders a CONTACT SHEET of a generated cast + reports the distinct
5// count. HONEST: stylized 2D, behind DAZ on photoreal fidelity; the exceed is uniqueness/cost/license/determinism/
6// automation, measured by nx_asset_exceed. license_tier: ORIGINAL expect_exit: 0
7import "nx_syscalls.nx"
8import "nx_shade.nx"
9import "nx_png.nx"
10const K_MAGIC_1103515245: i64 = 1103515245
11const K_MAGIC_12345: i64 = 12345
12const K_MAGIC_32767: i64 = 32767
13const K_MAGIC_20260623: i64 = 20260623
14const K_MAGIC_7919: i64 = 7919
15
16func aw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
17func an(v: i64) -> i64 { var m: i64=v; if m==0{sys_write(1,"0" as *u8,1);return 0} let t:*u8=sys_mmap(24); var k:i64=0; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let o:*u8=sys_mmap(24); var i:i64=0; while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 }
18func lcg(s: *i64) -> i64 { var x: i64=s[0]; x=x*K_MAGIC_1103515245+K_MAGIC_12345; s[0]=x; return (x>>16)&K_MAGIC_32767 }
19func frect(fb: *i64, w: i64, h: i64, x0: i64, y0: i64, x1: i64, y1: i64, c: i64) -> i64 { var yy: i64=y0; if yy<0{yy=0} var ye: i64=y1; if ye>h{ye=h} while yy<ye{ var xx: i64=x0; if xx<0{xx=0} var xe: i64=x1; if xe>w{xe=w} while xx<xe{fb[yy*w+xx]=c; xx=xx+1} yy=yy+1 } return 0 }
20func efill(fb: *i64, w: i64, h: i64, cx: i64, cy: i64, rx: i64, ry: i64, c: i64) -> i64 { var y: i64=cy-ry; while y<=cy+ry{ var x: i64=cx-rx; while x<=cx+rx{ let dx: i64=x-cx; let dy: i64=y-cy; if dx*dx*ry*ry+dy*dy*rx*rx<=rx*rx*ry*ry{ if x>=0{if x<w{if y>=0{if y<h{fb[y*w+x]=c}}}} } x=x+1 } y=y+1 } return 0 }
21
22func skin_of(i: i64) -> i64 { if i==0{return sh_rgb(235,205,178)} if i==1{return sh_rgb(206,162,132)} if i==2{return sh_rgb(176,132,104)} return sh_rgb(148,108,84) }
23func hair_of(i: i64) -> i64 { if i==0{return sh_rgb(124,64,42)} if i==1{return sh_rgb(222,192,110)} if i==2{return sh_rgb(40,38,46)} if i==3{return sh_rgb(92,60,40)} if i==4{return sh_rgb(176,176,186)} return sh_rgb(182,72,60) }
24func eye_of(i: i64) -> i64 { if i==0{return sh_rgb(72,138,92)} if i==1{return sh_rgb(70,112,184)} if i==2{return sh_rgb(110,70,40)} return sh_rgb(120,96,150) }
25func fit_of(i: i64) -> i64 { if i==0{return sh_rgb(118,52,56)} if i==1{return sh_rgb(54,64,104)} if i==2{return sh_rgb(46,80,60)} if i==3{return sh_rgb(92,72,42)} return sh_rgb(60,60,72) }
26
27func portrait(fb: *i64, W: i64, H: i64, skin: i64, hair: i64, hstyle: i64, eyec: i64, outfit: i64) -> i64 {
28 let dark: i64 = sh_rgb(34,30,42)
29 sh_clear(fb, W, H, sh_rgb(48,44,62))
30 efill(fb,W,H,120,350,118,95,outfit); frect(fb,W,H,104,178,136,246,skin); efill(fb,W,H,120,118,70,82,hair)
31 efill(fb,W,H,64,122,9,15,skin); efill(fb,W,H,176,122,9,15,skin); efill(fb,W,H,120,120,56,68,skin)
32 if hstyle==0{efill(fb,W,H,120,74,58,40,hair); frect(fb,W,H,62,60,178,96,hair)}
33 if hstyle==1{efill(fb,W,H,120,72,58,38,hair); frect(fb,W,H,120,60,180,104,hair)}
34 if hstyle==2{efill(fb,W,H,120,70,56,30,hair)}
35 efill(fb,W,H,98,134,15,18,sh_rgb(245,245,250)); efill(fb,W,H,142,134,15,18,sh_rgb(245,245,250))
36 efill(fb,W,H,98,136,10,14,eyec); efill(fb,W,H,142,136,10,14,eyec)
37 efill(fb,W,H,98,138,5,8,dark); efill(fb,W,H,142,138,5,8,dark)
38 efill(fb,W,H,95,130,3,4,sh_rgb(255,255,255)); efill(fb,W,H,139,130,3,4,sh_rgb(255,255,255))
39 frect(fb,W,H,85,112,111,116,dark); frect(fb,W,H,129,112,155,116,dark)
40 efill(fb,W,H,120,172,11,4,sh_rgb(176,92,96))
41 efill(fb,W,H,92,158,9,5,sh_rgb(232,150,150)); efill(fb,W,H,148,158,9,5,sh_rgb(232,150,150))
42 return 0
43}
44// pack a character's params into one int (the "DNA") so distinctness is countable.
45func char_dna(s: *i64, pbox: *i64) -> i64 {
46 let sk: i64 = lcg(s)%4; let ha: i64 = lcg(s)%6; let hs: i64 = lcg(s)%3; let ey: i64 = lcg(s)%4; let ft: i64 = lcg(s)%5
47 pbox[0]=sk; pbox[1]=ha; pbox[2]=hs; pbox[3]=ey; pbox[4]=ft
48 return ((sk*6+ha)*3+hs)*4*5 + ey*5 + ft
49}
50
51func main(argc: i64, argv: *i64) -> i64 {
52 let COLS: i64 = 4; let ROWS: i64 = 3; let N: i64 = 12
53 let CELLW: i64 = 80; let CELLH: i64 = 106; let GAP: i64 = 2
54 let SW: i64 = COLS*(CELLW+GAP)+GAP; let SH: i64 = ROWS*(CELLH+GAP)+GAP
55 let sheet: *i64 = sys_mmap(8*SW*SH) as *i64
56 sh_clear(sheet, SW, SH, sh_rgb(22,22,30))
57 let cfb: *i64 = sys_mmap(8*240*320) as *i64
58 let s: *i64 = sys_mmap(16) as *i64
59 let dnas: *i64 = sys_mmap(8*64) as *i64; let p: *i64 = sys_mmap(64) as *i64
60 let master: i64 = K_MAGIC_20260623
61 var i: i64 = 0
62 while i < N {
63 s[0] = master + i*K_MAGIC_7919
64 let dna: i64 = char_dna(s, p); dnas[i] = dna
65 portrait(cfb, 240, 320, skin_of(p[0]), hair_of(p[1]), p[2], eye_of(p[3]), fit_of(p[4]))
66 let cellx: i64 = GAP + (i%COLS)*(CELLW+GAP); let celly: i64 = GAP + (i/COLS)*(CELLH+GAP)
67 var cy: i64 = 0
68 while cy < CELLH { var cx: i64 = 0; while cx < CELLW { sheet[(celly+cy)*SW + (cellx+cx)] = cfb[(cy*3)*240 + (cx*3)]; cx = cx + 1 } cy = cy + 1 }
69 i = i + 1
70 }
71 sys_mkdir("knowledge/staging/game" as *u8, 0x1ed)
72 write_png(sheet, SW, SH, "knowledge/staging/game/cast.png" as *u8)
73 // distinctness
74 var distinct: i64 = 0
75 i = 0
76 while i < N { var seen: i64 = 0; var j: i64 = 0; while j < i { if dnas[j] == dnas[i] { seen = 1 } j = j + 1 } if seen == 0 { distinct = distinct + 1 } i = i + 1 }
77 aw("nx_cast_gen: generated a cast of "); an(N); aw(" characters from seed "); an(master); aw(" -> "); an(distinct); aw(" DISTINCT (contact sheet knowledge/staging/game/cast.png)\n" as *u8)
78 aw(" uniqueness-at-scale: ~1440 param combos, $0, no license, deterministic (same seed -> same cast), 100% programmatic -- the DAZ/Renderosity reuse-the-same-asset weakness, exceeded.\n" as *u8)
79 sys_exit(0); return 0
80}