code wiki / (root) / nx_hairdyn_pose_gate_t263.nx

nx_hairdyn_pose_gate_t263.nx source

↩ module page · 51 lines · 3300 B

1// Real HSTR guide0 from SHA31778134b5167258b05b18ae9ae062c073fd03fb3f46d212e3512d28660c4fed. 2// Numerical tests use mesh units promoted to solver Q8; no world-frame claim. 3import "nx_hairdyn_pose_candidate_t263.nx" 4import "nx_hairdyn_lib.nx" 5import "nx_gate_verdict.nx" 6func hp_seat(st:*i64,rest:*i64,n:i64)->i64 { 7 var i:i64=0 8 while i<n { 9 let b:i64=i*SD_STRIDE;let r:i64=(i+1)*3 10 st[b]=rest[r];st[b+1]=rest[r+1];st[b+2]=rest[r+2] 11 st[b+3]=0;st[b+4]=0;st[b+5]=0;i=i+1 12 } 13 return 0 14} 15func main()->i64 { 16 let ctr:*i64=gv_ctr();gv_head("posed authored hair guide" as *u8) 17 let rest:*i64=sys_mmap(24*8) as *i64 18 rest[0]=5937*SD_Q8;rest[1]=5160*SD_Q8;rest[2]=159683*SD_Q8;rest[3]=4851*SD_Q8;rest[4]=5818*SD_Q8;rest[5]=157344*SD_Q8;rest[6]=4320*SD_Q8;rest[7]=6311*SD_Q8;rest[8]=153526*SD_Q8;rest[9]=4376*SD_Q8;rest[10]=6311*SD_Q8;rest[11]=148302*SD_Q8;rest[12]=3917*SD_Q8;rest[13]=6311*SD_Q8;rest[14]=141772*SD_Q8;rest[15]=4138*SD_Q8;rest[16]=6311*SD_Q8;rest[17]=133936*SD_Q8;rest[18]=4414*SD_Q8;rest[19]=6311*SD_Q8;rest[20]=124794*SD_Q8;rest[21]=3700*SD_Q8;rest[22]=6311*SD_Q8;rest[23]=114346*SD_Q8 19 let st:*i64=hd_alloc(7);let scratch:*i64=sys_mmap(24) as *i64 20 hp_seat(st,rest,7) 21 let c:i64=hd_tick_posed_collide(st,7,rest,SB_K_HAIR,SB_C_HAIR,SB_MAXD_HAIR,0 as *i64,0,scratch) 22 gv_check_eq("no collider no contacts" as *u8,c,0,ctr) 23 var err:i64=0;var i:i64=0 24 while i<7 {var a:i64=0;while a<3 {if st[i*SD_STRIDE+a]!=rest[(i+1)*3+a] {err=err+1};a=a+1};i=i+1} 25 gv_check_eq("all authored coordinates remain at rest" as *u8,err,0,ctr) 26 // Exact quarter turn around source Z and translation; deformation targets 27 // and state must transform together, rather than falling into a Y-up chain. 28 let rotated:*i64=sys_mmap(24*8) as *i64 29 i=0 30 while i<8 {rotated[i*3]=0-rest[i*3+1]+rest[0];rotated[i*3+1]=rest[i*3]+rest[1];rotated[i*3+2]=rest[i*3+2];i=i+1} 31 hp_seat(st,rotated,7) 32 hd_tick_posed_collide(st,7,rotated,SB_K_HAIR,SB_C_HAIR,SB_MAXD_HAIR,0 as *i64,0,scratch) 33 err=0;i=0 34 while i<7 {var a:i64=0;while a<3 {if st[i*SD_STRIDE+a]!=rotated[(i+1)*3+a] {err=err+1};a=a+1};i=i+1} 35 gv_check_eq("posed quarter turn preserves authored contour" as *u8,err,0,ctr) 36 // Collision against a sphere centered on the first authored node. 37 // Radius is one quarter of actual root-to-node length. 38 let dx:i64=rest[3]-rest[0];let dy:i64=rest[4]-rest[1];let dz:i64=rest[5]-rest[2] 39 let radius:i64=vm_isqrt(dx*dx+dy*dy+dz*dz)/4 40 let caps:*i64=sys_mmap(7*8) as *i64 41 caps[0]=rest[3];caps[1]=rest[4];caps[2]=rest[5];caps[3]=rest[3];caps[4]=rest[4];caps[5]=rest[5];caps[6]=radius 42 hp_seat(st,rest,7) 43 let contacts:i64=hd_tick_posed_collide(st,1,rest,SB_K_HAIR,SB_C_HAIR,SB_MAXD_HAIR,caps,1,scratch) 44 gv_check_eq("entered node reports contact" as *u8,contacts,1,ctr) 45 let px:i64=st[0]-caps[0];let py:i64=st[1]-caps[1];let pz:i64=st[2]-caps[2] 46 gv_check_eq("entered node is on fixture sphere" as *u8,vm_isqrt(px*px+py*py+pz*pz),radius,ctr) 47 hp_seat(st,rest,7) 48 hd_tick_posed_collide(st,1,rest,SB_K_HAIR,SB_C_HAIR,SB_MAXD_HAIR,caps,0,scratch) 49 gv_check_eq("no collision control remains inside fixture" as *u8,st[0],caps[0],ctr) 50 return gv_verdict("nx_hairdyn_pose_gate_t263" as *u8,ctr,"authored rest and transformed rest preserved; entered-node collision and disabled control; not runtime or ribbon-width qualification" as *u8) 51}