zaa transforms properly readjusted wrt omitted effectors/roots
This commit is contained in:
parent
6f2c1cf168
commit
c320310084
|
@ -44,12 +44,18 @@ def decompress_curves(input_file) -> Dict[int, Dict[int, List[ Dict[int,float]]]
|
||||||
with head.read_child() as mina:
|
with head.read_child() as mina:
|
||||||
|
|
||||||
for i in range(num_anims):
|
for i in range(num_anims):
|
||||||
mina.skip_bytes(8)
|
|
||||||
|
transBitFlags = mina.read_u32()
|
||||||
|
mina.skip_bytes(4)
|
||||||
|
|
||||||
anim_crc = mina.read_u32()
|
anim_crc = mina.read_u32()
|
||||||
anim_crcs.append(anim_crc)
|
anim_crcs.append(anim_crc)
|
||||||
|
|
||||||
anim_metadata[anim_crc] = {"num_frames" : mina.read_u16(), "num_bones" : mina.read_u16()}
|
anim_metadata[anim_crc] = {
|
||||||
|
"num_frames" : mina.read_u16(),
|
||||||
|
"num_bones" : mina.read_u16(),
|
||||||
|
"transBitFlags" : transBitFlags,
|
||||||
|
}
|
||||||
|
|
||||||
# Read TADA offsets and quantization parameters for each rot + loc component, for each bone, for each anim
|
# Read TADA offsets and quantization parameters for each rot + loc component, for each bone, for each anim
|
||||||
with head.read_child() as tnja:
|
with head.read_child() as tnja:
|
||||||
|
@ -57,10 +63,13 @@ def decompress_curves(input_file) -> Dict[int, Dict[int, List[ Dict[int,float]]]
|
||||||
for i, anim_crc in enumerate(anim_crcs):
|
for i, anim_crc in enumerate(anim_crcs):
|
||||||
|
|
||||||
bone_params = {}
|
bone_params = {}
|
||||||
|
bone_list = []
|
||||||
|
|
||||||
for _ in range(anim_metadata[anim_crc]["num_bones"]):
|
for _ in range(anim_metadata[anim_crc]["num_bones"]):
|
||||||
|
|
||||||
bone_crc = tnja.read_u32()
|
bone_crc = tnja.read_u32()
|
||||||
|
|
||||||
|
bone_list.append(bone_crc)
|
||||||
|
|
||||||
bone_params[bone_crc] = {
|
bone_params[bone_crc] = {
|
||||||
"rot_offsets" : [tnja.read_u32() for _ in range(4)], # Offsets into TADA for rotation
|
"rot_offsets" : [tnja.read_u32() for _ in range(4)], # Offsets into TADA for rotation
|
||||||
|
@ -69,6 +78,7 @@ def decompress_curves(input_file) -> Dict[int, Dict[int, List[ Dict[int,float]]]
|
||||||
}
|
}
|
||||||
|
|
||||||
anim_metadata[anim_crc]["bone_params"] = bone_params
|
anim_metadata[anim_crc]["bone_params"] = bone_params
|
||||||
|
anim_metadata[anim_crc]["bone_list"] = bone_list
|
||||||
|
|
||||||
# Decompress/dequantize frame data into discrete per-component curves
|
# Decompress/dequantize frame data into discrete per-component curves
|
||||||
with head.read_child() as tada:
|
with head.read_child() as tada:
|
||||||
|
@ -80,9 +90,11 @@ def decompress_curves(input_file) -> Dict[int, Dict[int, List[ Dict[int,float]]]
|
||||||
num_frames = anim_metadata[anim_crc]["num_frames"]
|
num_frames = anim_metadata[anim_crc]["num_frames"]
|
||||||
num_bones = anim_metadata[anim_crc]["num_bones"]
|
num_bones = anim_metadata[anim_crc]["num_bones"]
|
||||||
|
|
||||||
|
transBitFlags = anim_metadata[anim_crc]["transBitFlags"]
|
||||||
|
|
||||||
#print("\n\tAnim hash: {} Num frames: {} Num joints: {}".format(hex(anim_crc), num_frames, num_bones))
|
#print("\n\tAnim hash: {} Num frames: {} Num joints: {}".format(hex(anim_crc), num_frames, num_bones))
|
||||||
|
|
||||||
for bone_num, bone_crc in enumerate(anim_metadata[anim_crc]["bone_params"]):
|
for bone_num, bone_crc in enumerate(anim_metadata[anim_crc]["bone_list"]):
|
||||||
|
|
||||||
bone_curves = []
|
bone_curves = []
|
||||||
|
|
||||||
|
@ -96,9 +108,6 @@ def decompress_curves(input_file) -> Dict[int, Dict[int, List[ Dict[int,float]]]
|
||||||
|
|
||||||
for o, start_offset in enumerate(offsets_list):
|
for o, start_offset in enumerate(offsets_list):
|
||||||
|
|
||||||
# Skip to start of compressed data for component, as specified in TNJA
|
|
||||||
tada.skip_bytes(start_offset)
|
|
||||||
|
|
||||||
# Init curve dict
|
# Init curve dict
|
||||||
curve : Dict[int,float] = {}
|
curve : Dict[int,float] = {}
|
||||||
|
|
||||||
|
@ -115,6 +124,12 @@ def decompress_curves(input_file) -> Dict[int, Dict[int, List[ Dict[int,float]]]
|
||||||
# Translations have specific quantization parameters; biases for each component and
|
# Translations have specific quantization parameters; biases for each component and
|
||||||
# a single multiplier for all three
|
# a single multiplier for all three
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
if (0x00000001 << bone_num) & transBitFlags == 0:
|
||||||
|
bone_curves.append(None)
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
mult = qparams[-1]
|
mult = qparams[-1]
|
||||||
bias = qparams[o - 4]
|
bias = qparams[o - 4]
|
||||||
|
|
||||||
|
@ -122,6 +137,10 @@ def decompress_curves(input_file) -> Dict[int, Dict[int, List[ Dict[int,float]]]
|
||||||
|
|
||||||
#print("\n\t\t\tOffset {}: {} ({}, {} remaining)".format(o,start_offset, tada.get_current_pos(), tada.how_much_left(tada.get_current_pos())))
|
#print("\n\t\t\tOffset {}: {} ({}, {} remaining)".format(o,start_offset, tada.get_current_pos(), tada.how_much_left(tada.get_current_pos())))
|
||||||
|
|
||||||
|
# Skip to start of compressed data for component, as specified in TNJA
|
||||||
|
tada.skip_bytes(start_offset)
|
||||||
|
|
||||||
|
|
||||||
j = 0
|
j = 0
|
||||||
while (j < num_frames):
|
while (j < num_frames):
|
||||||
accumulator = bias + mult * tada.read_i16()
|
accumulator = bias + mult * tada.read_i16()
|
||||||
|
@ -232,17 +251,14 @@ def extract_and_apply_munged_anim(input_file_path):
|
||||||
bone_obj_parent = bone_obj.parent
|
bone_obj_parent = bone_obj.parent
|
||||||
|
|
||||||
bind_mat = bone_obj.matrix_local
|
bind_mat = bone_obj.matrix_local
|
||||||
stack_mat = Matrix.Identity(4)
|
|
||||||
|
|
||||||
|
|
||||||
while(True):
|
while(True):
|
||||||
if bone_obj_parent is None or bone_obj_parent.name in arma.data.bones:
|
if bone_obj_parent is None or bone_obj_parent.name in arma.data.bones:
|
||||||
break
|
break
|
||||||
bind_mat = bone_obj_parent.matrix_local @ bind_mat
|
bind_mat = bone_obj_parent.matrix_local @ bind_mat
|
||||||
stack_mat = bone_obj_parent.matrix_local @ stack_mat
|
|
||||||
bone_obj_parent = bone_obj_parent.parent
|
bone_obj_parent = bone_obj_parent.parent
|
||||||
|
|
||||||
bone_bind_poses[bone.name] = bind_mat.inverted() @ stack_mat
|
bone_bind_poses[bone.name] = bind_mat.inverted()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -254,8 +270,6 @@ def extract_and_apply_munged_anim(input_file_path):
|
||||||
else:
|
else:
|
||||||
anim_str = str(hex(anim_crc))
|
anim_str = str(hex(anim_crc))
|
||||||
|
|
||||||
#print("\nExtracting anim: " + anim_crc_str)
|
|
||||||
|
|
||||||
if anim_str in bpy.data.actions:
|
if anim_str in bpy.data.actions:
|
||||||
bpy.data.actions[anim_str].use_fake_user = False
|
bpy.data.actions[anim_str].use_fake_user = False
|
||||||
bpy.data.actions.remove(bpy.data.actions[anim_str])
|
bpy.data.actions.remove(bpy.data.actions[anim_str])
|
||||||
|
@ -268,8 +282,6 @@ def extract_and_apply_munged_anim(input_file_path):
|
||||||
for bone in arma.pose.bones:
|
for bone in arma.pose.bones:
|
||||||
bone_crc = to_crc(bone.name)
|
bone_crc = to_crc(bone.name)
|
||||||
|
|
||||||
#print("\tGetting curves for bone: " + bone.name)
|
|
||||||
|
|
||||||
if bone_crc not in animation:
|
if bone_crc not in animation:
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -280,6 +292,8 @@ def extract_and_apply_munged_anim(input_file_path):
|
||||||
bone_curves = animation[bone_crc]
|
bone_curves = animation[bone_crc]
|
||||||
num_frames = max(bone_curves[0])
|
num_frames = max(bone_curves[0])
|
||||||
|
|
||||||
|
has_translation = bone_curves[4] is not None
|
||||||
|
|
||||||
#print("\t\tNum frames: " + str(num_frames))
|
#print("\t\tNum frames: " + str(num_frames))
|
||||||
|
|
||||||
last_values = [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
last_values = [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||||
|
@ -322,14 +336,16 @@ def extract_and_apply_munged_anim(input_file_path):
|
||||||
fcurve_rot_y = action.fcurves.new(rot_data_path, index=2, action_group=bone.name)
|
fcurve_rot_y = action.fcurves.new(rot_data_path, index=2, action_group=bone.name)
|
||||||
fcurve_rot_z = action.fcurves.new(rot_data_path, index=3, action_group=bone.name)
|
fcurve_rot_z = action.fcurves.new(rot_data_path, index=3, action_group=bone.name)
|
||||||
|
|
||||||
fcurve_loc_x = action.fcurves.new(loc_data_path, index=0, action_group=bone.name)
|
if has_translation:
|
||||||
fcurve_loc_y = action.fcurves.new(loc_data_path, index=1, action_group=bone.name)
|
fcurve_loc_x = action.fcurves.new(loc_data_path, index=0, action_group=bone.name)
|
||||||
fcurve_loc_z = action.fcurves.new(loc_data_path, index=2, action_group=bone.name)
|
fcurve_loc_y = action.fcurves.new(loc_data_path, index=1, action_group=bone.name)
|
||||||
|
fcurve_loc_z = action.fcurves.new(loc_data_path, index=2, action_group=bone.name)
|
||||||
|
|
||||||
for frame in range(num_frames):
|
for frame in range(num_frames):
|
||||||
|
|
||||||
q = get_quat(frame)
|
q = get_quat(frame)
|
||||||
if q is not None:
|
if q is not None:
|
||||||
|
|
||||||
# Very bloated, but works for now
|
# Very bloated, but works for now
|
||||||
q = (bind_mat @ convert_rotation_space(q).to_matrix().to_4x4()).to_quaternion()
|
q = (bind_mat @ convert_rotation_space(q).to_matrix().to_4x4()).to_quaternion()
|
||||||
fcurve_rot_w.keyframe_points.insert(frame,q.w)
|
fcurve_rot_w.keyframe_points.insert(frame,q.w)
|
||||||
|
@ -337,13 +353,16 @@ def extract_and_apply_munged_anim(input_file_path):
|
||||||
fcurve_rot_y.keyframe_points.insert(frame,q.y)
|
fcurve_rot_y.keyframe_points.insert(frame,q.y)
|
||||||
fcurve_rot_z.keyframe_points.insert(frame,q.z)
|
fcurve_rot_z.keyframe_points.insert(frame,q.z)
|
||||||
|
|
||||||
t = get_vec(frame)
|
if has_translation:
|
||||||
if t is not None:
|
|
||||||
# ''
|
t = get_vec(frame)
|
||||||
t = (bind_mat @ Matrix.Translation(convert_vector_space(t))).translation
|
if t is not None:
|
||||||
fcurve_loc_x.keyframe_points.insert(frame,t.x)
|
|
||||||
fcurve_loc_y.keyframe_points.insert(frame,t.y)
|
t = (bind_mat @ Matrix.Translation(convert_vector_space(t))).translation
|
||||||
fcurve_loc_z.keyframe_points.insert(frame,t.z)
|
|
||||||
|
fcurve_loc_x.keyframe_points.insert(frame,t.x)
|
||||||
|
fcurve_loc_y.keyframe_points.insert(frame,t.y)
|
||||||
|
fcurve_loc_z.keyframe_points.insert(frame,t.z)
|
||||||
|
|
||||||
arma.animation_data.action = action
|
arma.animation_data.action = action
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue