Skip to content

Instantly share code, notes, and snippets.

@MoePus
Created February 15, 2018 14:04
Show Gist options
  • Save MoePus/430b50645c6ec79243b308d7d59c2ac1 to your computer and use it in GitHub Desktop.
Save MoePus/430b50645c6ec79243b308d7d59c2ac1 to your computer and use it in GitHub Desktop.
Combine vmd data with physics data from mmdbridge
import os,sys,io
from struct import pack,unpack
if len(sys.argv) < 3:
print("not enough input file")
exit(-1)
class VMD:
def __init__(self,fn):
self.fp = open(fn,"rb")
def checkHeader(self):
self.fp.seek(0,0)
magic = self.fp.read(30)
return magic.startswith(b'Vocaloid Motion Data 0002')
def intkeyframe(self,mark):
self.fp.seek(0x32, 0)
keyframeNums = unpack("<I",self.fp.read(4))[0]
#self.keyframes = [{"bone":"","frame":0,"pos":0,"mark":mark}] * keyframeNums
self.keyframes = []
for i in range(keyframeNums):
pos = self.fp.tell()
self.fp.read(15)
index = unpack("<I",self.fp.read(4))[0]
self.fp.seek(0x5c, 1)
self.keyframes.append([index,pos,mark])
self.meshFramePos = self.fp.tell()
fileA = sys.argv[1]
fileB = sys.argv[2]
fileC = sys.argv[1][:-4] + "_com.vmd"
vmdA = VMD(fileA)
if not vmdA.checkHeader():
print("illegal vmd file a")
exit(-2)
vmdA.intkeyframe(1)
vmdB = VMD(fileB)
if not vmdB.checkHeader():
print("illegal vmd file b")
exit(-2)
vmdB.intkeyframe(2)
with open(fileC,"wb") as cfp:
combined = list(sorted(vmdA.keyframes + vmdB.keyframes,key=lambda x:x[0]))
vmdA.fp.seek(0,0)
cfp.write(vmdA.fp.read(0x32))
cfp.write(pack("<I",len(combined)))
progress = 0
task = float(len(combined))
for keyframe in combined:
progress+=1
fp = None
if keyframe[2] == 1:
fp = vmdA.fp
else:
fp = vmdB.fp
fp.seek(keyframe[1],0)
cfp.write(fp.read(0x6F))
if progress % 65536:
print("\r%.2f"%(progress/task*100),end="")
vmdA.fp.seek(vmdA.meshFramePos, 0)
cfp.write(vmdA.fp.read())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment