code wiki / (root) / nx_rigbench_motion_t21.nx

nx_rigbench_motion_t21.nx source

↩ module page · 161 lines · 6775 B

1// Additive rigbench temporal contract; reuse the normative NXA evaluator. 2import "nx_syscalls.nx" 3import "nx_nxa.nx" 4import "nx_nxa_anim_lib.nx" 5const RBM_BYTES: i64 = 8 6const RBM_QUAT: i64 = 4 7const RBM_VERT_STRIDE: i64 = 3 8const RBM_SKIN_STRIDE: i64 = 8 9const RBM_OK: i64 = 0 10const RBM_ABSTAIN: i64 = 3 11const RBM_REFUSE: i64 = 4 12const RBM_R_JOINTS: i64 = 0 13const RBM_R_DURATION: i64 = 1 14const RBM_R_TRACKED: i64 = 2 15const RBM_R_CHANGED: i64 = 3 16const RBM_R_NONIDENTITY_A: i64 = 4 17const RBM_R_NONIDENTITY_B: i64 = 5 18const RBM_R_TIME_A: i64 = 6 19const RBM_R_TIME_B: i64 = 7 20const RBM_R_ASSET_RC: i64 = 8 21const RBM_R_CONSUMER_RC: i64 = 9 22const RBM_R_CONSUMER_MISMATCH_A: i64 = 10 23const RBM_R_CONSUMER_MISMATCH_B: i64 = 11 24const RBM_R_REASON: i64 = 12 25const RBM_R_WORDS: i64 = 13 26const RBM_REASON_NONE: i64 = 0 27const RBM_REASON_SHAPE: i64 = 1 28const RBM_REASON_NO_ANIM: i64 = 2 29const RBM_REASON_TIMES: i64 = 3 30const RBM_REASON_TRACKS: i64 = 4 31const RBM_REASON_STATIC: i64 = 5 32 33func rb_motion_init(rep: *i64) -> i64 { 34 var k: i64 = 0 35 while k < RBM_R_WORDS { rep[k] = 0; k = k + 1 } 36 rep[RBM_R_ASSET_RC] = RBM_ABSTAIN 37 rep[RBM_R_CONSUMER_RC] = RBM_ABSTAIN 38 rep[RBM_R_CONSUMER_MISMATCH_A] = 0 - 1 39 rep[RBM_R_CONSUMER_MISMATCH_B] = 0 - 1 40 return 0 41} 42// A dual quaternion and its simultaneous negation encode the same transform. 43// Comparisons use normative integer rows, before a renderer converts to f32. 44func rb_motion_row_equal(a: *i64, b: *i64, nj: i64, j: i64) -> i64 { 45 let ro: i64 = j * RBM_QUAT 46 let du: i64 = nj * RBM_QUAT + ro 47 var same: i64 = 1 48 var opposite: i64 = 1 49 var k: i64 = 0 50 while k < RBM_QUAT { 51 if a[ro+k] != b[ro+k] { same = 0 } 52 if a[du+k] != b[du+k] { same = 0 } 53 if a[ro+k] != 0-b[ro+k] { opposite = 0 } 54 if a[du+k] != 0-b[du+k] { opposite = 0 } 55 k = k + 1 56 } 57 if same == 1 { return 1 } 58 return opposite 59} 60func rb_motion_nonidentity(a: *i64, nj: i64, j: i64) -> i64 { 61 let ro: i64 = j * RBM_QUAT 62 let du: i64 = nj * RBM_QUAT + ro 63 var k: i64 = 0 64 while k < RBM_QUAT { 65 if a[du+k] != 0 { return 1 } 66 if k < RBM_QUAT-1 { if a[ro+k] != 0 { return 1 } } 67 k = k + 1 68 } 69 let qw: i64 = a[ro+RBM_QUAT-1] 70 if qw == NA_Q12 { return 0 } 71 if qw == 0-NA_Q12 { return 0 } 72 return 1 73} 74func rb_motion_fail(rep: *i64, rc: i64, reason: i64) -> i64 { 75 rep[RBM_R_ASSET_RC] = rc 76 rep[RBM_R_REASON] = reason 77 return rc 78} 79// Inputs are validated counted payloads. Caller owns buffers sized from nj. 80// Raw authored motion has no fitted root drift and no frozen-pose hold. 81func rb_motion_pair(anim: *i64, nw: i64, skel: *i64, nj: i64, ta: i64, tb: i64, idx: *i64, rv: *i64, a: *i64, b: *i64, scr: *i64, rep: *i64) -> i64 { 82 rb_motion_init(rep) 83 rep[RBM_R_JOINTS] = nj 84 rep[RBM_R_TIME_A] = ta 85 rep[RBM_R_TIME_B] = tb 86 if nj < 1 { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_SHAPE) } 87 if ta < 0 { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_TIMES) } 88 if tb <= ta { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_TIMES) } 89 let duration: i64 = na_index(anim,nw,nj,idx) 90 if duration < 0 { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_TRACKS) } 91 rep[RBM_R_DURATION] = duration 92 if tb > duration { return rb_motion_fail(rep,RBM_ABSTAIN,RBM_REASON_TIMES) } 93 var j: i64 = 0 94 while j < nj { if idx[j*NA_IDX_W] >= 0 { rep[RBM_R_TRACKED] = rep[RBM_R_TRACKED]+1 } j=j+1 } 95 var k: i64 = 0 96 while k < NA_RV_W { rv[k]=0; k=k+1 } 97 na_rows(anim,idx,nj,skel,0 as *i64,0 as *i64,0,rv,ta,0,a,scr) 98 na_rows(anim,idx,nj,skel,0 as *i64,0 as *i64,0,rv,tb,0,b,scr) 99 j=0 100 while j < nj { 101 if rb_motion_row_equal(a,b,nj,j) == 0 { rep[RBM_R_CHANGED]=rep[RBM_R_CHANGED]+1 } 102 rep[RBM_R_NONIDENTITY_A]=rep[RBM_R_NONIDENTITY_A]+rb_motion_nonidentity(a,nj,j) 103 rep[RBM_R_NONIDENTITY_B]=rep[RBM_R_NONIDENTITY_B]+rb_motion_nonidentity(b,nj,j) 104 j=j+1 105 } 106 if rep[RBM_R_CHANGED] == 0 { return rb_motion_fail(rep,RBM_ABSTAIN,RBM_REASON_STATIC) } 107 return rb_motion_fail(rep,RBM_OK,RBM_REASON_NONE) 108} 109// API receipts must independently bind asset/evaluator/scene/observation hashes. 110// Matching these two palettes alone does not prove a visible rendered animation. 111func rb_motion_consumer(a: *i64,b: *i64,oa: *i64,ob: *i64,nj: i64,rep: *i64) -> i64 { 112 rep[RBM_R_CONSUMER_RC]=RBM_ABSTAIN 113 if rep[RBM_R_ASSET_RC] != RBM_OK { return RBM_ABSTAIN } 114 if nj != rep[RBM_R_JOINTS] { rep[RBM_R_CONSUMER_RC]=RBM_REFUSE; return RBM_REFUSE } 115 var j: i64 = 0 116 var ma: i64 = 0 117 var mb: i64 = 0 118 while j < nj { 119 if rb_motion_row_equal(a,oa,nj,j) == 0 { ma=ma+1 } 120 if rb_motion_row_equal(b,ob,nj,j) == 0 { mb=mb+1 } 121 j=j+1 122 } 123 rep[RBM_R_CONSUMER_MISMATCH_A]=ma 124 rep[RBM_R_CONSUMER_MISMATCH_B]=mb 125 if ma+mb > 0 { rep[RBM_R_CONSUMER_RC]=RBM_REFUSE; return RBM_REFUSE } 126 rep[RBM_R_CONSUMER_RC]=RBM_OK 127 return RBM_OK 128} 129func rb_motion_asset(b: *u8,flen: i64,ta: i64,tb: i64,max_joints: i64,rep: *i64) -> i64 { 130 rb_motion_init(rep) 131 let vo: i64 = nxa_counted_section(b,flen,nxa_tag4("VERT" as *u8),RBM_VERT_STRIDE) 132 let so: i64 = nxa_counted_section(b,flen,nxa_tag4("SKEL" as *u8),NA_SKEL_W) 133 let ko: i64 = nxa_counted_section(b,flen,nxa_tag4("SKIN" as *u8),RBM_SKIN_STRIDE) 134 if vo < 0 { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_SHAPE) } 135 if so < 0 { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_SHAPE) } 136 if ko < 0 { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_SHAPE) } 137 let w: *i64 = b as *i64 138 let nj: i64 = w[so] 139 rep[RBM_R_JOINTS]=nj 140 if nj < 1 { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_SHAPE) } 141 if nj > max_joints { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_SHAPE) } 142 if w[vo] != w[ko] { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_SHAPE) } 143 let ae: i64 = nxa_section_entry(b,flen,nxa_tag4("ANIM" as *u8)) 144 if ae == 0-1 { return rb_motion_fail(rep,RBM_ABSTAIN,RBM_REASON_NO_ANIM) } 145 if ae < 0 { return rb_motion_fail(rep,RBM_REFUSE,RBM_REASON_SHAPE) } 146 let anim: *i64 = ((b as i64)+w[ae+1]) as *i64 147 let skel: *i64 = ((b as i64)+(so+1)*RBM_BYTES) as *i64 148 let ni: i64 = nj*NA_IDX_W*RBM_BYTES 149 let nr: i64 = nj*NA_ROW_W*RBM_BYTES 150 let ns: i64 = NA_SCR_W*RBM_BYTES 151 let nv: i64 = NA_RV_W*RBM_BYTES 152 let idx: *i64 = sys_mmap(ni) as *i64 153 let a: *i64 = sys_mmap(nr) as *i64 154 let outb: *i64 = sys_mmap(nr) as *i64 155 let scr: *i64 = sys_mmap(ns) as *i64 156 let rv: *i64 = sys_mmap(nv) as *i64 157 let rc: i64 = rb_motion_pair(anim,w[ae+2],skel,nj,ta,tb,idx,rv,a,outb,scr,rep) 158 sys_munmap(idx as *u8,ni);sys_munmap(a as *u8,nr);sys_munmap(outb as *u8,nr) 159 sys_munmap(scr as *u8,ns);sys_munmap(rv as *u8,nv) 160 return rc 161}