MetaFusion/resources/meta_anim/meta_body_anim.py
2025-02-07 05:10:30 +08:00

178 lines
8.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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() # 调用导入函数