def writeHalfVB(self, f): attrs = MdlPntAttrs(self) npnt = self.numPnt() for ipnt in xrange(npnt): pnt = self.pnts[ipnt] pos = self.ppos[ipnt] nrm = attrs.getNrm(pnt) onrm = xcore.encodeOcta(nrm) tex = attrs.getTex(pnt) clr = attrs.getClr(pnt) alf = attrs.getAlf(pnt) f.write(xcore.packTupF32(pos)) pk = struct.pack("HHHHHHHH", xcore.f16(onrm[0]), xcore.f16(onrm[1]), xcore.f16(tex[0]), xcore.f16(1.0 - tex[1]), xcore.f16(clr[0]), xcore.f16(clr[1]), xcore.f16(clr[2]), xcore.f16(alf)) f.write(pk) if self.skinData: skn = self.skinData[ipnt] nwgt = len(skn) jidx = [skn[nwgt - 1][0] for i in xrange(4)] jwgt = [0.0 for i in xrange(4)] scl = 0xFFFF for i in xrange(nwgt): iw = skn[i] jidx[i] = iw[0] jwgt[i] = max(min(int(round(iw[1] * scl)), scl), 0) f.write(struct.pack("HHHH", jwgt[0], jwgt[1], jwgt[2], jwgt[3])) f.write(struct.pack("BBBB", jidx[0], jidx[1], jidx[2], jidx[3]))
def packXMtx(mtx): return xcore.packTupF32(mtx.transposed().asTuple()[:3 * 4])
def writeData(self, bw, top): f = bw.getFile() npnt = self.numPnt() ntri = self.ntris nmtl = self.numMtl() nbat = self.numBat() nskn = self.numSkin() nskl = self.numSkel() ntex = len(self.tlst) if nskn > 0: bw.align(0x10) skinInfoTop = bw.getPos() bw.patch(self.patchPos + 0x10, skinInfoTop - top) # -> skin f.write(struct.pack("I", 0)) # +00 -> mdl spheres f.write(struct.pack("I", 0)) # +04 -> bat spheres f.write(struct.pack("I", 0)) # +08 -> names f.write(struct.pack("I", 0)) # +0C -> skel map f.write(struct.pack("I", 0)) # +10 -> bat jlst data f.write(struct.pack("I", len(self.jsphBats) / 4)) # +14 -> num bat items (spheres/jlst data) bw.align(0x10) bw.patch(skinInfoTop, bw.getPos() - top) f.write(xcore.packTupF32(self.jsphMdl)) bw.patch(skinInfoTop + 4, bw.getPos() - top) f.write(xcore.packTupF32(self.jsphBats)) bw.patch(skinInfoTop + 8, bw.getPos() - top) for skinName in self.skinNames: nameId = self.skinNameToStrId[skinName] self.writeStrId32(bw, nameId) bw.patch(skinInfoTop + 0xC, bw.getPos() - top) for skinName in self.skinNames: skelIdx = -1 if self.skelNodes: if skinName in self.skelNodeMap: skelIdx = self.skelNodeMap[skinName] bw.writeI32(skelIdx) bw.patch(skinInfoTop + 0x10, bw.getPos() - top) for bat in self.bats: for ijnt in bat.ijnts: f.write(struct.pack("i", ijnt)) if nskl > 0: bw.align(0x10) bw.patch(self.patchPos + 0x14, bw.getPos() - top) # -> skel mdata = "" for skelNode in self.skelNodes: mdata += packXMtx(skelNode.lmtx) for skelNode in self.skelNodes: mdata += packXMtx(skelNode.imtx) f.write(mdata) for skelNode in self.skelNodes: self.writeStrId32(bw, skelNode.nameId) for skelNode in self.skelNodes: f.write(struct.pack("i", skelNode.parentId)) if nmtl > 0: bw.align(0x10) mtlsTop = bw.getPos() bw.patch(self.patchPos + 4, mtlsTop - top) # -> mtls for mtl in self.mtls: mtl.write(bw) if self.swpMtls and len(self.swpMtls) > 0: for mtl in self.swpMtls: mtl.write(bw) for imtl, mtl in enumerate(self.mtls): if mtl.swapIds: bw.patch( mtlsTop + (imtl * Material.SIZE) + Material.SWAPS_OFFS, bw.getPos() - top) bw.writeI32(len(mtl.swapIds)) for swpId in mtl.swapIds: bw.writeI32(swpId) if ntex > 0: bw.align(0x10) bw.patch(self.patchPos + 8, bw.getPos() - top) # -> texs for tex in self.tlst: self.writeStrId32(bw, tex[0]) # nameId self.writeStrId32(bw, tex[1]) # pathId bw.writeU32(0) # work[0] bw.writeU32(0) # work[1] if nbat > 0: bw.align(0x10) bw.patch(self.patchPos + 0xC, bw.getPos() - top) # -> bats for bat in self.bats: # bbox[] f.write(xcore.packTupF32(bat.bboxMin + bat.bboxMax)) for bat in self.bats: # info[] bat.write(bw) bw.align(0x10) bw.patch(self.patchPos + 0, bw.getPos() - top) # -> pnts if self.useHalf: self.writeHalfVB(f) else: self.writeShortVB(f) if self.nidx16 > 0: bw.align(0x10) bw.patch(self.patchPos + 0x18, bw.getPos() - top) # -> idx16 for bat in self.bats: if bat.isIdx16(): grp = self.grps[bat.igrp] for i in xrange(bat.npol): ipol = grp.ipols[bat.org + i] pol = self.pols[ipol] for idx in pol.ibuf: rel = (idx - bat.minIdx) & 0xFFFF f.write(struct.pack("H", rel)) if self.nidx32 > 0: bw.align(0x10) bw.patch(self.patchPos + 0x1C, bw.getPos() - top) # -> idx32 for bat in self.bats: if not bat.isIdx16(): grp = self.grps[bat.igrp] for i in xrange(bat.npol): ipol = grp.ipols[bat.org + i] pol = self.pols[ipol] for idx in pol.ibuf: rel = idx - bat.minIdx f.write(struct.pack("I", rel))