Browse Source

Implement sound volume animations

pull/40/head
Adam Johnson 9 years ago
parent
commit
e2d18c898a
  1. 27
      korman/exporter/animation.py
  2. 37
      korman/properties/modifiers/sound.py

27
korman/exporter/animation.py

@ -47,6 +47,8 @@ class AnimationConverter:
# things that aren't the typical position, rotation, scale animations. # things that aren't the typical position, rotation, scale animations.
applicators = [] applicators = []
applicators.append(self._convert_transform_animation(bo.name, fcurves, bo.matrix_basis)) applicators.append(self._convert_transform_animation(bo.name, fcurves, bo.matrix_basis))
if bo.plasma_modifiers.soundemit.enabled:
applicators.extend(self._convert_sound_volume_animation(bo.name, fcurves, bo.plasma_modifiers.soundemit))
# Check to make sure we have some valid animation applicators before proceeding. # Check to make sure we have some valid animation applicators before proceeding.
if not any(applicators): if not any(applicators):
@ -83,6 +85,31 @@ class AnimationConverter:
atcanim.easeOutMax = 1.0 atcanim.easeOutMax = 1.0
atcanim.easeOutLength = 1.0 atcanim.easeOutLength = 1.0
def _convert_sound_volume_animation(self, name, fcurves, soundemit):
def convert_volume(value):
if value == 0.0:
return 0.0
else:
return math.log10(value) * 20.0
for sound in soundemit.sounds:
path = "{}.volume".format(sound.path_from_id())
fcurve = next((i for i in fcurves if i.data_path == path and i.keyframe_points), None)
if fcurve is None:
continue
for i in soundemit.get_sound_indices(sound=sound):
applicator = plSoundVolumeApplicator()
applicator.channelName = name
applicator.index = i
# libHSPlasma assumes a channel is not shared among applicators...
# so yes, we must convert the same animation data again and again.
channel = plScalarControllerChannel()
channel.controller = self.make_scalar_leaf_controller(fcurve, convert=convert_volume)
applicator.channel = channel
yield applicator
def _convert_transform_animation(self, name, fcurves, xform): def _convert_transform_animation(self, name, fcurves, xform):
pos = self.make_pos_controller(fcurves, xform) pos = self.make_pos_controller(fcurves, xform)
rot = self.make_rot_controller(fcurves, xform) rot = self.make_rot_controller(fcurves, xform)

37
korman/properties/modifiers/sound.py

@ -131,7 +131,7 @@ class PlasmaSound(bpy.types.PropertyGroup):
volume = IntProperty(name="Volume", volume = IntProperty(name="Volume",
description="Volume to play the sound", description="Volume to play the sound",
min=0, max=100, default=100, min=0, max=100, default=100,
options=set(), options={"ANIMATABLE"},
subtype="PERCENTAGE") subtype="PERCENTAGE")
fade_in = PointerProperty(type=PlasmaSfxFade, options=set()) fade_in = PointerProperty(type=PlasmaSfxFade, options=set())
@ -344,20 +344,35 @@ class PlasmaSoundEmitter(PlasmaModifierProperties):
if i.sound_data and i.enabled: if i.sound_data and i.enabled:
i.convert_sound(exporter, so, winaud) i.convert_sound(exporter, so, winaud)
def get_sound_indices(self, name): def get_sound_indices(self, name=None, sound=None):
"""Returns the index of the given sound in the plWin32Sound. This is needed because stereo """Returns the index of the given sound in the plWin32Sound. This is needed because stereo
3D sounds export as two mono sound objects -- wheeeeee""" 3D sounds export as two mono sound objects -- wheeeeee"""
assert name or sound
idx = 0 idx = 0
for i in self.sounds:
if i.name == name: if name is None:
yield idx for i in self.sounds:
if i.is_3d_stereo: if i == sound:
yield idx + 1 yield idx
break if i.is_3d_stereo:
yield idx + 1
break
else:
idx += 2 if i.is_3d_stereo else 1
else: else:
idx += 2 if i.is_3d_stereo else 1 raise LookupError(sound)
else:
raise ValueError(name) if sound is None:
for i in self.sounds:
if i.name == name:
yield idx
if i.is_3d_stereo:
yield idx + 1
break
else:
idx += 2 if i.is_3d_stereo else 1
else:
raise ValueError(name)
@classmethod @classmethod
def register(cls): def register(cls):

Loading…
Cancel
Save