Continuing modernization

This commit is contained in:
2025-11-05 20:28:52 -08:00
parent 8964bb030b
commit e3f4505d12
5 changed files with 59 additions and 36 deletions

View File

@@ -8,12 +8,13 @@ from numpy.linalg import norm
from mathutils import Vector, Quaternion
class FrameInterval:
def __init__(self, start_frame, end_frame):
self.start_frame = int(start_frame)
self.end_frame = int(end_frame)
def overlaps(self, other : 'FrameInterval') -> bool:
def overlaps(self, other: 'FrameInterval') -> bool:
return self.start_frame <= other.start_frame <= self.end_frame or \
other.start_frame <= self.start_frame <= other.end_frame
@@ -33,7 +34,7 @@ def compute_relative_vector(camera: bpy.types.Camera, target: bpy.types.Object):
# The camera's worldvector is norm to the horizon, we want a vector
# down the barrel.
camera_correction = Quaternion( ( sqrt(2.) / 2. , sqrt(2.) / 2. , 0. , 0.) )
camera_correction = Quaternion((sqrt(2.) / 2., sqrt(2.) / 2., 0., 0.))
relative_vector.rotate(camera_correction)
return relative_vector
@@ -51,11 +52,11 @@ def room_norm_vector(vec, room_size=1.) -> Vector:
The Pro Tools/Dolby Atmos workflow I am targeting uses "Room Centric" panner coordinates
("cartesian allocentric coordinates" in ADM speak) and this process seems to yield good
results.
I also experimented with using normalized camera frame coordinates from the
bpy_extras.object_utils.world_to_camera_view method and this gives very good results as
long as the object is on-screen; coordinates for objects off the screen are unusable.
In the future it would be worth exploring wether there's a way to produce ADM
coordinates that are "Screen-accurate" while the object is on-screen, but still gives
sensible results when the object is off-screen as well.
@@ -67,19 +68,20 @@ def room_norm_vector(vec, room_size=1.) -> Vector:
return vec / chebyshev
def closest_approach_to_camera(scene, speaker_object) -> (float, int):
def closest_approach_to_camera(scene, speaker_object) -> tuple[float, int]:
"""
The distance and frame number of `speaker_object`s closest point to
the scene's camera.
(Works for any object, not just speakers.)
"""
max_dist = sys.float_info.max
at_time = scene.frame_start
for frame in range(scene.frame_start, scene.frame_end + 1):
scene.frame_set(frame)
rel = speaker_object.matrix_world.to_translation() - scene.camera.matrix_world.to_translation()
dist = norm(rel)
rel = speaker_object.matrix_world.to_translation() - \
scene.camera.matrix_world.to_translation()
dist = float(norm(rel))
if dist < max_dist:
max_dist = dist