nx_sdf_attribution_gate_t344.nx source
↩ module page · 114 lines · 7570 B
1// nx_sdf_attribution_gate_t344.nx -- Computes signed distance fields for 3D objects using per-part blending and surface operations.
2import "nx_sdfrender.nx"
3import "nx_gate_verdict.nx"
4func reference_eval(base: i64, px: i64, py: i64, pz: i64) -> i64 {
5 let p: *i64 = (base + O_PARTS) as *i64
6 let kp: *i64 = (base + O_KBLEND) as *i64
7 var k: i64 = kp[0]
8 if k <= 0 { k = KBLEND }
9 let npp: *i64 = (base + O_NPART) as *i64
10 var np: i64 = npp[0]
11 if np <= 0 { np = NPART }
12 if np > PARTS_CAP { np = PARTS_CAP }
13 let op: *i64 = (base + O_OPS) as *i64
14 let k2: *i64 = (base + O_KB2) as *i64
15 let rt: *i64 = (base + O_ROT) as *i64
16 let rl: *i64 = (base + O_ROLL) as *i64
17 let pr: *i64 = (base + O_PRIM) as *i64
18 var d: i64 = PARTS_MAGIC_999999
19 var i: i64 = 0
20 while i < np {
21 let rc: i64 = rt[i * 2]
22 let rs: i64 = rt[i * 2 + 1]
23 var di: i64 = 0
24 if op[i] == SDF_OP_LIDSHELL { // a lid shell reads its own parameter row and its roll, never the ellipsoid
25 di = sdf_lidshell(px, py, pz, p[i*6], p[i*6+1], p[i*6+2], p[i*6+3], p[i*6+4], p[i*6+5], pr[i*SDF_PRIM_FIELDS+SDF_PR_HALFW], pr[i*SDF_PRIM_FIELDS+SDF_PR_UP], pr[i*SDF_PRIM_FIELDS+SDF_PR_LOW], rl[i*SDF_ROT_FIELDS], rl[i*SDF_ROT_FIELDS+1])
26 } else {
27 if rc == 0 { if rs == 0 { // identity (unrotated) -> the fast path
28 di = sdf_ellip(px, py, pz, p[i*6], p[i*6+1], p[i*6+2], p[i*6+3], p[i*6+4], p[i*6+5])
29 } else { di = sdf_ellip_rot(px, py, pz, p[i*6], p[i*6+1], p[i*6+2], p[i*6+3], p[i*6+4], p[i*6+5], rc, rs) } }
30 else { di = sdf_ellip_rot(px, py, pz, p[i*6], p[i*6+1], p[i*6+2], p[i*6+3], p[i*6+4], p[i*6+5], rc, rs) }
31 }
32 if op[i] == SDF_OP_LIPSWEEP { di = sdf_lipsweep_part(base, i, px, py, pz) } // a lip reads its own sweep, never the ellipsoid of its six numbers
33 var ki: i64 = k2[i] // per-part blend; 0 -> inherit the body default
34 if ki <= 0 { ki = k }
35 if i == 0 { d = di } else {
36 if op[i] == 1 { d = sdf_smax(d, 0 - di, ki) } // CARVE this part out (eye socket, mouth, nostril)
37 else { d = sdf_smin(d, di, ki) } // UNION (add)
38 }
39 i = i + 1
40 }
41 return d
42}
43
44func reference_part(base: i64, px: i64, py: i64, pz: i64) -> i64 {
45 let p: *i64 = (base + O_PARTS) as *i64
46 let npp: *i64 = (base + O_NPART) as *i64
47 var np: i64 = npp[0]
48 if np <= 0 { np = NPART }
49 if np > PARTS_CAP { np = PARTS_CAP }
50 let op: *i64 = (base + O_OPS) as *i64
51 let rl: *i64 = (base + O_ROLL) as *i64
52 let pr: *i64 = (base + O_PRIM) as *i64
53 var best: i64 = 0
54 var bd: i64 = PARTS_MAGIC_999999
55 var i: i64 = 0
56 while i < np {
57 if op[i] == 0 { // carve parts are TOOLS, not surfaces -- skip for material
58 let di: i64 = sdf_ellip(px, py, pz, p[i*6], p[i*6+1], p[i*6+2], p[i*6+3], p[i*6+4], p[i*6+5])
59 if di < bd { bd = di; best = i }
60 }
61 if op[i] == SDF_OP_LIDSHELL { // a lid is a SURFACE with its own field, never an ellipsoid of its six numbers
62 let dls: i64 = sdf_lidshell(px, py, pz, p[i*6], p[i*6+1], p[i*6+2], p[i*6+3], p[i*6+4], p[i*6+5], pr[i*SDF_PRIM_FIELDS+SDF_PR_HALFW], pr[i*SDF_PRIM_FIELDS+SDF_PR_UP], pr[i*SDF_PRIM_FIELDS+SDF_PR_LOW], rl[i*SDF_ROT_FIELDS], rl[i*SDF_ROT_FIELDS+1])
63 if dls < bd { bd = dls; best = i }
64 }
65 if op[i] == SDF_OP_LIPSWEEP { // a lip is a swept half tube with its own field
66 let dlp: i64 = sdf_lipsweep_part(base, i, px, py, pz)
67 if dlp < bd { bd = dlp; best = i }
68 }
69 i = i + 1
70 }
71 return best
72}
73
74func at_set(base:i64,i:i64,x:i64,y:i64,z:i64,rx:i64,ry:i64,rz:i64)->i64{
75 let p:*i64=(base+O_PARTS) as *i64;p[i*6]=x;p[i*6+1]=y;p[i*6+2]=z;p[i*6+3]=rx;p[i*6+4]=ry;p[i*6+5]=rz;return 0
76}
77func main()->i64{
78 let c:*i64=gv_ctr();let b:i64=sys_mmap(sdf_bytes()) as i64;sdf_body(b)
79 var same:i64=1;var x:i64=-2;while x<=2{var y:i64=-2;while y<=2{var z:i64=-2;while z<=2{
80 if sdf_eval(b,x*400,y*800,z*400)!=reference_eval(b,x*400,y*800,z*400){same=0}
81 if sdf_eval_part(b,x*400,y*800,z*400)!=reference_part(b,x*400,y*800,z*400){same=0}
82 z=z+1};y=y+1};x=x+1}
83 gv_check("125 actual body field and unrotated attribution samples unchanged",same,c)
84 let np:*i64=(b+O_NPART) as *i64;let k:*i64=(b+O_KBLEND) as *i64;let rt:*i64=(b+O_ROT) as *i64
85 sdf_clear_ops(b,PARTS_CAP);np[0]=2;k[0]=1
86 at_set(b,0,0,0,0,100,1000,100);at_set(b,1,0,1050,0,100,100,100)
87 sdf_set_mat(b,0,2);sdf_set_mat(b,1,1);rt[0]=0;rt[1]=256
88 gv_check_eq("original rotation attribution mismatch reproduced",reference_part(b,0,950,0),0,c)
89 gv_check_eq("shared rotated primitive selects actual surface owner",sdf_eval_part(b,0,950,0),1,c)
90 gv_check_eq("rotated field unchanged",sdf_eval(b,0,950,0),reference_eval(b,0,950,0),c)
91 let out:*i64=sys_mmap(SDF_AT_WORDS*8) as *i64
92 gv_check("attribution matches field and eye material",sdf_part_attribution(b,0,950,0,out,SDF_AT_WORDS)==0&&out[SDF_AT_PART]==1&&out[SDF_AT_MATERIAL]==1&&out[SDF_AT_FIELD]==sdf_eval(b,0,950,0),c)
93 sdf_clear_ops(b,PARTS_CAP);np[0]=2;k[0]=100
94 at_set(b,0,0,0,0,100,100,100);at_set(b,1,0,0,0,100,100,100);sdf_set_mat(b,1,1)
95 sdf_part_attribution(b,100,0,0,out,SDF_AT_WORDS)
96 gv_check("smooth union reports composed-field and tied-owner ambiguity",out[SDF_AT_COMPOSED]==1&&out[SDF_AT_TIED]==1&&out[SDF_AT_NEAREST]==0&&out[SDF_AT_FIELD]==-25,c)
97 at_set(b,1,0,0,0,50,50,50);sdf_set_op(b,1,1);sdf_set_mat(b,1,2);k[0]=1
98 sdf_part_attribution(b,0,0,0,out,SDF_AT_WORDS)
99 gv_check("carve tool never becomes material owner",out[SDF_AT_PART]==0&&out[SDF_AT_MATERIAL]==0&&out[SDF_AT_COMPOSED]==1,c)
100 gv_check_eq("carved field unchanged",sdf_eval(b,0,0,0),reference_eval(b,0,0,0),c)
101 sdf_clear_ops(b,PARTS_CAP);np[0]=1;at_set(b,0,0,0,0,100,10,100);sdf_set_op(b,0,SDF_OP_LIDSHELL)
102 sdf_set_prim(b,0,SDF_PR_HALFW,50);sdf_set_prim(b,0,SDF_PR_UP,20);sdf_set_prim(b,0,SDF_PR_LOW,15);sdf_set_roll(b,0,200)
103 same=1;x=-2;while x<=2{var y:i64=-2;while y<=2{if sdf_eval(b,x*25,y*25,-100)!=reference_eval(b,x*25,y*25,-100){same=0};if sdf_eval_part(b,x*25,y*25,-100)!=reference_part(b,x*25,y*25,-100){same=0};y=y+1};x=x+1}
104 gv_check("rolled lid shell geometry and attribution preserved",same,c)
105 sdf_set_mat(b,0,0);let lm:i64=sdf_surface_material(b,0,0,20)
106 gv_check("lash material uses existing lid-margin predicate",lm==4*sdf_lid_lash(b,0,0,20),c)
107 sdf_clear_ops(b,PARTS_CAP);np[0]=1;at_set(b,0,0,0,0,100,30,20);sdf_set_op(b,0,SDF_OP_LIPSWEEP);sdf_set_prim(b,0,SDF_PL_TAPER,500);sdf_set_prim(b,0,SDF_PL_SIDE,1)
108 same=1;x=-2;while x<=2{var y:i64=-2;while y<=2{if sdf_eval(b,x*25,y*10,-10)!=reference_eval(b,x*25,y*10,-10){same=0};if sdf_eval_part(b,x*25,y*10,-10)!=reference_part(b,x*25,y*10,-10){same=0};y=y+1};x=x+1}
109 gv_check("lip sweep geometry and attribution preserved",same,c)
110 out[0]=77;gv_check("invalid attribution record leaves output untouched",sdf_part_attribution(b,0,0,0,out,SDF_AT_WORDS-1)==-1&&out[0]==77,c)
111 sdf_part_attribution(b,0,0,0,out,SDF_AT_WORDS);gv_check("single surface explicitly has no runner-up",out[SDF_AT_RUNNER_PART]==-1&&out[SDF_AT_TIED]==0,c)
112 sdf_set_op(b,0,1);gv_check("all-carve arena refuses absent material surface",sdf_part_attribution(b,0,0,0,out,SDF_AT_WORDS)==-2,c)
113 return gv_verdict("SDF-ATTRIBUTION",c,"shared primitive transform parity; nearest-part display approximation with composed/tied evidence, no anatomical confidence claim")
114}