MetaFusion/resources/meta_anim/meta_body_anim.py

178 lines
8.6 KiB
Python
Raw Permalink Normal View History

2025-02-07 05:10:30 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
MetaHuman Body Animation
"""
import os # 导入os模块
import sys # 导入sys模块
import json # 导入json模块
import maya.cmds as cmds # 导入maya命令模块
def mgApplyBodyMocap():
objLs = cmds.ls(sl=1) # 获取当前选中的对象列表
namespace = ''
filePath = cmds.fileDialog2(fileMode=1, caption="Import Metahuman Body Animation") # 打开文件对话框以选择动画文件
if not filePath:
print("No file selected.") # 如果未选择文件,打印消息并返回
return
filePath = filePath[0] # 获取选择的文件路径
if len(objLs) > 0:
if ':' in objLs[0]:
namespace = objLs[0].split(':')[0] + ':' # 获取选中对象的命名空间
else:
namespace = ''
# 加载JSON文件
try:
with open(filePath, 'r') as f:
anim_keys = json.load(f) # 读取并加载json文件
except ValueError as e:
print("Error loading JSON file:", e) # 如果加载json文件出错打印错误消息并返回
return
# 要转换的控制器列表
controllers_to_convert = [
'hips_ctrl', 'spine_01_ctrl', 'spine_02_ctrl', 'spine_03_ctrl',
'neck_01_ctrl', 'neck_02_ctrl', 'head_ctrl', 'body_ctrl'
]
controllers_to_special_convert_l = [
'hand_l_ik_ctrl', 'foot_l_ik_ctrl'
]
controllers_to_special_convert_r = [
'hand_r_ik_ctrl', 'foot_r_ik_ctrl'
]
for dict_key in anim_keys:
keyframes_list = anim_keys[dict_key] # 获取当前控制器的关键帧列表
ctrl = dict_key
attr = 'translateY'
if '.' in ctrl:
ctrl_string_list = ctrl.split('.')
ctrl = ctrl_string_list[0]
if len(ctrl_string_list) > 2:
attr = ctrl_string_list[1].replace('Location', 'translate').replace('Rotation', 'rotate').replace('Scale', 'scale') + ctrl_string_list[-1].upper()
else:
attr = 'translate' + ctrl_string_list[-1].upper()
# 检查控制器名称末尾是否有数字
ctrl_name = ctrl
if ctrl_name.split('_')[-1].isdigit():
ctrl_name = ctrl_name.replace('_' + ctrl_name.split('_')[-1], '')
ctrl_name = namespace + ctrl_name # 添加命名空间到控制器名称
if cmds.objExists(ctrl_name): # 如果控制器对象存在
for key_num in range(0, len(keyframes_list)):
key_val = keyframes_list[key_num]
key_value = key_val[0]
key_time = key_val[1]
# 初始化变量以存储旋转值和平移值
rotateX = None
rotateY = None
rotateZ = None
translateX = None
translateY = None
translateZ = None
# 将关键帧值分配给适当的属性
if 'rotateX' in attr:
rotateX = key_value
elif 'rotateY' in attr:
rotateY = key_value
elif 'rotateZ' in attr:
rotateZ = key_value
elif 'translateX' in attr:
translateX = key_value
elif 'translateY' in attr:
translateY = key_value
elif 'translateZ' in attr:
translateZ = key_value
# 对指定控制器的旋转进行特殊处理
if ctrl_name in controllers_to_convert:
if rotateX is not None:
# 将X旋转转换为Z旋转并取负值
cmds.setKeyframe(ctrl_name, attribute='rotateZ', v=-rotateX, t=key_time)
if rotateZ is not None:
# 将Z旋转转换为X旋转并取负值
cmds.setKeyframe(ctrl_name, attribute='rotateX', v=-rotateZ, t=key_time)
if rotateY is not None:
cmds.setKeyframe(ctrl_name, attribute='rotateY', v=rotateY, t=key_time)
# 确保body_ctrl的平移数据被正确导入
if ctrl_name == 'body_ctrl':
if translateX is not None:
# 将X平移转换为Z平移并取负值
cmds.setKeyframe(ctrl_name, attribute='translateZ', v=-translateX, t=key_time)
if translateY is not None:
# 将Y平移转换为负值
cmds.setKeyframe(ctrl_name, attribute='translateY', v=-translateY, t=key_time)
if translateZ is not None:
# 将Z平移转换为X平移
cmds.setKeyframe(ctrl_name, attribute='translateX', v=translateZ, t=key_time)
elif ctrl_name in controllers_to_special_convert_l:
if rotateX is not None:
# 将X旋转转换为Z旋转并取负值
cmds.setKeyframe(ctrl_name, attribute='rotateZ', v=-rotateX, t=key_time)
if rotateZ is not None:
# 将Z旋转转换为X旋转并取负值
cmds.setKeyframe(ctrl_name, attribute='rotateX', v=-rotateZ, t=key_time)
if rotateY is not None:
# 将Y旋转转换为负值
cmds.setKeyframe(ctrl_name, attribute='rotateY', v=-rotateY, t=key_time)
if translateX is not None:
# 将X平移转换为Z平移并取负值
cmds.setKeyframe(ctrl_name, attribute='translateZ', v=-translateX, t=key_time)
if translateY is not None:
# 将Y平移转换为负值
cmds.setKeyframe(ctrl_name, attribute='translateY', v=-translateY, t=key_time)
if translateZ is not None:
# 将Z平移转换为X平移不取负值
cmds.setKeyframe(ctrl_name, attribute='translateX', v=translateZ, t=key_time)
elif ctrl_name in controllers_to_special_convert_r:
if rotateX is not None:
# 将X旋转转换为Z旋转并取负值
cmds.setKeyframe(ctrl_name, attribute='rotateZ', v=-rotateX, t=key_time)
if rotateZ is not None:
# 将Z旋转转换为X旋转并取负值
cmds.setKeyframe(ctrl_name, attribute='rotateX', v=-rotateZ, t=key_time)
if rotateY is not None:
# 将Y旋转转换为负值
cmds.setKeyframe(ctrl_name, attribute='rotateY', v=-rotateY, t=key_time)
if translateX is not None:
# 将X平移转换为Z平移不取负值
cmds.setKeyframe(ctrl_name, attribute='translateZ', v=translateX, t=key_time)
if translateY is not None:
# 将Y平移导入但不转换
cmds.setKeyframe(ctrl_name, attribute='translateY', v=translateY, t=key_time)
if translateZ is not None:
# 将Z平移转换为X平移并取负值
cmds.setKeyframe(ctrl_name, attribute='translateX', v=-translateZ, t=key_time)
else:
# 对于其他控制器将Y旋转和Z旋转取负值
if rotateY is not None:
cmds.setKeyframe(ctrl_name, attribute='rotateY', v=-rotateY, t=key_time)
if rotateZ is not None:
cmds.setKeyframe(ctrl_name, attribute='rotateZ', v=-rotateZ, t=key_time)
if rotateX is not None:
cmds.setKeyframe(ctrl_name, attribute='rotateX', v=rotateX, t=key_time)
# 对于非指定控制器,直接设置平移数据
if translateX is not None:
cmds.setKeyframe(ctrl_name, attribute='translateX', v=translateX, t=key_time)
if translateY is not None:
cmds.setKeyframe(ctrl_name, attribute='translateY', v=translateY, t=key_time)
if translateZ is not None:
cmds.setKeyframe(ctrl_name, attribute='translateZ', v=translateZ, t=key_time)
else:
print('Skipping ' + ctrl_name + ' as no such object exists.') # 如果对象不存在,打印跳过消息
print('Applied Animation to Body Rig.') # 打印应用动画完成消息
mgApplyBodyMocap() # 调用导入函数