code wiki / (root) / nx_makeup.nx

nx_makeup.nx source

↩ module page · 83 lines · 4629 B

1// nx_makeup.nx -- MAKEUP layer (the LT_MAKEUP layer type from nx_char_layers, operator "add layers of ... makeup"). 2// Unlike clothing (worn geometry), makeup is a COSMETIC recolor/overlay of face REGIONS painted by the photoreal 3// shader (nx_sdfrender mats 12/13/16). v0 recolored lip parts only; ★v2 (2026-07-07, the crash-session follow-ons): 4// EYESHADOW = appended thin LID parts (mat 16, between lash line and brow) + BLUSH = appended cheek-APPLE parts 5// (mat 13, low + frontal -- the old cheek-6/7 recolor sat in the shadowed under-eye zone and read as a dark patch, 6// exactly why it was deferred). Applies to the DETAILED sdf_face; call AFTER sdf_face (+ hairstyle) so appends 7// stack correctly. license_tier: ORIGINAL 8import "nx_syscalls.nx" 9import "nx_sdfrender.nx" 10 11// cosmetic materials (nx_sdfrender albedo) 12const MK_LIPSTICK: i64 = 12 13const MK_BLUSH: i64 = 13 14const MK_EYESHADOW: i64 = 16 15// sdf_face part indices (see sdf_face part list): 6/7 cheeks, 10/11 lips 16const FACE_CHEEK_L: i64 = 6 17const FACE_CHEEK_R: i64 = 7 18const FACE_LIP_UP: i64 = 10 19const FACE_LIP_LO: i64 = 11 20// makeup presets 21const MKUP_NONE: i64 = 0 22const MKUP_NATURAL: i64 = 1 // blush + soft lip 23const MKUP_GLAM: i64 = 2 // bold lip + blush 24 25// apply cosmetic materials onto an sdf_face base (call after sdf_face). Flags select the zones. 26func makeup_apply(base: i64, lips_on: i64, blush_on: i64) -> i64 { 27 if lips_on == 1 { sdf_set_mat(base, FACE_LIP_UP, MK_LIPSTICK); sdf_set_mat(base, FACE_LIP_LO, MK_LIPSTICK) } 28 if blush_on == 1 { sdf_set_mat(base, FACE_CHEEK_L, MK_BLUSH); sdf_set_mat(base, FACE_CHEEK_R, MK_BLUSH) } 29 return 0 30} 31// ★v2 apply (2026-07-07): lips recolor (as v0) + APPENDED cosmetic geometry -- eyeshadow LID parts (thin, just 32// above the lash line at (+-258,290,-632), below the brows at (+-250,322,-565); slightly proud in -z so the 33// material query picks them) + blush cheek-APPLE parts (low + frontal on the apples, clear of the under-eye 34// shadow zone that killed the v0 recolor). n0 = current part count (27 straight after sdf_face; pass the 35// hairstyle's return if one was applied). Returns the new part count. 36func makeup_apply2(base: i64, n0: i64, lips_on: i64, blush_on: i64, shadow_on: i64) -> i64 { 37 var n: i64 = n0 38 let p: *i64 = (base + O_PARTS) as *i64 39 if lips_on == 1 { sdf_set_mat(base, FACE_LIP_UP, MK_LIPSTICK); sdf_set_mat(base, FACE_LIP_LO, MK_LIPSTICK) } 40 if shadow_on == 1 { 41 // the lid band is CROWDED: lash (front z~-724) below y~307, brow field reaching z~-651 across y 280..364. 42 // The lid part must be PROUD of the brow field (front ~-680) so the material query picks it on the 43 // between-lash-and-brow skin, while the lash stays in front in its own band = the real makeup layering. 44 p[n*6]=0-255; p[n*6+1]=315; p[n*6+2]=0-640; p[n*6+3]=148; p[n*6+4]=30; p[n*6+5]=40 45 sdf_set_mat(base, n, MK_EYESHADOW) 46 n = n + 1 47 p[n*6]=255; p[n*6+1]=315; p[n*6+2]=0-640; p[n*6+3]=148; p[n*6+4]=30; p[n*6+5]=40 48 sdf_set_mat(base, n, MK_EYESHADOW) 49 n = n + 1 50 } 51 if blush_on == 1 { 52 // on the MALAR prominence (below the outer eye, out on the cheek mass) -- placement lessons: (+-285,-130, 53 // -480) sat inboard by the nose = gaunt-hollow read; (+-310,-70,-470) was BURIED inside the cheek volume 54 // (surface there ~z-580 -> diff 0). The apple must ride the malar SURFACE ~10-15 units proud: front 55 // reach z ~-595 vs the cheek ellipsoid's ~-580 at (x310,y-70). 56 p[n*6]=0-310; p[n*6+1]=0-70; p[n*6+2]=0-540; p[n*6+3]=100; p[n*6+4]=80; p[n*6+5]=55 57 sdf_set_mat(base, n, MK_BLUSH) 58 n = n + 1 59 p[n*6]=310; p[n*6+1]=0-70; p[n*6+2]=0-540; p[n*6+3]=100; p[n*6+4]=80; p[n*6+5]=55 60 sdf_set_mat(base, n, MK_BLUSH) 61 n = n + 1 62 } 63 let np: *i64 = (base + O_NPART) as *i64 64 np[0] = n 65 return n 66} 67// presets (v2): NATURAL = soft lip + blush apples; GLAM = lip + blush + eyeshadow. Returns the new part count. 68// (v0 makeup_style kept below for old callers -- lipstick-only, no appends.) 69func makeup_style2(base: i64, n0: i64, style: i64) -> i64 { 70 if style == MKUP_NATURAL { return makeup_apply2(base, n0, 1, 1, 0) } 71 if style == MKUP_GLAM { return makeup_apply2(base, n0, 1, 1, 1) } 72 return n0 73} 74func makeup_style(base: i64, style: i64) -> i64 { 75 if style == MKUP_NATURAL { makeup_apply(base, 1, 0) } 76 if style == MKUP_GLAM { makeup_apply(base, 1, 0) } 77 return 0 78} 79func makeup_name(s: i64) -> *u8 { 80 if s == 1 { return "natural" as *u8 } 81 if s == 2 { return "glam" as *u8 } 82 return "bare" as *u8 83}