diff --git a/intern/pro_tools.py b/intern/pro_tools.py index e7ddb35..d35f934 100644 --- a/intern/pro_tools.py +++ b/intern/pro_tools.py @@ -1,8 +1,13 @@ +import pprint + import bpy import ptsl from ptsl import PTSL_pb2 as pt +from .geom_utils import compute_relative_vector, room_norm_vector, speaker_active_time_range + + def mixdown_speaker(speaker: bpy.types.Object, scene: bpy.types.Scene) -> str: return "" @@ -50,9 +55,54 @@ def insert_audio(speaker: bpy.types.Object, scene: bpy.types.Scene, def apply_pan_automation(speaker: bpy.types.Object, scene: bpy.types.Scene, - track_id: str, client: ptsl.Client): + track_id: str, room_size: float, client: ptsl.Client): - pass + CId_SetTrackControlBreakpoints = 150 + # fps = scene.render.fps + speaker_interval = speaker_active_time_range(speaker) + assert scene.camera, "Scene does not have a camera" + + values: list[tuple[dict, dict, dict]] = [] + + for frame in range(speaker_interval.start_frame, + speaker_interval.end_frame + 1): + scene.frame_set(frame) + relative_vector = compute_relative_vector(camera=scene.camera, + target=speaker) + norm_vec = room_norm_vector(relative_vector, + room_size=room_size) + + time_struct = {'location': str(frame), 'time_type': 'TLType_Frames'} + + x_pos = {'time': time_struct, 'value': round(norm_vec.x, 4)} + y_pos = {'time': time_struct, 'value': round(norm_vec.y, 4)} + z_pos = {'time': time_struct, 'value': round(norm_vec.z, 4)} + + values.append((x_pos, y_pos, z_pos)) + + for i, control in enumerate(['PCParameter_X', 'PCParameter_Y', + 'PCParameter_Z']): + + params ={ + 'track_id': track_id, + 'control_id': { + 'section': 'TSId_MainOut', + 'control_type': 'TCType_Pan', + 'pan': { + 'pan_space': 'PSpace_3dCart3layer', + 'parameter': control, + 'channel': 'SChannel_Mono' + }, + }, + 'breakpoints': [v[i] for v in values] + + } + + print("Sending parameter changes:") + pprint.pprint(params) + + client.run_command(CId_SetTrackControlBreakpoints, params) + def send_to_pro_tools(speakers: list[bpy.types.Object], @@ -67,7 +117,8 @@ def send_to_pro_tools(speakers: list[bpy.types.Object], for speaker in speakers: new_track_id = create_track(speaker, client) insert_audio(speaker, scene, new_track_id, client) - apply_pan_automation(speaker, scene, new_track_id, client) + apply_pan_automation(speaker, scene, new_track_id, room_size, + client) client.close() return True diff --git a/operator_protools_export.py b/operator_protools_export.py index 3f74688..bc47438 100644 --- a/operator_protools_export.py +++ b/operator_protools_export.py @@ -23,7 +23,8 @@ class SendToProTools(bpy.types.Operator): @classmethod def poll(cls, context): return len(filter_speakers(context.selected_objects)) > 0 and \ - bpy.app.online_access + bpy.app.online_access and \ + context.scene.camera is not None def invoke(self, context, event): wm = context.window_manager