def lerp(current, target, factor=1.0, falloff=False): """ Blend between two values\\ current <to> target """ if falloff: factor = utils.proportional(factor, mode=falloff) def blend(current, target): if (Is.digit(current) and Is.digit(target)) and not \ (Is.string(current) or Is.string(target)): return (current * (1.0 - factor) + target * factor) elif (factor): return target else: return current if (Is.matrix(current) and Is.matrix(target)): return current.lerp(target, factor) elif (Is.iterable(current) and Is.iterable(target)) and not \ (Is.string(current) or Is.string(target)): # Assume the items are tuple/list/set. Not dict (but dicts can merge) merge = list() for (s, o) in zip(current, target): merge.append(blend(s, o)) return merge else: return blend(current, target)
def execute(self, context): fac = (self.factor / 100) selected = Get.selected(context, mirror=True) for src in selected: base = pose.base[repr(src)] reset = pose.reset[repr(src)] if src.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'): euler = 'XYZ' else: euler = src.rotation_mode if Is.matrix(reset): matrix = utils.lerp(base, reset, fac) matrix = utils.matrix_to_transforms(matrix, euler=euler) else: location = base.to_translation() rotation_quaternion = base.to_quaternion() axis = base.to_quaternion().to_axis_angle() rotation_axis_angle = (*axis[0], axis[1]) rotation_euler = base.to_euler(euler) scale = base.to_scale() matrix = type( 'matrix and transforms', (), dict( location=utils.lerp(location, reset.location, fac), rotation_quaternion=utils.lerp( rotation_quaternion, reset.rotation_quaternion, fac), rotation_axis_angle=utils.lerp( rotation_axis_angle, reset.rotation_axis_angle, fac), rotation_euler=utils.lerp(rotation_euler, reset.rotation_euler, fac), scale=utils.lerp(scale, reset.scale, fac), )) if 'loc' in self.mode: src.location = matrix.location if 'rot' in self.mode: src.rotation_quaternion = matrix.rotation_quaternion src.rotation_axis_angle = matrix.rotation_axis_angle src.rotation_euler = matrix.rotation_euler if 'scale' in self.mode: src.scale = matrix.scale keyframe.keyingset(context, selected=selected) return {'FINISHED'}