Update
This commit is contained in:
@ -276,10 +276,22 @@ class LeenkxExporter:
|
||||
if armature.animation_data:
|
||||
action = armature.animation_data.action
|
||||
if action:
|
||||
return [fcurve for fcurve in action.fcurves if fcurve.data_path.startswith(path)]
|
||||
fcurves = LeenkxExporter.get_action_fcurves(action, armature.animation_data)
|
||||
return [fcurve for fcurve in fcurves if fcurve.data_path.startswith(path)]
|
||||
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def get_action_fcurves(action: bpy.types.Action, anim_data: Optional[bpy.types.AnimData] = None) -> List[bpy.types.FCurve]:
|
||||
if bpy.app.version >= (5, 0, 0):
|
||||
if anim_data and anim_data.action_slot:
|
||||
from bpy_extras import anim_utils
|
||||
channelbag = anim_utils.action_ensure_channelbag_for_slot(action, anim_data.action_slot)
|
||||
return channelbag.fcurves if channelbag else []
|
||||
return []
|
||||
else:
|
||||
return action.fcurves
|
||||
|
||||
def export_bone(self, armature, bone: bpy.types.Bone, o, action: bpy.types.Action):
|
||||
rpdat = lnx.utils.get_rp()
|
||||
bobject_ref = self.bobject_bone_array.get(bone)
|
||||
@ -319,7 +331,7 @@ class LeenkxExporter:
|
||||
oanim['root_motion_rot'] = action.lnx_root_motion_rot
|
||||
|
||||
@staticmethod
|
||||
def calculate_anim_frame_range(action: bpy.types.Action) -> Tuple[int, int]:
|
||||
def calculate_anim_frame_range(action: bpy.types.Action, anim_data: Optional[bpy.types.AnimData] = None) -> Tuple[int, int]:
|
||||
"""Calculates the required frame range of the given action by
|
||||
also taking fcurve modifiers into account.
|
||||
|
||||
@ -330,14 +342,16 @@ class LeenkxExporter:
|
||||
start = frame_range[0]
|
||||
end = frame_range[1]
|
||||
|
||||
fcurves = LeenkxExporter.get_action_fcurves(action, anim_data)
|
||||
|
||||
# Blender 4.0+ compatibility: Handle zero-length frame ranges
|
||||
if start == end:
|
||||
start = 1
|
||||
end = 2
|
||||
|
||||
if action.fcurves:
|
||||
if fcurves:
|
||||
all_keyframes = []
|
||||
for fcurve in action.fcurves:
|
||||
for fcurve in fcurves:
|
||||
if fcurve.keyframe_points:
|
||||
for keyframe in fcurve.keyframe_points:
|
||||
all_keyframes.append(keyframe.co[0])
|
||||
@ -350,7 +364,7 @@ class LeenkxExporter:
|
||||
|
||||
# Take FCurve modifiers into account if they have a restricted
|
||||
# frame range
|
||||
for fcurve in action.fcurves:
|
||||
for fcurve in fcurves:
|
||||
for modifier in fcurve.modifiers:
|
||||
if not modifier.use_restricted_range:
|
||||
continue
|
||||
@ -404,7 +418,7 @@ class LeenkxExporter:
|
||||
o['object_actions'] = []
|
||||
o['object_actions'].append('action_' + action_name + ext)
|
||||
|
||||
frame_range = self.calculate_anim_frame_range(action)
|
||||
frame_range = self.calculate_anim_frame_range(action, bobject.animation_data)
|
||||
out_anim = {
|
||||
'begin': frame_range[0],
|
||||
'end': frame_range[1],
|
||||
@ -414,7 +428,8 @@ class LeenkxExporter:
|
||||
self.export_pose_markers(out_anim, action)
|
||||
|
||||
unresolved_data_paths = set()
|
||||
for fcurve in action.fcurves:
|
||||
fcurves = self.get_action_fcurves(action, bobject.animation_data)
|
||||
for fcurve in fcurves:
|
||||
data_path = fcurve.data_path
|
||||
|
||||
try:
|
||||
@ -535,7 +550,7 @@ class LeenkxExporter:
|
||||
fcurve_list = self.collect_bone_animation(armature, bone.name)
|
||||
|
||||
if fcurve_list and pose_bone:
|
||||
begin_frame, end_frame = self.calculate_anim_frame_range(action)
|
||||
begin_frame, end_frame = self.calculate_anim_frame_range(action, armature.animation_data)
|
||||
|
||||
out_track = {'target': "transform", 'frames': [], 'values': []}
|
||||
o['anim'] = {'tracks': [out_track]}
|
||||
@ -653,8 +668,8 @@ class LeenkxExporter:
|
||||
return fov
|
||||
return None
|
||||
|
||||
def write_bone_matrices(self, scene, action):
|
||||
begin_frame, end_frame = self.calculate_anim_frame_range(action)
|
||||
def write_bone_matrices(self, scene, action, anim_data: Optional[bpy.types.AnimData] = None):
|
||||
begin_frame, end_frame = self.calculate_anim_frame_range(action, anim_data)
|
||||
if len(self.bone_tracks) > 0:
|
||||
hidden_states = {}
|
||||
try:
|
||||
@ -807,7 +822,8 @@ class LeenkxExporter:
|
||||
# if (shapeKeys.animation_data):
|
||||
# action = shapeKeys.animation_data.action
|
||||
# if (action):
|
||||
# for fcurve in action.fcurves:
|
||||
# fcurves = self.get_action_fcurves(action, shapeKeys.animation_data)
|
||||
# for fcurve in fcurves:
|
||||
# if ((fcurve.data_path.startswith("key_blocks[")) and (fcurve.data_path.endswith("].value"))):
|
||||
# keyName = fcurve.data_path.strip("abcdehklopstuvy[]_.")
|
||||
# if ((keyName[0] == "\"") or (keyName[0] == "'")):
|
||||
@ -822,7 +838,8 @@ class LeenkxExporter:
|
||||
# if ((not action) and (node.animation_data)):
|
||||
# action = node.animation_data.action
|
||||
# if (action):
|
||||
# for fcurve in action.fcurves:
|
||||
# fcurves = self.get_action_fcurves(action, node.animation_data)
|
||||
# for fcurve in fcurves:
|
||||
# if ((fcurve.data_path.startswith("data.shape_keys.key_blocks[")) and (fcurve.data_path.endswith("].value"))):
|
||||
# keyName = fcurve.data_path.strip("abcdehklopstuvy[]_.")
|
||||
# if ((keyName[0] == "\"") or (keyName[0] == "'")):
|
||||
@ -1324,7 +1341,7 @@ class LeenkxExporter:
|
||||
_bake_hidden[_obj] = False
|
||||
_obj.hide_viewport = True
|
||||
|
||||
start, end = self.calculate_anim_frame_range(action)
|
||||
start, end = self.calculate_anim_frame_range(action, skelobj.animation_data)
|
||||
|
||||
bake_result = bpy.ops.nla.bake(
|
||||
frame_start=start,
|
||||
@ -1361,7 +1378,7 @@ class LeenkxExporter:
|
||||
boneo = {}
|
||||
self.export_bone(skelobj, bone, boneo, action)
|
||||
bones.append(boneo)
|
||||
self.write_bone_matrices(bpy.context.scene, action)
|
||||
self.write_bone_matrices(bpy.context.scene, action, skelobj.animation_data)
|
||||
if len(bones) > 0 and 'anim' in bones[0]:
|
||||
self.export_pose_markers(bones[0]['anim'], original_action)
|
||||
self.export_root_motion(bones[0]['anim'], original_action)
|
||||
|
||||
Reference in New Issue
Block a user