178 lines
8.6 KiB
Python
178 lines
8.6 KiB
Python
#!/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() # 调用导入函数
|