Created
October 10, 2025 21:24
-
-
Save xDShot/3008aa58db1c9225e2bd771269974fd4 to your computer and use it in GitHub Desktop.
Gets bones move velocity
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import bpy | |
| from mathutils import Vector | |
| def get_bone_fcurves(armature_object, bone_name): | |
| """ | |
| Retrieves a list of F-curves associated with a specific bone in an armature. | |
| Args: | |
| armature_object (bpy.types.Object): The armature object. | |
| bone_name (str): The name of the bone. | |
| Returns: | |
| list: A list of bpy.types.FCurve objects associated with the bone. | |
| """ | |
| fcurves = [] | |
| if armature_object and armature_object.animation_data and armature_object.animation_data.action: | |
| # Construct the expected data_path prefix for the bone | |
| # bpy.utils.escape_identifier handles special characters in bone names | |
| bone_path_prefix = f'pose.bones["{bpy.utils.escape_identifier(bone_name)}"]' | |
| for fcurve in armature_object.animation_data.action.fcurves: | |
| if fcurve.data_path.startswith(bone_path_prefix): | |
| fcurves.append(fcurve) | |
| return fcurves | |
| def get_bone_location_fcurves(armature_object, bone_name): | |
| """ | |
| Finds and returns the F-Curves affecting the location of a specified bone | |
| in a given armature. | |
| Args: | |
| armature_object (bpy.types.Object): The armature object. | |
| bone_name (str): The name of the bone within the armature. | |
| Returns: | |
| list: A list containing the F-Curves for X, Y, and Z location, | |
| or None if not found. | |
| """ | |
| armature = armature_object | |
| if not armature.animation_data or not armature.animation_data.action: | |
| print(f"No active action found for armature '{armature_object_name}'.") | |
| return None | |
| action = armature.animation_data.action | |
| location_fcurves = [None, None, None] # For X, Y, Z location | |
| # The data path for a bone's location F-Curve looks like: | |
| # 'pose.bones["BoneName"].location' | |
| expected_data_path = f'pose.bones["{bpy.utils.escape_identifier(bone_name)}"].location' | |
| found_bone = False | |
| for fcurve in action.fcurves: | |
| if fcurve.data_path == expected_data_path: | |
| if fcurve.array_index == 0: # X Location | |
| found_bone = True | |
| location_fcurves[0] = fcurve | |
| elif fcurve.array_index == 1: # Y Location | |
| found_bone = True | |
| location_fcurves[1] = fcurve | |
| elif fcurve.array_index == 2: # Z Location | |
| found_bone = True | |
| location_fcurves[2] = fcurve | |
| if found_bone: | |
| return location_fcurves | |
| else: | |
| return None | |
| obj = bpy.data.objects['inverse kinematics skeleton'] | |
| act = bpy.data.objects['inverse kinematics skeleton'].animation_data.action | |
| act_name = act.name | |
| act_length = int(act.frame_range[1]) | |
| curves = act.fcurves | |
| move_helper_name = "Movement helper" # Replace with your bone name | |
| loc_fcurves = get_bone_location_fcurves(obj, move_helper_name) | |
| if loc_fcurves: | |
| print(f"F-Curves for bone '{move_helper_name}' location:") | |
| if loc_fcurves[0]: | |
| print(f" X Location F-Curve: {loc_fcurves[0]}") | |
| if loc_fcurves[1]: | |
| print(f" Y Location F-Curve: {loc_fcurves[1]}") | |
| if loc_fcurves[2]: | |
| print(f" Z Location F-Curve: {loc_fcurves[2]}") | |
| else: | |
| raise Exception(f"Could not find location F-Curves for bone '{move_helper_name}' in action '{act_name}'.") | |
| def parse_keyframe_points(axis_name, fcurve): | |
| print(f"Axis {axis_name}:") | |
| keypoints = [] | |
| for keyframe_point in fcurve.keyframe_points: | |
| frame = keyframe_point.co[0] # X-coordinate is the frame | |
| value = keyframe_point.co[1] # Y-coordinate is the value | |
| print(f"\tFrame: {frame}, Value: {value}") | |
| keypoints.append([frame, value]) | |
| print(keypoints) | |
| return keypoints | |
| keys = ( parse_keyframe_points("X", loc_fcurves[0]), parse_keyframe_points("Y", loc_fcurves[1]), parse_keyframe_points("Z", loc_fcurves[2]) ) | |
| def get_axis_velocity(axis_name, keyframe): | |
| frames_range = keyframe[1][0] - keyframe[0][0] | |
| start = keyframe[0][1] | |
| end = keyframe[1][1] | |
| velocity = start - end | |
| velocity = velocity / frames_range | |
| print(f"Axis {axis_name}, frames_range: {frames_range}, Points: {start:.3f} {end:.3f}, velocity: {velocity:.3f}") | |
| return velocity | |
| vel_x = get_axis_velocity("X", keys[0]) | |
| vel_y = get_axis_velocity("Y", keys[1]) | |
| vel_z = get_axis_velocity("Z", keys[2]) | |
| velocity = Vector((vel_x, vel_y, vel_z)) * act_length | |
| print(f"Frames range: {act_length}") | |
| print(velocity.x, velocity.y, velocity.z) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment