nx_bvh_nearest_asset_gate_t284.nx source
↩ module page · 110 lines · 5228 B
1// Native representative asset evaluator, using shared NXA admission and NxBvh.
2// Each accelerated query is compared with exhaustive traversal of admitted triangles.
3// This checks BVH pruning independently; analytic kernel controls are a separate gate.
4// No sign/inside, collision response, hair support, motion or beauty claim.
5import "nx_bvh_nearest_candidate_t284.nx"
6import "nx_nxa.nx"
7import "nx_gate_verdict.nx"
8func bqa_is_hair(s:*u8)->i64{
9 let expected:*u8="hair" as *u8
10 var i:i64=0
11 while expected[i]!=(0 as u8){if s[i]!=expected[i]{return 0};i=i+1}
12 if s[i]!=(0 as u8){return 0}
13 return 1
14}
15func main(argc:i64,argv:*i64)->i64{
16 if argc<2||argc>3{gv_puts("usage: asset.nxa [hair]\n" as *u8);return 2}
17 if argc==3{if bqa_is_hair(argv[2] as *u8)==0{gv_puts("unsupported query mode\n" as *u8);return 2}}
18 let size:*i64=sys_mmap(16) as *i64
19 let data:*u8=sys_read_file(argv[1] as *u8,size)
20 if (data as i64)==0{return 3}
21 let h:*i64=data as *i64
22 let vo:i64=nxa_counted_section(data,size[0],nxa_tag4("VERT" as *u8),3)
23 let to:i64=nxa_counted_section(data,size[0],nxa_tag4("TRIS" as *u8),3)
24 if vo<0||to<0{gv_puts("source sections refused\n" as *u8);return 4}
25 let nv:i64=h[vo];let nt:i64=h[to]
26 var ho:i64=0-1
27 if argc==3{
28 ho=nxa_counted_section(data,size[0],nxa_tag4("HSTR" as *u8),24)
29 if ho<0{gv_puts("HSTR unavailable; hair query unsupported\n" as *u8);return 8}
30 if h[ho]<1{gv_puts("HSTR empty; no hair queries available\n" as *u8);return 8}
31 }
32 let m:*NxMesh=nx_mesh_alloc(nv,nt,0)
33 if (m as i64)==0{return 5}
34 var v:i64=0
35 while v<nv{
36 var a:i64=0;while a<3{
37 let x:i64=h[vo+1+v*3+a]
38 if nx_f64_to_i64(nx_i64_to_f64(x))!=x{gv_puts("coordinate not exactly representable\n" as *u8);return 6}
39 m.verts[v*4+a]=x;a=a+1
40 };m.verts[v*4+3]=0;v=v+1
41 }
42 var i:i64=0;while i<nt*3{m.indices[i]=h[to+1+i];i=i+1}
43 if nx_mesh_validate(m)!=NX_MESH_OK{return 7}
44 let b:*NxBvh=nx_bvh_build(m)
45 let stack:*i64=sys_mmap(b.n_nodes*8) as *i64
46 let out:*f64=sys_mmap(32) as *f64;let scratch:*f64=sys_mmap(64) as *f64
47 let meta:*i64=sys_mmap(32) as *i64;let brute:*f64=sys_mmap(32) as *f64;let trial:*f64=sys_mmap(32) as *f64
48 let ctr:*i64=gv_ctr();gv_head("actual NXA nearest surface" as *u8)
49 gv_kv("source_bytes" as *u8,size[0]);gv_kv("vertices" as *u8,nv);gv_kv("triangles" as *u8,nt);gv_kv("bvh_nodes" as *u8,b.n_nodes)
50 var k:i64=0
51 while k<5{
52 let ti:i64=k*(nt-1)/4;let vi:i64=m.indices[ti*3]
53 var x:i64=m.verts[vi*4];var y:i64=m.verts[vi*4+1];var z:i64=m.verts[vi*4+2]
54 if ho>=0{
55 let g:i64=k*(h[ho]-1)/4
56 x=h[ho+1+g*24+12];y=h[ho+1+g*24+13];z=h[ho+1+g*24+14]
57 }
58 let rc:i64=nx_bvh_nearest_query(b,m,x,y,z,stack,b.n_nodes,out,4,scratch,8,meta,4)
59 gv_check_eq("accelerated query status" as *u8,rc,0,ctr)
60 if rc!=0{return 9}
61 let px:f64=bq_f(x);let py:f64=bq_f(y);let pz:f64=bq_f(z)
62 bq_mesh_triangle(m,0,brute,scratch,px,py,pz)
63 i=1;while i<nt{bq_mesh_triangle(m,i,trial,scratch,px,py,pz);bq_copy_best(brute,trial);i=i+1}
64 gv_check_eq("BVH exhaustive distance bits" as *u8,out[3] as i64,brute[3] as i64,ctr)
65 if ho<0{gv_check_eq("referenced surface vertex distance" as *u8,out[3] as i64,0,ctr)}
66 gv_kv("query" as *u8,k);gv_kv("nearest_triangle" as *u8,meta[0])
67 gv_kv("nodes_visited" as *u8,meta[1]);gv_kv("triangles_tested" as *u8,meta[2])
68 gv_kv("degenerate_tests" as *u8,meta[3]);gv_kv("distance_squared_floor" as *u8,nx_f64_to_i64(out[3] as i64))
69 k=k+1
70 }
71 // Independent support-plane oracle: every referenced triangle point is within
72 // each axis extremum. The chosen vertex attains the lower bound d^2.
73 var axis:i64=0
74 while axis<3{
75 var lo:i64=m.indices[0];var hi:i64=lo
76 i=1
77 while i<nt*3{
78 let vi:i64=m.indices[i]
79 if m.verts[vi*4+axis]<m.verts[lo*4+axis]{lo=vi}
80 if m.verts[vi*4+axis]>m.verts[hi*4+axis]{hi=vi}
81 i=i+1
82 }
83 let span:f64=bq_f(m.verts[hi*4+axis])-bq_f(m.verts[lo*4+axis])
84 var delta:i64=nx_f64_to_i64((span/2.0) as i64)
85 if delta<1{delta=1}
86 var side:i64=0
87 while side<2{
88 var vi:i64=lo
89 var sign:f64=0.0-1.0
90 if side==1{vi=hi;sign=1.0}
91 let q:*i64=sys_mmap(24) as *i64
92 q[0]=m.verts[vi*4];q[1]=m.verts[vi*4+1];q[2]=m.verts[vi*4+2]
93 let desired:f64=bq_f(q[axis])+sign*bq_f(delta)
94 q[axis]=nx_f64_to_i64(desired as i64)
95 if (bq_f(q[axis]) as i64)!=(desired as i64){gv_puts("off-surface coordinate not exactly representable\n" as *u8);return 10}
96 let rc:i64=nx_bvh_nearest_query(b,m,q[0],q[1],q[2],stack,b.n_nodes,out,4,scratch,8,meta,4)
97 gv_check_eq("independent off-surface status" as *u8,rc,0,ctr)
98 if rc!=0{return 11}
99 var a:i64=0
100 while a<3{gv_check_eq("extreme vertex nearest coordinate bits" as *u8,out[a] as i64,nx_i64_to_f64(m.verts[vi*4+a]),ctr);a=a+1}
101 let expected:f64=bq_f(delta)*bq_f(delta)
102 gv_check_eq("support-plane independent distance bits" as *u8,out[3] as i64,expected as i64,ctr)
103 gv_kv("off_surface_axis" as *u8,axis);gv_kv("off_surface_side" as *u8,side)
104 gv_kv("extreme_vertex" as *u8,vi);gv_kv("offset_source_units" as *u8,delta)
105 side=side+1
106 }
107 axis=axis+1
108 }
109 return gv_verdict("nx_bvh_nearest_asset_gate_t284" as *u8,ctr,"per-asset six independent off-surface support-plane probes plus shared-kernel exhaustive probes; no signed contact, motion or general hair qualification" as *u8)
110}