Last active
September 23, 2023 09:35
-
-
Save Tempate/88ecdb5caa22f67228a0594278bd17a5 to your computer and use it in GitHub Desktop.
This file contains 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
from math import * | |
import random | |
import bpy | |
N_FLAPS = 30 | |
N_SHAFTS = 42 | |
SHAFTS = ["Circle.{:03d}".format(i) for i in range(N_SHAFTS)] | |
FRAMES_PER_IMAGE = 10 | |
FRAMES_PER_PAUSE = 10 | |
# The percentage of shafts to rotate in each iteration | |
SHAFTS_TO_ROTATE_PER_IT = 0.3 | |
SHAFTS_TO_ROTATE_PER_IT_MIN = 0.1 | |
N_ROTATIONS = 1 | |
def clear_animation_data(): | |
for shaft in SHAFTS: | |
obj = bpy.data.objects[shaft] | |
obj.animation_data_clear() | |
def pin_to_current_frame(frame_count): | |
for shaft in SHAFTS: | |
obj = bpy.data.objects[shaft] | |
obj.keyframe_insert( | |
data_path="rotation_euler", | |
frame=frame_count, | |
index=1) | |
def rads(angle): | |
return angle * pi / 180 | |
clear_animation_data() | |
frame_count = 1 | |
pin_to_current_frame(frame_count) | |
for _ in range(N_ROTATIONS): | |
shafts_rotated = [] | |
while len(shafts_rotated) < N_SHAFTS: | |
# The shafts that have not been rotated yet | |
shafts_remaining = list(set(SHAFTS).difference(shafts_rotated)) | |
if len(shafts_remaining) <= N_SHAFTS * SHAFTS_TO_ROTATE_PER_IT_MIN: | |
# There are too few shafts remaining. Rotate them all. | |
n_shafts_to_rotate = len(shafts_remaining) | |
else: | |
# There are enough shafts remainig. Rotate a percentage of them. | |
n_shafts_to_rotate = ceil(len(shafts_remaining) * SHAFTS_TO_ROTATE_PER_IT) | |
shafts_to_rotate = random.sample(shafts_remaining, n_shafts_to_rotate) | |
# Rotate the selected shafts | |
for shaft in shafts_to_rotate: | |
obj = bpy.data.objects[shaft] | |
obj.rotation_euler.y -= rads(360 / Flaps) | |
shafts_rotated += shafts_to_rotate | |
frame_count += FRAMES_PER_DIGIT | |
pin_to_current_frame(frame_count) | |
frame_count += FRAMES_PER_PAUSE | |
pin_to_current_frame(frame_count) | |
# Make everything linear instead of bezier | |
for shaft in SHAFTS: | |
obj = bpy.data.objects[shaft] | |
fcurves = obj.animation_data.action.fcurves | |
for fcurve in fcurves: | |
for kf in fcurve.keyframe_points: | |
kf.interpolation = 'LINEAR' | |
# Adjust total frame count in this animation | |
bpy.data.scenes[0].frame_end = frame_count |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment