diff --git a/NinjaModel.py b/NinjaModel.py index 4a714e6..9f3aa58 100644 --- a/NinjaModel.py +++ b/NinjaModel.py @@ -439,7 +439,7 @@ class NinjaModel: user_function_interpolation = p[3] & 0x80 anim = NinjaMotion() - anim.setName("anim_%03d" % len(self.anim_list)) + anim.setName(len(self.anim_list)) anim.setFrames(frame_count) anim.setSkeleton(self.bones) self.anim_list.append(anim) @@ -602,6 +602,19 @@ class NinjaModel: for bone in self.bones: bone.createDmfEntry(f) + #Write Animations + pos = f.tell() + count = len(self.anim_list) + f.seek(0x68, 0) + f.write(struct.pack('II', pos, count)) + f.seek(0, 2) + + for anim in self.anim_list: + anim.generateDmfEntry(f) + + for anim in self.anim_list: + anim.writeDmfAnimation(f) + f.close() return None diff --git a/NinjaMotion.py b/NinjaMotion.py index fb618e0..5a4832a 100644 --- a/NinjaMotion.py +++ b/NinjaMotion.py @@ -30,15 +30,18 @@ from Mat4 import Mat4 class NinjaMotion: def __init__(self): + self.index = -1 self.name = ""; self.skeleton = [] self.frames = 0 self.fps = 30 self.keyFrames = [] + self.count = 0 return None - def setName(self, name): - self.name = name + def setName(self, index): + self.index = index + self.name = "anim_%03d" % index return None def setSkeleton(self, bones): @@ -102,15 +105,92 @@ class NinjaMotion: keyFrames[lastIndex]['rot'] = bone.getRotation() for keyFrame in keyFrames: - + + self.count += 1 if 'rot' not in keyFrame.keys(): continue mat4 = Mat4() mat4.rotate(keyFrame['rot']) keyFrame['quat'] = mat4.toQuat() - print(keyFrame['quat']) return None + + def generateDmfEntry(self, file): + + name = self.name + while len(name) < 0x20: + name += '\0' + bytes = name.encode() + file.write(bytes) + + bytes = struct.pack('hh', self.index, self.fps) + file.write(bytes) + self.pos = file.tell() + file.write(struct.pack('I', 0)) + file.write(struct.pack('I', self.count)) + + duration = (self.frames - 1) / self.fps + file.write(struct.pack('f', duration)) + + return None + + def writeDmfAnimation(self, file): + + offset = file.tell() + file.seek(self.pos, 0) + file.write(struct.pack('I', offset)) + file.seek(0, 2) + + for i in range(len(self.keyFrames)): + + keyFrames = self.keyFrames[i] + for keyFrame in keyFrames: + skipFlags = 0 + + if 'pos' in keyFrame.keys(): + skipFlags |= 0x01 + + if 'rot' in keyFrame.keys(): + skipFlags |= 0x02 + + if 'scl' in keyFrame.keys(): + skipFlags |= 0x04 + + file.write(struct.pack('hh', i, skipFlags)) + file.write(struct.pack('f', keyFrame['frame'] / self.fps)) + + if 'pos' in keyFrame.keys(): + file.write(struct.pack('f', keyFrame['pos'][0])) + file.write(struct.pack('f', keyFrame['pos'][1])) + file.write(struct.pack('f', keyFrame['pos'][2])) + else: + file.write(struct.pack('f', 0)) + file.write(struct.pack('f', 0)) + file.write(struct.pack('f', 0)) + + if 'quat' in keyFrame.keys(): + file.write(struct.pack('f', keyFrame['quat'][0])) + file.write(struct.pack('f', keyFrame['quat'][1])) + file.write(struct.pack('f', keyFrame['quat'][2])) + file.write(struct.pack('f', keyFrame['quat'][3])) + else: + file.write(struct.pack('f', 0)) + file.write(struct.pack('f', 0)) + file.write(struct.pack('f', 0)) + file.write(struct.pack('f', 1)) + + if 'scl' in keyFrame.keys(): + file.write(struct.pack('f', keyFrame['scl'][0])) + file.write(struct.pack('f', keyFrame['scl'][1])) + file.write(struct.pack('f', keyFrame['scl'][2])) + else: + file.write(struct.pack('f', 1)) + file.write(struct.pack('f', 1)) + file.write(struct.pack('f', 1)) + + print(keyFrame) + + return None