cabasus / main.py
arcan3
added mods
247dc37
raw
history blame
6.93 kB
import csv
import bpy
from mathutils import *
import sys
argv = sys.argv
argv = argv[argv.index("--") + 1:] # get all args after "--"
D = bpy.data
C = bpy.context
def copy_armature_animation(
source_armature_name,
destination_armature_name,
start_frame_source,
end_frame_source,
start_frame_target,
):
# Get the source and destination armature objects
source_armature = bpy.data.objects[source_armature_name]
destination_armature = bpy.data.objects[destination_armature_name]
# Copy the animation data from the source armature to the destination armature
#print(f"copying animation {start_frame_source}-{end_frame_source} to {start_frame_target} ")
for i, frame in enumerate(range(start_frame_source, end_frame_source + 1)):
bpy.context.scene.frame_set(frame)
# Set the location and rotation of the destination bone at the given frame
for bone in source_armature.pose.bones:
destination_bone = destination_armature.pose.bones.get(bone.name)
destination_bone.location = bone.location
destination_bone.rotation_quaternion = bone.rotation_quaternion
destination_bone.keyframe_insert(
data_path="location", frame=start_frame_target + i
)
destination_bone.keyframe_insert(
data_path="rotation_quaternion", frame=start_frame_target + i
)
# Copy the bone's animation data for each frame in the range
def adjust_armature_animation_timing(
armature_name, old_start, old_end, new_start, new_end
):
# Get the armature object by name
armature = bpy.data.objects[armature_name]
# Calculate the ratio between the old and new keyframe ranges
old_range = old_end - old_start
new_range = new_end - new_start
ratio = new_range / old_range
#print(f"Adjsuting timming from {old_start}-{old_end} to {new_start}-{new_end} with ratio: {ratio}")
# Iterate through all the armature bones and modify their animation keyframes
for fcurve in armature.animation_data.action.fcurves:
if fcurve.array_index < 4:
for keyframe in fcurve.keyframe_points:
# Adjust the keyframe position based on the ratio
if keyframe.co.x in range (old_start, old_end):
#print(f"keyframe move from {keyframe.co.x}")
keyframe.co.x = (keyframe.co.x - old_start) * ratio + new_start
#print(f"to {keyframe.co.x}")
else:
continue
def calculate_new_frame_range(frame_rate, timestamp, start_frame):
adjusted_end_frame = int(timestamp / 1000 * frame_rate + start_frame)
return adjusted_end_frame
def change_material_property(
material_name, node_name, new_value, start_frame, end_frame
):
value = bpy.data.materials[material_name].node_tree.nodes[node_name].outputs[0]
value.default_value = new_value
value.keyframe_insert(data_path="default_value", frame=start_frame+1)
value.keyframe_insert(data_path="default_value", frame=end_frame-1)
def set_cues_state(
global_state,
global_color,
c1_state,
c1_color,
c2_state,
c2_color,
c3_state,
c3_color,
c4_state,
c4_color,
start_frame,
end_frame,
):
# cue 1 noise
change_material_property(
"CUE_MAT_1", "Distortion", float(c1_state), start_frame, end_frame
)
# cue 2 noise
change_material_property(
"CUE_MAT_2", "Distortion", float(c2_state), start_frame, end_frame
)
# cue 3 noise
change_material_property(
"CUE_MAT_3", "Distortion", float(c3_state), start_frame, end_frame
)
# cue 4 noise
change_material_property(
"CUE_MAT_4", "Distortion", float(c4_state), start_frame, end_frame
)
# cue 1 color
change_material_property(
"CUE_MAT_1", "Color", float(c1_color), start_frame, end_frame
)
# cue 2 color
change_material_property(
"CUE_MAT_2", "Color", float(c2_color), start_frame, end_frame
)
# cue 3 color
change_material_property(
"CUE_MAT_3", "Color", float(c3_color), start_frame, end_frame
)
# cue 4 color
change_material_property(
"CUE_MAT_4", "Color", float(c4_color), start_frame, end_frame
)
# global cue on
change_material_property(
"GLOBAL_CUE_MAT", "MixFactor", float(global_state), start_frame, end_frame
)
# global cue color
change_material_property(
"GLOBAL_CUE_MAT", "Color", float(global_color), start_frame, end_frame
)
def animate_cycle(source_armature, target_armature, csv_file):
# Get the current scene
scene = bpy.context.scene
# Get the frame rate of the current scene
frame_rate = scene.render.fps / scene.render.fps_base
gait_to_keyframe_start = {0: 10, 1: 80, 2: 60, 3: 250}
gait_to_keyframe_end = {0: 49, 1: 99, 2: 74, 3: 310}
# column_names = ["Gait", "TS", "State", "Condition", "Shape1", "Shape2", "Shape3", "Shape4", "Color1", "Color2", "Color3", "Color4", "Danger1", "Danger2", "Danger3", "Danger4"]
previous_end_frame = 0
with open(csv_file, "r") as csvfile:
datareader = csv.reader(csvfile)
for i, row in enumerate(datareader):
if i == 0 or row[0] is None:
continue
copy_armature_animation(
source_armature,
target_armature,
gait_to_keyframe_start[int(row[0])],
gait_to_keyframe_end[int(row[0])],
previous_end_frame + 1,
)
adjusted_end_frame = calculate_new_frame_range(
frame_rate=frame_rate,
timestamp=int(float(row[1])),
start_frame=previous_end_frame + 1,
)
adjust_armature_animation_timing(
target_armature,
previous_end_frame + 1,
previous_end_frame + 1 + gait_to_keyframe_end[int(row[0])] - gait_to_keyframe_start[int(row[0])],
previous_end_frame + 1,
adjusted_end_frame,
)
set_cues_state(
row[3],
row[4],
row[8],
row[5],
row[9],
row[6],
row[10],
row[7],
row[11],
row[2],
previous_end_frame,
adjusted_end_frame,
)
#print(previous_end_frame, adjusted_end_frame)
previous_end_frame = adjusted_end_frame
print(f"Animated row {i}")
bpy.context.scene.frame_end = previous_end_frame
bpy.ops.render.render(animation=True)
print("Cycle_device:")
print(bpy.context.preferences.addons["cycles"].preferences.has_active_device())
animate_cycle("Deformation", "Deformation.001", str(argv[0]))