Example #1
0
    def get_head_length(self):
        jnt_head = self.get_head_jnt()
        if not jnt_head:
            self.warning("Can't resolve head length!")

        ref_tm = jnt_head.getMatrix(worldSpace=True)

        geometries = libRigging.get_affected_geometries(jnt_head)

        # Resolve the top of the head location
        bot = pymel.datatypes.Point(ref_tm.translate)
        #dir = pymel.datatypes.Point(1,0,0) * ref_tm
        #dir = dir.normal()
        # This is strange but not pointing to the world sometime don't work...
        # TODO: FIX ME
        dir = pymel.datatypes.Point(0,1,0)

        top = libRigging.ray_cast_farthest(bot, dir, geometries)
        if not top:
            self.warning("Can't resolve head top location using raycasts using {0} {1}!".format(
                bot, dir
            ))
            return None

        return libPymel.distance_between_vectors(bot, top)
Example #2
0
    def get_head_length(self, jnt_head):
        """
        Resolve a head influence height using raycasts.
        This is in the Rig class to increase performance using the caching mechanism.
        :param jnt_head: The head influence to mesure.
        :return: A float representing the head length. None if unsuccessful.
        """
        ref_tm = jnt_head.getMatrix(worldSpace=True)

        geometries = libHistory.get_affected_shapes(jnt_head)

        # Resolve the top of the head location
        bot = pymel.datatypes.Point(ref_tm.translate)
        # dir = pymel.datatypes.Point(1,0,0) * ref_tm
        # dir = dir.normal()
        # This is strange but not pointing to the world sometime don't work...
        # TODO: FIX ME
        dir = pymel.datatypes.Point(0, 1, 0)

        top = libRigging.ray_cast_farthest(bot, dir, geometries)
        if not top:
            self.warning("Can't resolve head top location using raycasts using {0} {1}!".format(
                bot, dir
            ))
            return None

        return libPymel.distance_between_vectors(bot, top)
Example #3
0
    def get_head_length(self):
        jnt_head = self.get_head_jnt()
        if not jnt_head:
            self.warning("Can't resolve head length!")

        ref_tm = jnt_head.getMatrix(worldSpace=True)

        geometries = libRigging.get_affected_geometries(jnt_head)

        # Resolve the top of the head location
        bot = pymel.datatypes.Point(ref_tm.translate)
        #dir = pymel.datatypes.Point(1,0,0) * ref_tm
        #dir = dir.normal()
        # This is strange but not pointing to the world sometime don't work...
        # TODO: FIX ME
        dir = pymel.datatypes.Point(0, 1, 0)

        top = libRigging.ray_cast_farthest(bot, dir, geometries)
        if not top:
            self.warning(
                "Can't resolve head top location using raycasts using {0} {1}!"
                .format(bot, dir))
            return None

        return libPymel.distance_between_vectors(bot, top)
Example #4
0
    def get_face_macro_ctrls_distance_from_head(self,
                                                multiplier=1.2,
                                                default_distance=20):
        """
        :return: The recommended distance between the head middle and the face macro ctrls.
        """
        jnt_head = self.get_head_jnt()
        if not jnt_head:
            log.warning(
                "Cannot resolve desired macro avars distance from head. Using default ({0})"
                .format(default_distance))
            return default_distance

        ref_tm = jnt_head.getMatrix(worldSpace=True)

        geometries = libRigging.get_affected_geometries(jnt_head)

        # Resolve the top of the head location
        pos = pymel.datatypes.Point(ref_tm.translate)
        #dir = pymel.datatypes.Point(1,0,0) * ref_tm
        #dir = dir.normal()
        # This is strange but not pointing to the world sometime don't work...
        # TODO: FIX ME
        dir = pymel.datatypes.Point(0, 1, 0)

        top = next(iter(libRigging.ray_cast(pos, dir, geometries)), None)
        if not top:
            raise Exception("Can't resolve head top location using raycasts!")

        # Resolve the middle of the head
        middle = ((top - pos) * 0.5) + pos

        # Find the front of the face
        # For now, one raycase seem fine.
        #dir = pymel.datatypes.Point(0,-1,0) * ref_tm
        #dir.normalize()
        dir = pymel.datatypes.Point(0, 0, 1)
        front = next(iter(libRigging.ray_cast(middle, dir, geometries)), None)
        if not front:
            raise Exception(
                "Can't resolve head front location using raycasts!")

        distance = libPymel.distance_between_vectors(middle, front)

        return distance * multiplier
