Browse Source

Implement Plasma Sound loading

This allows us to use Blender's Sound datablocks, despite it actively
opposing our attempts to do so. Meaning the artist can pack their sounds.
:)
pull/35/head
Adam Johnson 9 years ago
parent
commit
b29f4ebf75
  1. 1
      korman/operators/__init__.py
  2. 88
      korman/operators/op_sound.py
  3. 1
      korman/properties/modifiers/__init__.py
  4. 64
      korman/properties/modifiers/sound.py
  5. 1
      korman/ui/modifiers/__init__.py
  6. 60
      korman/ui/modifiers/sound.py

1
korman/operators/__init__.py

@ -17,6 +17,7 @@ from . import op_export as exporter
from . import op_lightmap as lightmap from . import op_lightmap as lightmap
from . import op_modifier as modifier from . import op_modifier as modifier
from . import op_nodes as nodes from . import op_nodes as nodes
from . import op_sound as sound
from . import op_texture as texture from . import op_texture as texture
from . import op_toolbox as toolbox from . import op_toolbox as toolbox
from . import op_world as world from . import op_world as world

88
korman/operators/op_sound.py

@ -0,0 +1,88 @@
# This file is part of Korman.
#
# Korman is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Korman is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
import bpy
from bpy.props import *
class SoundOperator:
@classmethod
def poll(cls, context):
return context.scene.render.engine == "PLASMA_GAME"
class PlasmaSoundOpenOperator(SoundOperator, bpy.types.Operator):
bl_idname = "sound.plasma_open"
bl_label = "Load Sound"
bl_options = {"INTERNAL"}
filter_glob = StringProperty(default="*.ogg;*.wav", options={"HIDDEN"})
filepath = StringProperty(subtype="FILE_PATH")
data_path = StringProperty(options={"HIDDEN"})
sound_property = StringProperty(options={"HIDDEN"})
def execute(self, context):
# Check to see if the sound exists... Because the sneakily introduced bpy.data.sounds.load
# check_existing doesn't tell us if it already exists... dammit...
# We don't want to take ownership forcefully if we don't have to.
for i in bpy.data.sounds:
if self.filepath == i.filepath:
sound = i
break
else:
sound = bpy.data.sounds.load(self.filepath)
sound.plasma_owned = True
sound.use_fake_user = True
# Now do the stanky leg^H^H^H^H^H^H^H^H^H^H deed and put the sound on the mod
dest = eval(self.data_path)
setattr(dest, self.sound_property, sound.name)
return {"FINISHED"}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {"RUNNING_MODAL"}
class PlasmaSoundPackOperator(SoundOperator, bpy.types.Operator):
bl_idname = "sound.plasma_pack"
bl_label = "Pack"
bl_options = {"INTERNAL"}
def execute(self, context):
soundemit = context.active_object.plasma_modifiers.soundemit
sound = bpy.data.sounds.get(soundemit.sounds[soundemit.active_sound_index].sound_data)
sound.pack()
return {"FINISHED"}
class PlasmaSoundUnpackOperator(SoundOperator, bpy.types.Operator):
bl_idname = "sound.plasma_unpack"
bl_label = "Unpack"
bl_options = {"INTERNAL"}
method = EnumProperty(name="Method", description="How to unpack",
# See blender/makesrna/intern/rna_packedfile.c
items=[("USE_LOCAL", "Use local file", "", 5),
("WRITE_LOCAL", "Write Local File (overwrite existing)", "", 4),
("USE_ORIGINAL", "Use Original File", "", 6),
("WRITE_ORIGINAL", "Write Original File (overwrite existing)", "", 3)],
options=set())
def execute(self, context):
soundemit = context.active_object.plasma_modifiers.soundemit
sound = bpy.data.sounds.get(soundemit.sounds[soundemit.active_sound_index].sound_data)
sound.unpack(self.method)
return {"FINISHED"}

1
korman/properties/modifiers/__init__.py

