Is is possible to have two audio tracks playing but only being able to hear one based on just the rotation of the camera?
1 Answer
Drive the volume of the speaker.
There are three vectors of interest.
- The direction the camera is facing (-Z local axis) in global coordinates.
The direction the speaker is facing (-Z local axis) in global coordinates.
The line between the camera and speaker.
In test script below, the angle between the camera vector -Z axis direction and the line between the camera and speaker are converted to global coordinates and normalized. The dot product is used to drive the volume of the speaker.
Notice this doesn't look at whether the speaker is facing the camera, as this can also be achieved by setting the cone attributes of the speaker.
For convenience running the script will add drivers to Speaker.volume
. (Note will cause problems if speaker objects are sharing speaker data) for each speaker object in scene.
Will be verbose to the system console as there are print statements. Could look at the angle between vectors, or drive the mute property.
import bpy
from mathutils import Vector
context = bpy.context
scene = context.scene
def speaker_vol(spk, name):
cam = scene.camera
cmw = cam.matrix_world
cam_vec = (cmw * Vector((0, 0, -1)) - cmw.translation).normalized()
spk_obj = scene.objects.get(name)
if not spk_obj:
return 0
smw = spk_obj.matrix_world
spk_vec = (smw.translation - cmw.translation).normalized()
print(spk.name)
print(cam_vec)
print(spk_vec)
print(spk_vec.angle(cam_vec)) # angle in radians
print(spk_vec.dot(cam_vec))
return max(0, spk_vec.dot(cam_vec))
# register this driver
bpy.app.driver_namespace["speaker_vol"] = speaker_vol
# set up the drivers
speakers = [spk for spk in scene.objects if spk.type == 'SPEAKER']
for spk in speakers:
fcurve = spk.data.driver_add("volume")
driver = fcurve.driver
driver.use_self = True
driver.expression = 'speaker_vol(self, "%s")' % spk.name