Example #5
0
def calibrate_attr_using_translation(attr, ref, step_size=0.1, epsilon=0.01, default=1.0):
    """
    Return the distance that @ref move when @attr is changed.
    This is used to automatically tweak the ctrl sensibility so the doritos have a more pleasant feel.
    Note that to compensate non-linear movement, a small value (@step_size) is used.
    """
    attr.set(0)
    pos_s = ref.getTranslation(space='world')
    attr.set(-step_size)  # HACK: Jaw only deforme the face in the negative direction...
    pos_e = ref.getTranslation(space='world')
    attr.set(0)
    distance = libPymel.distance_between_vectors(pos_s, pos_e) / step_size

    if distance > epsilon:
        return distance
    else:
        log.warning("Can't detect sensibility for {0}".format(attr))
        return default
Example #6
0
def get_average_pos_between_nodes(jnts):
    nearest_jnt = None
    nearest_distance = None

    middle = get_average_pos_between_vectors(jnts)
    middle.y = 0
    middle.z = 0

    for jnt in jnts:
        jnt_pos = jnt.getTranslation(space='world')
        jnt_pos.y = 0
        jnt_pos.z = 0
        distance = libPymel.distance_between_vectors(jnt_pos, middle)
        #distance = abs(.x)
        if nearest_jnt is None or distance < nearest_distance:
            nearest_jnt = jnt
            nearest_distance = distance
    return nearest_jnt
Example #7
0
def get_closest_point_on_shapes(meshes, pos):
    """
    Return informations about the closest intersection between a point and multiple mesh polygons.
    :param mesh: A pymel.nodetypes.Mesh to analyze.
    :param pos: A pymel.datatypes.Vector world-space position.
    :return: A 4-sized tuple containing:
    - A pymel.nodetypes.Mesh instance representing the closest mesh.
    - A pymel.datatypes.Vector representing the closest intersection between the mesh and the provided position.
    - The u coordinate of the resulting position.
    - The v coordinate of the resulting position.
    If nothing is found, a 4-sized tuple containing all None values are returned.
    """
    shortest_delta = None
    return_val = (None, None, None, None)
    for mesh in meshes:
        closest_pos, closest_u, closest_v = get_closest_point_on_shape(mesh, pos)
        delta = libPymel.distance_between_vectors(pos, closest_pos)
        if shortest_delta is None or delta < shortest_delta:
            shortest_delta = delta
            return_val = (mesh, closest_pos, closest_u, closest_v)
    return return_val
Example #8
0
    def get_face_macro_ctrls_distance_from_head(self, multiplier=1.2, default_distance=20):
        """
        :return: The recommended distance between the head middle and the face macro ctrls.
        """
        jnt_head = self.get_head_jnt()
        if not jnt_head:
            log.warning("Cannot resolve desired macro avars distance from head. Using default ({0})".format(default_distance))
            return default_distance

        ref_tm = jnt_head.getMatrix(worldSpace=True)

        geometries = libRigging.get_affected_geometries(jnt_head)

        # Resolve the top of the head location
        pos = pymel.datatypes.Point(ref_tm.translate)
        #dir = pymel.datatypes.Point(1,0,0) * ref_tm
        #dir = dir.normal()
        # This is strange but not pointing to the world sometime don't work...
        # TODO: FIX ME
        dir = pymel.datatypes.Point(0,1,0)

        top = next(iter(libRigging.ray_cast(pos, dir, geometries)), None)
        if not top:
            raise Exception("Can't resolve head top location using raycasts!")

        # Resolve the middle of the head
        middle = ((top-pos) * 0.5) + pos

        # Find the front of the face
        # For now, one raycase seem fine.
        #dir = pymel.datatypes.Point(0,-1,0) * ref_tm
        #dir.normalize()
        dir = pymel.datatypes.Point(0,0,1)
        front = next(iter(libRigging.ray_cast(middle, dir, geometries)), None)
        if not front:
            raise Exception("Can't resolve head front location using raycasts!")

        distance = libPymel.distance_between_vectors(middle, front)

        return distance * multiplier
Example #9
0
def ray_cast_farthest(pos, *args, **kwargs):
    results = ray_cast(pos, *args, **kwargs)
    results = sorted(results, key=lambda x: libPymel.distance_between_vectors(pos, x))
    return next(iter(reversed(results)), None)