Source code for artv2_components.aim_helper

# -*- coding: utf-8 -*-
"""
This module contains the class for handling aim mode on a component. Aim mode is a mode that can be toggled that
determines whether joints aim at their children when the joint mover controls are edited.
"""


import pymel.core as pm
import artv2_utilities.general_utilities as utils


[docs]class AimHelper: """ Class that handles toggling aim mode on a component. Aim mode is a mode that can be toggled that determines whether joints aim at their children when the joint mover controls are moved or rotated. This setup is done using the joint mover markup tool and setting the attributes it adds concerning aim mode. The relevant attributes are: * Can Aim * Aim Joint * Aim Axis * Invert Aim Axis * Up Axis * Maintain Offset .. glossary:: Can Aim Whether this joint should aim at another joint when aim mode is turned on. Aim Joint Which joint this joint should aim at when aim mode is turned on. (This is ignored if Can Aim is False) Aim Axis Which axis represents the aim axis. (This is ignored if Can Aim is False) Invert Aim Axis If the aim axis should be inverted. (If your aim axis is set to X, but needs to be -X, this would be True) (This is ignored if Can Aim is False) Up Axis The axis of the joint that is closes to the world up axis. (This is ignored if Can Aim is False) Maintain Offset This will probably not ever need to be used, but in the case of some special circumstance, this will create the aim constraint while maintaining offsets. (This is ignored if Can Aim is False) """ def __init__(self, metanode): """ :param metanode: This is the network node from a component, like a leg or torso. It contains all of the metadata """ self._metanode = pm.PyNode(metanode) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
[docs] def toggle_aim_mode(self): """ Toggles aim mode on a component. Aim mode determines whether joints aim at their children when the joint mover controls are moved or rotated. Which joints and their settings are setup using the joint mover markup tool. """ if self._metanode.isAiming.get(): self.tear_down_aim_mode() else: self.setup_aim_mode()
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
[docs] def setup_aim_mode(self): """ Sets up the aim constraints on the joint mover controls that have aim mode setup. """ aim_data = self._gather_aim_data() constraints = [] for mover_grp in aim_data: aim_target, aim_axis, up_axis, invert, offset = aim_data.get(mover_grp) constraint = pm.aimConstraint(aim_target, mover_grp, aimVector=self._convert_axis(aim_axis, invert), upVector=self._convert_axis(up_axis), worldUpType="objectrotation", worldUpObject=aim_target, worldUpVector=self._convert_axis(pm.upAxis(q=True, axis=True).upper()), maintainOffset=offset) constraints.append(constraint) utils.set_attribute(self._metanode, "isAiming", True) for constraint in constraints: constraint.addAttr("metanode", at="message") self._metanode.aimModeConstraints.connect(constraint.metanode)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
[docs] def tear_down_aim_mode(self): """ Removes the aim constraints from the joint mover controls. """ constraints = self._metanode.aimModeConstraints.connections() for each in constraints: pm.delete(each) utils.set_attribute(self._metanode, "isAiming", False)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # def _gather_aim_data(self): offset_movers = self._metanode.offset_movers.connections() component_name = self._metanode.componentName.get() aim_data = {} for mover in offset_movers: mover_grp = mover.getParent() jnt = mover.connected_joint.connections()[0] if jnt.hasAttr("canAim"): can_aim = jnt.canAim.get() if can_aim: maintain_offsets = jnt.maintainOffset.get() aim_axis = jnt.aimAxis.get(asString=True) invert_aim = jnt.invertAimAxis.get() up_axis = jnt.upAxis.get(asString=True) aim_joint = jnt.aimJoint.get(asString=True) aim_joint_node = pm.PyNode("{0}_{1}".format(component_name, aim_joint)) aim_target_connections = aim_joint_node.attr("message").connections() for connection in aim_target_connections: if type(connection) == pm.nodetypes.Transform: aim_target = connection aim_data[mover_grp] = [aim_target, aim_axis, up_axis, invert_aim, maintain_offsets] return aim_data # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
[docs] def _convert_axis(self, axis, inverted=False): """ Converts a simple string axis value (like X) to a float tuple (like (1.0, 0.0, 0.0)) :return: A tuple containing three floats defining the given axis """ if axis == "X": if inverted: return [-1.0, 0.0, 0.0] else: return [1.0, 0.0, 0.0] if axis == "Y": if inverted: return [0.0, -1.0, 0.0] else: return [0.0, 1.0, 0.0] if axis == "Z": if inverted: return [0.0, 0.0, -1.0] else: return [0.0, 0.0, 1.0]