nx_oscar_batch_test.nx source
↩ module page · 150 lines · 5947 B
1import "nx_syscalls.nx"
2import "nx_image.nx"
3import "nx_color_palette.nx"
4import "nx_shadow_integration.nx"
5import "nx_hair_style.nx"
6import "nx_emotion_authenticity.nx"
7
8func paint_rgb(rgb: *Image, r: i64, g: i64, b: i64) -> i64 {
9 var y: i64 = 0
10 while y < rgb.height {
11 var x: i64 = 0
12 while x < rgb.width {
13 nx_image_set(rgb, x, y, 0, r); nx_image_set(rgb, x, y, 1, g); nx_image_set(rgb, x, y, 2, b)
14 x = x + 1
15 }
16 y = y + 1
17 }
18 return 0
19}
20
21func paint_mask(mask: *Image, x0: i64, y0: i64, x1: i64, y1: i64, v: i64) -> i64 {
22 var y: i64 = y0
23 while y < y1 {
24 var x: i64 = x0
25 while x < x1 {
26 if x >= 0 { if x < mask.width { if y >= 0 { if y < mask.height {
27 nx_image_set(mask, x, y, 0, v)
28 } } } }
29 x = x + 1
30 }
31 y = y + 1
32 }
33 return 0
34}
35
36func main() -> i64 {
37 let pal_res: *i64 = (sys_mmap(NX_PAL_RES_FIELDS * 8 + 16)) as *i64
38
39 // ==========================================================
40 // COLOR PALETTE
41 // ==========================================================
42 // T1: warm amber palette — high R, mid G, low B.
43 let rgb: *Image = nx_image_alloc(40, 40, 3)
44 paint_rgb(rgb, 200, 130, 50)
45 nx_color_palette(rgb, pal_res)
46 let pal1: i64 = pal_res[NX_PAL_RES_KIND]
47 let w1: i64 = pal_res[NX_PAL_RES_WARM_Q10]
48 if w1 < 200 { return 1 }
49 if pal1 != NX_PALETTE_WARM_AMBER { if pal1 != NX_PALETTE_EARTH_NEUTRAL { return 2 } }
50
51 // T2: cool blue palette — low R, mid G, high B.
52 paint_rgb(rgb, 60, 100, 200)
53 nx_color_palette(rgb, pal_res)
54 let pal2: i64 = pal_res[NX_PAL_RES_KIND]
55 if pal2 != NX_PALETTE_COOL_BLUE { return 10 }
56
57 // T3: monochrome — R=G=B.
58 paint_rgb(rgb, 120, 120, 120)
59 nx_color_palette(rgb, pal_res)
60 let pal3: i64 = pal_res[NX_PAL_RES_KIND]
61 if pal3 != NX_PALETTE_MONOCHROME { return 20 }
62
63 // ==========================================================
64 // SHADOW INTEGRATION
65 // ==========================================================
66 let mask: *Image = nx_image_alloc(200, 200, 1)
67 let bbox: *i64 = (sys_mmap(8 * 8 + 16)) as *i64
68 let sh_res: *i64 = (sys_mmap(NX_SHADOW_RES_FIELDS * 8 + 16)) as *i64
69
70 // Subject in left half (mask=255), env on right (mask=0).
71 let rgb2: *Image = nx_image_alloc(200, 200, 3)
72 paint_rgb(rgb2, 180, 180, 180) // env baseline bright
73 // Make shadow band darker (rows 50-150 in env area near subject edge).
74 paint_mask(mask, 0, 0, 100, 200, 255) // subject left half
75 paint_mask(mask, 100, 0, 200, 200, 0) // env right half
76 // Shadow band: cols 100-115 darker.
77 var sy: i64 = 0
78 while sy < 200 {
79 var sx: i64 = 100
80 while sx < 115 {
81 nx_image_set(rgb2, sx, sy, 0, 140); nx_image_set(rgb2, sx, sy, 1, 140); nx_image_set(rgb2, sx, sy, 2, 140)
82 sx = sx + 1
83 }
84 sy = sy + 1
85 }
86 bbox[0] = 100; bbox[1] = 50; bbox[2] = 115; bbox[3] = 150 // band
87 bbox[4] = 150; bbox[5] = 50; bbox[6] = 199; bbox[7] = 150 // baseline far
88 nx_shadow_integration(rgb2, mask, bbox, sh_res)
89 let sv1: i64 = sh_res[NX_SHADOW_RES_VERDICT]
90 let depth1: i64 = sh_res[NX_SHADOW_RES_DEPTH_PCT]
91 // band=140, baseline=180. depth = (180-140)/180 = 22%. NATURAL.
92 if sv1 != NX_SHADOW_V_NATURAL { return 30 }
93 if depth1 < 18 { return 31 }
94 if depth1 > 26 { return 32 }
95
96 // T5: missing shadow (band same as baseline).
97 paint_rgb(rgb2, 180, 180, 180)
98 nx_shadow_integration(rgb2, mask, bbox, sh_res)
99 let sv2: i64 = sh_res[NX_SHADOW_RES_VERDICT]
100 if sv2 != NX_SHADOW_V_MISSING { return 40 }
101
102 // ==========================================================
103 // HAIR STYLE
104 // ==========================================================
105 let hr_res: *i64 = (sys_mmap(NX_HAIR_RES_FIELDS * 8 + 16)) as *i64
106
107 // T6: GYM + PRACTICAL_UPDO → APPROPRIATE.
108 nx_hair_style_score(NX_HAIR_PRACTICAL_UPDO, NX_HAIR_PRACTICAL_UPDO, NX_HR_LOC_GYM, hr_res)
109 let hv1: i64 = hr_res[NX_HAIR_RES_VERDICT]
110 if hv1 != NX_HAIR_V_APPROPRIATE { return 50 }
111
112 // T7: GYM + EDITORIAL_AVANT → INAPPROPRIATE.
113 nx_hair_style_score(NX_HAIR_EDITORIAL_AVANT, NX_HAIR_EDITORIAL_AVANT, NX_HR_LOC_GYM, hr_res)
114 let hv2: i64 = hr_res[NX_HAIR_RES_VERDICT]
115 if hv2 != NX_HAIR_V_INAPPROPRIATE { return 60 }
116
117 // T8: POOL + WET_DAMP → APPROPRIATE.
118 nx_hair_style_score(NX_HAIR_WET_DAMP, NX_HAIR_WET_DAMP, NX_HR_LOC_POOL, hr_res)
119 let hv3: i64 = hr_res[NX_HAIR_RES_VERDICT]
120 if hv3 != NX_HAIR_V_APPROPRIATE { return 70 }
121
122 // ==========================================================
123 // EMOTION AUTHENTICITY
124 // ==========================================================
125 let ea_res: *i64 = (sys_mmap(NX_EAU_RES_FIELDS * 8 + 16)) as *i64
126
127 // T9: HAPPY emotion, full markers (eye crinkle high, brow neutral, lip up, gaze engaged).
128 nx_emotion_authenticity(NX_EAU_EMO_HAPPY,
129 819, 614, 870, 614, 870, ea_res)
130 let ev1: i64 = ea_res[NX_EAU_RES_VERDICT]
131 if ev1 != NX_EAU_V_AUTHENTIC { return 80 }
132
133 // T10: HAPPY but DEAD EYES (no crinkle, no gaze engagement) — mouth-only smile.
134 nx_emotion_authenticity(NX_EAU_EMO_HAPPY,
135 100, 614, 870, 614, 100, ea_res)
136 let ev2: i64 = ea_res[NX_EAU_RES_VERDICT]
137 let fa2: i64 = ea_res[NX_EAU_RES_FAIL_AXIS]
138 if ev2 == NX_EAU_V_AUTHENTIC { return 90 }
139 // gaze (100 vs target 870) = score 254. eye_crinkle (100 vs 819) = score 305.
140 // gaze is more off → fail_axis = GAZE
141 if fa2 != NX_EAU_AXIS_GAZE { return 91 }
142
143 // T11: SURPRISED — all markers wide.
144 nx_emotion_authenticity(NX_EAU_EMO_SURPRISED,
145 819, 920, 614, 870, 920, ea_res)
146 let ev3: i64 = ea_res[NX_EAU_RES_VERDICT]
147 if ev3 != NX_EAU_V_AUTHENTIC { return 100 }
148
149 return 0
150}