What?
Here’s the whole updated addon, replace it with the old one and import it on both Armatures in the test blend.
bl_info = {
'name': 'SBA simple binary animation format',
'author': 'vida_vida',
'version': (0, 1, 1),
'blender': (2, 6, 2),
'location': 'File > Import > SBA animation (.sba)',
'description': 'SBA animation importer',
'category': 'Import'}
import bpy
import mathutils
from math import radians
from bpy.props import *
from bpy_extras.io_utils import ExportHelper, ImportHelper
import os
import struct
def importSBA(filepath):
name = os.path.basename(filepath)
realpath = os.path.realpath(os.path.expanduser(filepath))
fileobject = open(realpath, 'rb')
armobj = bpy.context.scene.objects.active
if not armobj or armobj.type != 'ARMATURE':
raise Exception('An Armature must be selected!')
return
pose = armobj.pose
armobj.animation_data_create()
actionname = bpy.path.display_name_from_filepath(filepath)
action = bpy.data.actions.new(name = actionname)
armobj.animation_data.action = action
fileobject = open(filepath, 'rb')
# <char*4> signature (version)
datachunk = fileobject.read(4)
if datachunk != b'TSB0':
fileobject.close()
raise Exception('This file is not a valid SBA file!')
return
# <int*3> zero
datachunk = fileobject.seek(12, 1)
# <int> number of bones
bonecount = struct.unpack('<I', fileobject.read(4))[0]
# <int> number of frames
framecount = struct.unpack('<I', fileobject.read(4))[0]
# <int> unused
fileobject.seek(4, 1)
# <int> unused
datachunk = fileobject.seek(4, 1)
# We need to assign new pos/rot/scale key to each bone, for each frame.
# we read each animation matrix for each (pose)bone, for each frame from the SBA file and store the data in lists
frames = [] # 'frames' list contains 'frame' sublists itself, the amount of them are equal to the amount of frames, they in turn contain the matrices for each bone
for i in range(framecount):
frames.append([])
#for each frame:
# for each bone:
# # <float*16> transform matrix
# this will make the sublists have all the transform matrices as their members
for frameindex in range(len(frames)):
for x in sorted(pose.bones.keys()):
rawlist = struct.unpack('<16f', fileobject.read(64))
amat = mathutils.Matrix.Rotation(radians(90),4,'X') * mathutils.Matrix(( # since 2.62 a list of rows is supplied, not list of columns
(rawlist[0], rawlist[4], rawlist[8], rawlist[12]),
(rawlist[1], rawlist[5], rawlist[9], rawlist[13]),
(rawlist[2], rawlist[6], rawlist[10],rawlist[14]),
(rawlist[3], rawlist[7], rawlist[11],rawlist[15])))
frames[frameindex].append(amat)
# finally, add keys based on the data from the huge 'frames' nested list
bonenumber = 0
# for each frame:
for frame in range(framecount):
# for each pose bone: add a key
for bonename in sorted(pose.bones.keys()):
if pose.bones[bonename].parent:
matrix = frames[frame][bonenumber]
# Calculate bone vector(armature space).
pos = matrix.to_translation()
axis = matrix.to_3x3().col[1]
head = pos
tail = pos + axis
vector = tail - head
# Calculate rotation from parent bone vector to bone vector
parent_vector = pose.bones[bonename].parent.vector
rotation = parent_vector.rotation_difference(vector)
# Calculate bone head(armature space)
head = head
# Assign rotation and location to your Posebone.matrix.
pose.bones[bonename].location = head
pose.bones[bonename].rotation_quaternion = rotation
else:
pose.bones[bonename].matrix = frames[frame][bonenumber]
# create the 'keys' for the Action from the poses
pose.bones[bonename].keyframe_insert('location', frame = frame+1)
pose.bones[bonename].keyframe_insert('rotation_quaternion', frame = frame+1)
pose.bones[bonename].keyframe_insert('scale', frame = frame+1)
bonenumber += 1
bonenumber = 0
# GUI part
class ImportSBA(bpy.types.Operator, ImportHelper):
bl_idname= 'import_scene.sba'
bl_description = 'Import SBA animation (.sba)'
bl_label = 'Import SBA'
bl_options = {'INTERNAL'} # not write steps to Blender History (Ctr+Z)
filename_ext = '.sba'
filter_glob = StringProperty(default = '*.sba', options={'HIDDEN'})
filepath = StringProperty(name = 'File Path', description = 'Filepath used for importing the SBA file', maxlen = 1024, default = '')
def execute(self, context):
importSBA(self.properties.filepath)
return {'FINISHED'}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
def menu_func(self, context):
self.layout.operator(ImportSBA.bl_idname, text = 'SBA animation (.sba)')
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_import.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_import.remove(menu_func)
if __name__ == '__main__':
register()
Not right.