Browse Source

Implement wet footprints.

pull/172/head
Adam Johnson 4 years ago
parent
commit
8fe53c1518
Signed by: Hoikas
GPG Key ID: 0B6515D6FF6F271E
  1. 27
      korman/exporter/decal.py
  2. 28
      korman/properties/prop_scene.py
  3. 30
      korman/ui/ui_scene.py

27
korman/exporter/decal.py

@ -15,6 +15,7 @@
import bpy
from collections import defaultdict
import itertools
from PyHSPlasma import *
import weakref
@ -34,7 +35,8 @@ def _get_footprint_class(exporter, name, vs):
class DecalConverter:
_decal_lookup = {
"footprint": _get_footprint_class,
"footprint_dry": _get_footprint_class,
"footprint_wet": _get_footprint_class,
"puddle": _get_puddle_class,
"ripple": lambda e, name, vs: plDynaRippleVSMgr if vs else plDynaRippleMgr,
}
@ -42,6 +44,7 @@ class DecalConverter:
def __init__(self, exporter):
self._decal_managers = defaultdict(list)
self._exporter = weakref.ref(exporter)
self._notifies = defaultdict(set)
def add_dynamic_decal_receiver(self, so, decal_name):
# One decal manager in Blender can map to many Plasma decal managers.
@ -61,6 +64,15 @@ class DecalConverter:
if key.location == so_loc and getattr(decal_mgr, "waveSet", None) == waveset:
decal_mgr.addTarget(so_key)
# HACKAGE: Add the wet/dirty notifes now that we know about all the decal managers.
notify_names = self._notifies[decal_name]
notify_keys = itertools.chain.from_iterable((self._decal_managers[i] for i in notify_names))
for notify_key in notify_keys:
for i in (i.object for i in decal_mgrs):
i.addNotify(notify_key)
# Don't need to do that again.
del self._notifies[decal_name]
def export_active_print_shape(self, print_shape, decal_name):
decal_mgrs = self._decal_managers.get(decal_name)
if decal_mgrs is None:
@ -106,7 +118,7 @@ class DecalConverter:
self._decal_managers[decal_name].append(decal_mgr.key)
# Certain decals are required to be squares
if decal_type in {"footprint", "wake"}:
if decal_type in {"footprint_dry", "footprint_wet", "wake"}:
length, width = decal.length / 100.0, decal.width / 100.0
else:
length = max(decal.length, decal.width) / 100.0
@ -129,7 +141,7 @@ class DecalConverter:
decal_mgr.scale = hsVector3(length, width, 1.0)
# Hardwired calculations from PlasmaMAX
if decal_type in {"footprint", "bullet"}:
if decal_type in {"footprint_dry", "footprint_wet", "bullet"}:
decal_mgr.rampEnd = 0.1
decal_mgr.decayStart = decal.life_span - (decal.life_span * 0.25)
decal_mgr.lifeSpan = decal.life_span
@ -141,6 +153,15 @@ class DecalConverter:
else:
raise RuntimeError()
# While any decal manager can be wet/dry, it really makes the most sense to only
# expose wet footprints. In the future, we could expose the plDynaDecalEnableMsg
# to nodes for advanced hacking.
decal_mgr.waitOnEnable = decal_type == "footprint_wet"
if decal_type in {"puddle", "ripple"}:
decal_mgr.wetLength = decal.wet_time
self._notifies[decal_name].update((i.name for i in decal.wet_managers
if i.enabled and i.name != decal_name))
# UV Animations are hardcoded in PlasmaMAX. Any reason why we should expose this?
# I can't think of any presently... Note testing the final instance instead of the
# artist setting in case that gets overridden (puddle -> ripple)

28
korman/properties/prop_scene.py