@ -22,6 +22,7 @@ from .logic import *
from .physics import * from .physics import *
from .region import * from .region import *
from .render import * from .render import *
from .sound import *
from .water import * from .water import *
class PlasmaModifiers(bpy.types.PropertyGroup): class PlasmaModifiers(bpy.types.PropertyGroup):

64
korman/properties/modifiers/sound.py

@ -0,0 +1,64 @@
# This file is part of Korman.
#
# Korman is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Korman is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
import bpy
from bpy.props import *
from bpy.app.handlers import persistent
from PyHSPlasma import *
from .base import PlasmaModifierProperties
from ...exporter import ExportError
class PlasmaSound(bpy.types.PropertyGroup):
enabled = BoolProperty(name="Enabled", default=True, options=set())
sound_data = StringProperty(name="Sound", description="Sound Datablock", options=set())
class PlasmaSoundEmitter(PlasmaModifierProperties):
pl_id = "soundemit"
bl_category = "Logic"
bl_label = "Sound Emitter"
bl_description = "Point at which sound(s) are played"
bl_icon = "SPEAKER"
sounds = CollectionProperty(type=PlasmaSound)
active_sound_index = IntProperty(options={"HIDDEN"})
def export(self, exporter, bo, so):
pass
@classmethod
def register(cls):
bpy.types.Sound.plasma_owned = BoolProperty(default=False, options={"HIDDEN"})
@property
def requires_actor(self):
return True
@persistent
def _toss_orphaned_sounds(scene):
used_sounds = set()
for i in bpy.data.objects:
soundemit = i.plasma_modifiers.soundemit
used_sounds.update((j.sound_data for j in soundemit.sounds))
for i in bpy.data.sounds:
if i.plasma_owned and i.name not in used_sounds:
i.use_fake_user = False
i.user_clear()
# collects orphaned Plasma owned sound datablocks
bpy.app.handlers.save_pre.append(_toss_orphaned_sounds)

1
korman/ui/modifiers/__init__.py

@ -19,4 +19,5 @@ from .logic import *
from .physics import * from .physics import *
from .region import * from .region import *
from .render import * from .render import *
from .sound import *
from .water import * from .water import *

60
korman/ui/modifiers/sound.py

@ -0,0 +1,60 @@
# This file is part of Korman.
#
# Korman is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Korman is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
import bpy
class SoundListUI(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_property, index=0, flt_flag=0):
if item.sound_data:
sound = bpy.data.sounds.get(item.sound_data)
icon = "SOUND" if sound is not None else "ERROR"
layout.prop(item, "sound_data", emboss=False, icon=icon, text="")
layout.prop(item, "enabled", text="")
else:
layout.label("[Empty]")
def soundemit(modifier, layout, context):
row = layout.row()
row.template_list("SoundListUI", "sounds", modifier, "sounds", modifier, "active_sound_index",
rows=2, maxrows=3)
col = row.column(align=True)
op = col.operator("object.plasma_modifier_collection_add", icon="ZOOMIN", text="")
op.modifier = modifier.pl_id
op.collection = "sounds"
op = col.operator("object.plasma_modifier_collection_remove", icon="ZOOMOUT", text="")
op.modifier = modifier.pl_id
op.collection = "sounds"
op.index = modifier.active_sound_index
try:
sound = modifier.sounds[modifier.active_sound_index]
except:
pass
else:
# Sound datablock picker
row = layout.row(align=True)
row.prop_search(sound, "sound_data", bpy.data, "sounds", text="")
open_op = row.operator("sound.plasma_open", icon="FILESEL", text="")
open_op.data_path = repr(sound)
open_op.sound_property = "sound_data"
# Pack/Unpack
data = bpy.data.sounds.get(sound.sound_data)
if data is not None:
if data.packed_file is None:
row.operator("sound.plasma_pack", icon="UGLYPACKAGE", text="")
else:
row.operator_menu_enum("sound.plasma_unpack", "method", icon="PACKAGE", text="")
Loading…
Cancel
Save