code wiki / (root) / nx_fbx_rig.nx

nx_fbx_rig.nx source

↩ module page · 182 lines · 7158 B

1// nx_fbx_rig.nx -- RIG SURVEY: verified-facts instrument for the SKEL/SKIN/ANIM fill. 2// Walks a binary FBX and inventories the rig: Model/LimbNode counts (joints), Deformer 3// Skin/Cluster counts, Indexes/Weights array totals, Connections, AnimationCurve counts, 4// KeyTime totals -- and prints the first joint names. NOTHING is emitted yet: this is the 5// query-before-design step (agent prompts and format emitters get MEASURED facts, not guesses). 6// usage: nx_fbx_rig <file.fbx> 7// license_tier: ORIGINAL 8import "nx_syscalls.nx" 9const K_MAGIC_7500: i64 = 7500 10const K_MAGIC_500000: i64 = 500000 11 12func frw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 13func frn(v: i64) -> i64 { 14 let t: *u8 = sys_mmap(32) as *u8 15 var m: i64 = v; var w: i64 = 0 16 if m<0 { t[w]=45 as u8; w=w+1; m=0-m } 17 if m==0 { t[w]=48 as u8; sys_write(1,t,w+1); return 0 } 18 let d: *u8 = sys_mmap(32) as *u8 19 var k: i64=0 20 while m>0 { d[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } 21 var j: i64=0 22 while j<k { t[w]=d[k-1-j]; w=w+1; j=j+1 } 23 sys_write(1,t,w); return 0 24} 25func fr_u32(b: *u8, o: i64) -> i64 { 26 return ((b[o] & 0xff) as i64) | (((b[o+1] & 0xff) as i64) << 8) 27 | (((b[o+2] & 0xff) as i64) << 16) | (((b[o+3] & 0xff) as i64) << 24) 28} 29func fr_u64(b: *u8, o: i64) -> i64 { return fr_u32(b, o) | (fr_u32(b, o + 4) << 32) } 30 31// stats: 0=Model 1=LimbNode 2=Skin 3=Cluster 4=IndexesElems 5=WeightsElems 6=Conns 32// 7=AnimCurveNode 8=AnimCurve 9=KeyTimeElems 10=TransformArrays 11=jointNamesPrinted 33func fr_walk(b: *u8, flen: i64, off0: i64, big: i64, st: *i64) -> i64 { 34 var off: i64 = off0 35 var endo: i64 = 0 36 var nprops: i64 = 0 37 var plen: i64 = 0 38 var nlen: i64 = 0 39 var p: i64 = 0 40 if big == 1 { 41 endo = fr_u64(b, off) 42 nprops = fr_u64(b, off + 8) 43 plen = fr_u64(b, off + 16) 44 nlen = (b[off + 24] & 0xff) as i64 45 p = off + 25 46 } 47 if big == 0 { 48 endo = fr_u32(b, off) 49 nprops = fr_u32(b, off + 4) 50 plen = fr_u32(b, off + 8) 51 nlen = (b[off + 12] & 0xff) as i64 52 p = off + 13 53 } 54 if endo == 0 { return off } 55 if endo > flen { return flen } 56 // classify the node by name 57 var kind: i64 = 0 58 if nlen == 5 { if (b[p]&0xff)==77 { if (b[p+4]&0xff)==108 { kind = 1 } } } // Model 59 if nlen == 8 { if (b[p]&0xff)==68 { if (b[p+7]&0xff)==114 { kind = 2 } } } // Deformer 60 if nlen == 7 { 61 if (b[p]&0xff)==73 { if (b[p+6]&0xff)==115 { kind = 3 } } // Indexes 62 if (b[p]&0xff)==87 { if (b[p+6]&0xff)==115 { kind = 4 } } // Weights 63 if (b[p]&0xff)==75 { if (b[p+6]&0xff)==101 { kind = 5 } } // KeyTime 64 } 65 if nlen == 1 { if (b[p]&0xff)==67 { kind = 6 } } // C 66 if nlen == 18 { if (b[p]&0xff)==65 { if (b[p+17]&0xff)==101 { kind = 7 } } } // AnimationCurveNode 67 if nlen == 14 { if (b[p]&0xff)==65 { if (b[p+13]&0xff)==101 { kind = 8 } } } // AnimationCurve 68 if nlen == 9 { if (b[p]&0xff)==84 { if (b[p+8]&0xff)==109 { kind = 9 } } } // Transform 69 p = p + nlen 70 let pstart: i64 = p 71 // walk props; capture 2nd/3rd S-prop offsets+lens for Model/Deformer subtype checks 72 var s2o: i64 = 0 73 var s2l: i64 = 0 74 var s3o: i64 = 0 75 var s3l: i64 = 0 76 var sseen: i64 = 0 77 var pi: i64 = 0 78 var stop: i64 = 0 79 while pi < nprops { 80 if stop == 0 { 81 let t: i64 = (b[p] & 0xff) as i64 82 p = p + 1 83 var adv: i64 = 0 - 1 84 if t == 83 { 85 let l: i64 = fr_u32(b, p) 86 sseen = sseen + 1 87 if sseen == 1 { s2o = p + 4; s2l = l } 88 if sseen == 2 { s3o = p + 4; s3l = l } 89 adv = 4 + l 90 } 91 if t == 82 { adv = 4 + fr_u32(b, p) } 92 if t == 89 { adv = 2 } 93 if t == 67 { adv = 1 } 94 if t == 73 { adv = 4 } 95 if t == 70 { adv = 4 } 96 if t == 68 { adv = 8 } 97 if t == 76 { adv = 8 } 98 var isarr: i64 = 0 99 if t == 100 { isarr = 1 } 100 if t == 102 { isarr = 1 } 101 if t == 108 { isarr = 1 } 102 if t == 105 { isarr = 1 } 103 if t == 98 { isarr = 1 } 104 if isarr == 1 { 105 let alen: i64 = fr_u32(b, p) 106 let clen: i64 = fr_u32(b, p + 8) 107 if kind == 3 { st[4] = st[4] + alen } 108 if kind == 4 { st[5] = st[5] + alen } 109 if kind == 5 { st[9] = st[9] + alen } 110 if kind == 9 { st[10] = st[10] + alen } 111 adv = 12 + clen 112 } 113 if adv < 0 { stop = 1 } 114 if adv >= 0 { p = p + adv } 115 } 116 pi = pi + 1 117 } 118 if kind == 1 { 119 st[0] = st[0] + 1 120 // Model props: [L id][S name][S class] -- class is the 2nd S (s3), "LimbNode" = a joint 121 if s3l == 8 { if (b[s3o]&0xff)==76 { if (b[s3o+7]&0xff)==101 { 122 st[1] = st[1] + 1 123 if st[11] < 8 { if s2l > 0 { if s2l < 64 { 124 frw(" joint: " as *u8) 125 var q: i64 = 0 126 while q < s2l { if (b[s2o+q]&0xff) != 0 { if (b[s2o+q]&0xff) != 1 { sys_write(1, ((b as i64)+s2o+q) as *u8, 1) } } q = q + 1 } 127 frw("\n" as *u8) 128 st[11] = st[11] + 1 129 } } } 130 } } } 131 } 132 if kind == 2 { 133 if s3l == 4 { st[2] = st[2] + 1 } 134 if s3l == 7 { st[3] = st[3] + 1 } 135 } 136 if kind == 6 { st[6] = st[6] + 1 } 137 if kind == 7 { st[7] = st[7] + 1 } 138 if kind == 8 { st[8] = st[8] + 1 } 139 p = pstart + plen 140 var sent: i64 = 13 141 if big == 1 { sent = 25 } 142 while p < endo - sent { 143 p = fr_walk(b, flen, p, big, st) 144 if p >= flen { return flen } 145 } 146 return endo 147} 148 149func main(argc: i64, argv: *i64) -> i64 { 150 if argc < 2 { frw("usage: nx_fbx_rig <file.fbx>\n" as *u8); return 2 } 151 let lp: *i64 = sys_mmap(16) as *i64 152 let b: *u8 = sys_map_file(argv[1] as *u8, lp) 153 let flen: i64 = lp[0] 154 if flen < 64 { frw("unreadable\n" as *u8); return 3 } 155 let ver: i64 = fr_u32(b, 23) 156 var big: i64 = 0 157 if ver >= K_MAGIC_7500 { big = 1 } 158 frw("FBX ver=" as *u8); frn(ver); frw("\n" as *u8) 159 let st: *i64 = sys_mmap(128) as *i64 160 var pos: i64 = 27 161 var guard: i64 = 0 162 while pos < flen - 200 { 163 if guard > K_MAGIC_500000 { break } 164 let e: i64 = fr_walk(b, flen, pos, big, st) 165 if e <= pos { break } 166 pos = e 167 guard = guard + 1 168 } 169 frw("models=" as *u8); frn(st[0]) 170 frw(" limbnodes=" as *u8); frn(st[1]) 171 frw(" skins=" as *u8); frn(st[2]) 172 frw(" clusters=" as *u8); frn(st[3]) 173 frw("\nindexes_elems=" as *u8); frn(st[4]) 174 frw(" weights_elems=" as *u8); frn(st[5]) 175 frw(" transform_elems=" as *u8); frn(st[10]) 176 frw("\nconnections=" as *u8); frn(st[6]) 177 frw(" anim_curve_nodes=" as *u8); frn(st[7]) 178 frw(" anim_curves=" as *u8); frn(st[8]) 179 frw(" keytime_elems=" as *u8); frn(st[9]) 180 frw("\nRIG-SURVEY DONE\n" as *u8) 181 return 0 182}