Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.74 KB | None | 0 0
  1. from bpy import data
  2.  
  3. INTERPOLATION = "LINEAR"
  4.  
  5. location_kf_counter = 0
  6. rotation_kf_counter = 0
  7. rotation_kf_inc_counter = 0
  8. rotation_kf_fix_counter = 0
  9. rotation_kf_nofix_counter = 0
  10.  
  11. for action in data.actions:
  12. print("AGR_INTERP: Processing action {}".format(action.name))
  13. rot_fcurve_lists = {}
  14. for fcurve in action.fcurves:
  15. fc_split = fcurve.data_path.rsplit(".", 1)
  16. fc_name = (action.name + "." + fc_split[0]) if len(fc_split) == 2 else action.name
  17. fc_type = fc_split[-1]
  18. # Interpolate location normally
  19. if fc_type == "location":
  20. for kf in fcurve.keyframe_points:
  21. if kf.interpolation != INTERPOLATION:
  22. kf.interpolation = INTERPOLATION
  23. location_kf_counter += 1
  24. # Collect all 4 quaternion components to fix them, group them by their "names" extracted from data_path
  25. elif fc_type == "rotation_quaternion":
  26. if not fc_name in rot_fcurve_lists:
  27. rot_fcurve_lists[fc_name] = []
  28. rot_fcurve_lists[fc_name].append(fcurve)
  29. for rot_fcurves_name, rot_fcurves in rot_fcurve_lists.items():
  30. print("AGR_INTERP: Processing rotation for {}".format(rot_fcurves_name))
  31. rot_fcurves_n = len(rot_fcurves)
  32. if rot_fcurves_n > 0:
  33. if rot_fcurves_n == 4:
  34. # Ensure rotation interpolates correctly
  35. # Loop through each keyframe of the first component
  36. other_fcurves = rot_fcurves[1:]
  37. kf_is = [0 for fcurve in other_fcurves] # is = indexes
  38. prev_components = [None for fcurve in rot_fcurves]
  39. incomplete_kfs = set()
  40. for comp0 in rot_fcurves[0].keyframe_points:
  41. if comp0.interpolation != INTERPOLATION:
  42. comp0.interpolation = INTERPOLATION
  43. rotation_kf_counter += 1
  44. # Ensure other components exist at this frame (referred to as frame is "complete" from now on)
  45. comp0_x = comp0.co[0]
  46. components = [comp0]
  47. incomplete = False
  48. # Loop through the rest of the components
  49. for i, fcurve in enumerate(other_fcurves):
  50. kf_i = kf_is[i]
  51. kf_i_max = len(fcurve.keyframe_points) - 1
  52. if kf_i > kf_i_max:
  53. continue
  54. kf = fcurve.keyframe_points[kf_i]
  55. if kf.interpolation != INTERPOLATION:
  56. kf.interpolation = INTERPOLATION
  57. rotation_kf_counter += 1
  58. kf_x = kf.co[0]
  59. # Initially populate component with the previous frame's value
  60. # to keep track of most recent values even when there are incomplete frames
  61. components.append(prev_components[len(components)-1])
  62. # If the component's current keyframe's frame is less than the current frame
  63. # go forward the keyframes to see if we can find a matching one
  64. while kf_i <= kf_i_max and kf_x < comp0_x:
  65. # If we need to skip a keyframe, it must be incomplete
  66. incomplete_kfs.add(str(kf_x))
  67. components[-1] = kf
  68. if kf.interpolation != INTERPOLATION:
  69. kf.interpolation = INTERPOLATION
  70. rotation_kf_counter += 1
  71. kf_i += 1
  72. kf = fcurve.keyframe_points[kf_i]
  73. kf_x = kf.co[0]
  74. if kf_x == comp0_x:
  75. # Found a valid keyframe of the component at this frame
  76. components[-1] = kf
  77. # Move index by one since we found a frame for the current index's keyframe
  78. kf_i += 1
  79. else:
  80. # kf_x > comp_x or reached the end of fcurve kf_points
  81. # The current keyframe is incomplete, try next one
  82. # Index is not moved, since this keyframe can be part of another complete frame
  83. incomplete = True
  84. incomplete_kfs.add(str(comp0_x))
  85. # Update index to avoid checking keyframes more than once
  86. kf_is[i] = kf_i
  87. if prev_components.count(None) == 0:
  88. # Compare to previous frame, determine if negated is closer
  89. curr_y_values = [component.co[1] for component in components]
  90. neg_y_values = [-component.co[1] for component in components]
  91. last_y_values = [component.co[1] for component in prev_components]
  92. curr_diff = sum([abs(last_y_values[i] - curr_y_values[i]) for i in range(len(curr_y_values))])
  93. neg_diff = sum([abs(last_y_values[i] - neg_y_values[i]) for i in range(len(neg_y_values))])
  94. if neg_diff < curr_diff:
  95. if incomplete:
  96. print("AGR_INTERP: Cannot negate keyframe at {}: quaternion is incomplete".format(components[0].co.x))
  97. rotation_kf_nofix_counter += 1
  98. else:
  99. # VVV Too much spam VVV
  100. # print("AGR_INTERP: Negating keyframe at {}".format(components[0].co.x))
  101. for i, component in enumerate(components):
  102. component.co[1] = neg_y_values[i]
  103. rotation_kf_fix_counter += 1
  104. # Store components of the frame for future comparisons
  105. prev_components = components
  106. if len(incomplete_kfs) > 0:
  107. print("AGR_INTERP: Skipped incomplete keyframes at {}".format(", ".join(incomplete_kfs)))
  108. rotation_kf_inc_counter += len(incomplete_kfs)
  109. else:
  110. print("AGR_INTERP: Invalid amount of rotation quaternion components: {}".format(rot_fcurves_n))
  111.  
  112. print("AGR_INTERP: Interpolated {} location keyframes".format(location_kf_counter))
  113. print("AGR_INTERP: Interpolated {} rotation keyframes".format(rotation_kf_counter))
  114. print("AGR_INTERP: Found {} incomplete quaternions".format(rotation_kf_inc_counter))
  115. print("AGR_INTERP: Negated {} rotation keyframes".format(rotation_kf_fix_counter))
  116. print("AGR_INTERP: Could not negate {} rotation keyframes due to incomplete quaternions".format(rotation_kf_nofix_counter))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement