# -*- coding: utf-8 -*- 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() # 调用导入函数