From 027b076aa30dc3926943ad8e4308ebfdb50c985f Mon Sep 17 00:00:00 2001 From: Simon Anderson Date: Tue, 17 Oct 2023 14:14:28 +1300 Subject: [PATCH] Added AnimLayers module to mGear Core - added more layer functionality --- release/scripts/mgear/core/animLayers.py | 69 ++++++++++++++++++- .../game_tools_fbx/anim_clip_widgets.py | 6 +- .../mgear/shifter/game_tools_fbx/utils.py | 29 ++------ 3 files changed, 76 insertions(+), 28 deletions(-) diff --git a/release/scripts/mgear/core/animLayers.py b/release/scripts/mgear/core/animLayers.py index ebf550ce..1bc628e2 100644 --- a/release/scripts/mgear/core/animLayers.py +++ b/release/scripts/mgear/core/animLayers.py @@ -2,6 +2,12 @@ import maya.api.OpenMaya as om def animation_layer_exists(layer_name): + """Checks ig animation layer exists. + + :param str layer_name: Name of the layer that will be checked. + :return: True if the animation layer exists + :rtype: bool + """ is_anim_layer = False if not layer_name: @@ -15,6 +21,12 @@ def animation_layer_exists(layer_name): def base_animation_layer_name(): + """Finds the name of the base animation layer, as this base layer might not + be named the default "BaseAnimation". + + :return: name of the base animation layer. + :rtype: str + """ if animation_layer_exists("BaseAnimation"): return "BaseAnimation" @@ -28,6 +40,12 @@ def base_animation_layer_name(): def find_anim_layer_base_nodes(): + """Finds the animation base layer, as this base layer might not + be named the default "BaseAnimation". + + :return: list of Maya Objects. + :rtype: list[om.MObject] + """ anim_layer_nodes = [] # Create an iterator to iterate through all nodes @@ -56,8 +74,8 @@ def find_anim_layer_base_nodes(): def all_anim_layers_ordered(include_base_animation=True): """Recursive function that returns all available animation layers within current scene. - Returns: - list[str]: list of animation layers. + :return: list of animation layers. + :rtype: list[str] """ def _add_node_recursive(layer_node): @@ -78,4 +96,49 @@ def _add_node_recursive(layer_node): if "BaseAnimation" in all_layers: all_layers.remove("BaseAnimation") - return all_layers \ No newline at end of file + return all_layers + + +def get_layer_weights(): + """ + Gets all the animation layer weights. + + :return: Dictionary with the name of the animation layer, followed by the weight. + :rtype: dict + """ + anim_layer_weights = {} + anim_layers = all_anim_layers_ordered(include_base_animation=False) + + for anim_layer in anim_layers: + anim_layer_weights[anim_layer] = cmds.animLayer(anim_layer, query=True, weight=True) + + return anim_layer_weights + + +def set_layer_weights(anim_layer_weights): + """ + Sets the animation layer weights. + + :param dict anim_layer_weights: Dictionary containing all the animation layer names, and the weights to be set for each anim layer name. + """ + for name, weight in anim_layer_weights.items(): + cmds.animLayer(name, edit=True, weight=weight) + + +def set_layer_weight(name, value=1.0, toggle_other_off=False, include_base=False): + """ + Set a specific AnimationLayers weight. + + :param str name: Name of the animation layer to have its weight modified. + :param float value: weight of the animation layer + :param bool toggle_other_off: Turn all other layers off + :param bool include_base: include the base animation layer when toggling off layers. + """ + anim_layers = all_anim_layers_ordered(include_base_animation=include_base) + + if toggle_other_off: + for layer_name in anim_layers: + cmds.animLayer(layer_name, edit=True, weight=0.0) + + cmds.animLayer(name, edit=True, weight=value) + \ No newline at end of file diff --git a/release/scripts/mgear/shifter/game_tools_fbx/anim_clip_widgets.py b/release/scripts/mgear/shifter/game_tools_fbx/anim_clip_widgets.py index e1e1b7e2..d2eaa96b 100644 --- a/release/scripts/mgear/shifter/game_tools_fbx/anim_clip_widgets.py +++ b/release/scripts/mgear/shifter/game_tools_fbx/anim_clip_widgets.py @@ -4,7 +4,7 @@ from mgear.vendor.Qt import QtWidgets, QtCore, QtGui -from mgear.core import pyqt, utils as coreUtils +from mgear.core import pyqt, utils as coreUtils, animLayers from mgear.shifter.game_tools_fbx import fbx_export_node, utils @@ -253,7 +253,7 @@ def refresh(self): with pyqt.block_signals(self._anim_layer_combo): self._anim_layer_combo.clear() # TODO: Maybe we should filter display layers that are set with override mode? - anim_layers = utils.all_anim_layers_ordered() + anim_layers = animLayers.all_anim_layers_ordered() self._anim_layer_combo.addItems(["None"] + anim_layers) self._anim_layer_combo.setCurrentText( anim_clip_data.get("anim_layer", "None") @@ -398,7 +398,7 @@ def showPopup(self): self.clear() - anim_layers = utils.all_anim_layers_ordered() + anim_layers = animLayers.all_anim_layers_ordered() self.addItems(["None"] + anim_layers) self.setCurrentText(currentText) diff --git a/release/scripts/mgear/shifter/game_tools_fbx/utils.py b/release/scripts/mgear/shifter/game_tools_fbx/utils.py index 8476ae3d..0262146c 100644 --- a/release/scripts/mgear/shifter/game_tools_fbx/utils.py +++ b/release/scripts/mgear/shifter/game_tools_fbx/utils.py @@ -304,13 +304,13 @@ def export_animation_clip(config_data, clip_data): clip_data: Information about the clip to be exported. """ # Clip Data - start_frame = clip_data.get("startFrame", + start_frame = clip_data.get("start_frame", cmds.playbackOptions(query=True, minTime=True)) - end_frame = clip_data.get("endFrame", + end_frame = clip_data.get("end_frame", cmds.playbackOptions(query=True, maxTime=True)) title = clip_data.get("title", "") - frame_rate = clip_data.get("frameRate", coreUtils.get_frame_rate()) - anim_layer = clip_data.get("animLayer", "") + frame_rate = clip_data.get("geo_root", coreUtils.get_frame_rate()) + anim_layer = clip_data.get("anim_layer", "") # Config Data root_joint = config_data.get("joint_root", "") @@ -351,26 +351,12 @@ def export_animation_clip(config_data, clip_data): original_end_frame = cmds.playbackOptions(query=True, maxTime=True) temp_mesh = None temp_skin_cluster = None - original_anim_layer_weights = None + original_anim_layer_weights = animLayers.get_layer_weights() try: # set anim layer to enable if animLayers.animation_layer_exists(anim_layer): - to_activate = None - to_deactivate = [] - anim_layers = animLayers.all_anim_layers_ordered(include_base_animation=False) - original_anim_layer_weights = { - anim_layer: cmds.animLayer(anim_layer, query=True, weight=True) - for anim_layer in anim_layers - } - for found_anim_layer in anim_layers: - if found_anim_layer != anim_layer: - to_deactivate.append(found_anim_layer) - else: - to_activate = found_anim_layer - for anim_layer_to_deactivate in to_deactivate: - cmds.animLayer(anim_layer_to_deactivate, edit=True, weight=0.0) - cmds.animLayer(to_activate, edit=True, weight=1.0) + animLayers.set_layer_weight(anim_layer, toggle_other_off=True) # disable viewport mel.eval("paneLayout -e -manage false $gMainPane") @@ -463,8 +449,7 @@ def export_animation_clip(config_data, clip_data): finally: # setup again original anim layer weights if anim_layer and original_anim_layer_weights: - for name, weight in original_anim_layer_weights.items(): - cmds.animLayer(name, edit=True, weight=weight) + animLayers.set_layer_weights(original_anim_layer_weights) if temp_skin_cluster and cmds.objExists(temp_skin_cluster): cmds.delete(temp_skin_cluster)