@ -42,6 +42,16 @@ class PlasmaBakePass(bpy.types.PropertyGroup):
default=((True,) * _NUM_RENDER_LAYERS))
class PlasmaWetDecalRef(bpy.types.PropertyGroup):
enabled = BoolProperty(name="Enabled",
default=True,
options=set())
name = StringProperty(name="Decal Name",
description="Wet decal manager",
options=set())
class PlasmaDecalManager(bpy.types.PropertyGroup):
def _get_display_name(self):
return self.name
@ -53,6 +63,10 @@ class PlasmaDecalManager(bpy.types.PropertyGroup):
for j in itertools.chain(decal_receive.managers, decal_print.managers):
if j.name == prev_value:
j.name = value
for i in bpy.context.scene.plasma_scene.decal_managers:
for j in i.wet_managers:
if j.name == prev_value:
j.name = value
self.name = value
name = StringProperty(name="Decal Name",
@ -64,10 +78,11 @@ class PlasmaDecalManager(bpy.types.PropertyGroup):
decal_type = EnumProperty(name="Decal Type",
description="",
items=[("footprint", "Footprint", ""),
items=[("footprint_dry", "Footprint (Dry)", ""),
("footprint_wet", "Footprint (Wet)", ""),
("puddle", "Water Ripple (Shallow)", ""),
("ripple", "Water Ripple (Deep)", "")],
default="footprint",
default="footprint_dry",
options=set())
image = PointerProperty(name="Image",
description="",
@ -102,6 +117,15 @@ class PlasmaDecalManager(bpy.types.PropertyGroup):
subtype="TIME", unit="TIME",
min=0.0, soft_max=300.0, default=30.0,
options=set())
wet_time = FloatProperty(name="Wet Time",
description="How long the decal print shapes stay wet after losing contact with this surface",
subtype="TIME", unit="TIME",
min=0.0, soft_max=300.0, default=10.0,
options=set())
# Footprints to wet-ize
wet_managers = CollectionProperty(type=PlasmaWetDecalRef)
active_wet_index = IntProperty(options={"HIDDEN"})
class PlasmaScene(bpy.types.PropertyGroup):

30
korman/ui/ui_scene.py

@ -32,6 +32,15 @@ class DecalManagerListUI(bpy.types.UIList):
layout.prop(item, "display_name", emboss=False, text="")
class WetManagerListUI(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_property, index=0, flt_flag=0):
if item.name:
layout.label(item.name)
layout.prop(item, "enabled", text="")
else:
layout.label("[Empty]")
class PlasmaDecalManagersPanel(SceneButtonsPanel, bpy.types.Panel):
bl_label = "Plasma Decal Managers"
@ -68,5 +77,24 @@ class PlasmaDecalManagersPanel(SceneButtonsPanel, bpy.types.Panel):
col.label("Draw Settings:")
col.prop(decal_mgr, "intensity")
sub = col.row()
sub.active = decal_mgr.decal_type in {"footprint", "bullet", "torpedo"}
sub.active = decal_mgr.decal_type in {"footprint_dry", "footprint_wet", "bullet", "torpedo"}
sub.prop(decal_mgr, "life_span")
sub = col.row()
sub.active = decal_mgr.decal_type in {"puddle", "ripple"}
sub.prop(decal_mgr, "wet_time")
if decal_mgr.decal_type in {"puddle", "ripple"}:
box.separator()
box.label("Wet Footprints:")
ui_list.draw_list(box, "WetManagerListUI", "scene", decal_mgr, "wet_managers",
"active_wet_index", rows=2, maxrows=3)
try:
wet_ref = decal_mgr.wet_managers[decal_mgr.active_wet_index]
except:
pass
else:
wet_mgr = next((i for i in scene.decal_managers if i.name == wet_ref.name), None)
box.alert = getattr(wet_mgr, "decal_type", None) == "footprint_wet"
box.prop_search(wet_ref, "name", scene, "decal_managers", icon="NONE")
if wet_ref.name == decal_mgr.name:
box.label(text="Circular reference", icon="ERROR")

Loading…
Cancel
Save