Skip to content

Commit 943b476

Browse files
committed
allow pan-tilt to be applied to light, parent or grandparent
pan-tilt affects delta-rotation, so rotation can be used for setting centre
1 parent b05135e commit 943b476

File tree

3 files changed

+125
-21
lines changed

3 files changed

+125
-21
lines changed

__init__.py

+70-6
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
import bpy
2525
from bpy.app.handlers import persistent
26-
from bpy.props import BoolProperty, IntProperty, StringProperty
26+
from bpy.props import BoolProperty, IntProperty, StringProperty, EnumProperty
2727

2828
from .src.artnet_socket import ArtNetSocket
2929
from .src.universe_store import UniverseStore, ALL_UNIVERSES
@@ -36,9 +36,25 @@
3636
GLOBAL_DATA = {
3737
ArtNetSocket: ArtNetSocket,
3838
BlenderSynchroniser: BlenderSynchroniser,
39-
FixtureStore: FixtureStore
39+
FixtureStore: FixtureStore,
4040
}
4141

42+
PAN_TILT_TARGETS = [
43+
('lx', 'Light x', 'tilt around light x axis', 0),
44+
('ly', 'Light y', 'tilt around light y axis', 1),
45+
('lz', 'Light z', 'tilt around light z axis', 2),
46+
None,
47+
('px', 'Parent x', 'tilt around parent x axis', 3),
48+
('py', 'Parent y', 'tilt around parent y axis', 4),
49+
('pz', 'Parent z', 'tilt around parent z axis', 5),
50+
None,
51+
('gpx', 'Grandparent x', 'tilt around grandparent x axis', 6),
52+
('gpy', 'Grandparent y', 'tilt around grandparent y axis', 7),
53+
('gpz', 'Grandparent z', 'tilt around grandparent z axis', 8),
54+
None,
55+
('none', 'Ignore', 'ignore tilt from Artnet', 9)
56+
]
57+
4258
bl_info = {
4359
"name": "ArtNet Lighting Controller",
4460
"description": "Combine with Evee to get a real "
@@ -87,24 +103,70 @@ def register():
87103
bpy.app.handlers.load_post.append(_on_file_loaded)
88104
# add light properties
89105
bpy.types.Light.artnet_enabled = BoolProperty(
90-
name="artnet_enabled",
106+
name="Enabled",
91107
update=_light_data_change
92108
)
93109
bpy.types.Light.artnet_universe = IntProperty(
94-
name="artnet_universe",
110+
name="Universe",
95111
update=_light_data_change
96112
)
97113
bpy.types.Light.artnet_fixture_type = StringProperty(
98-
name="artnet_fixture_type",
114+
name="Fixture Type",
99115
update=_light_data_change
100116
)
101117
bpy.types.Light.artnet_base_address = IntProperty(
102-
name="artnet_base_address",
118+
name="Base DMX Address",
103119
update=_light_data_change
104120
)
121+
bpy.types.Light.artnet_pan_target = EnumProperty(
122+
name="Pan Target",
123+
items=PAN_TILT_TARGETS,
124+
default="lx",
125+
update=_light_data_change,
126+
get=get_pan_target,
127+
set=set_pan_target
128+
)
129+
bpy.types.Light.artnet_tilt_target = EnumProperty(
130+
name="Tilt Target",
131+
items=PAN_TILT_TARGETS,
132+
default="lz",
133+
update=_light_data_change,
134+
get=get_tilt_target,
135+
set=set_tilt_target
136+
)
137+
bpy.types.Light.artnet_old_pan_target = EnumProperty(
138+
name="Old Pan Target",
139+
items=PAN_TILT_TARGETS,
140+
default="none"
141+
)
142+
bpy.types.Light.artnet_old_tilt_target = EnumProperty(
143+
name="Old Tilt Target",
144+
items=PAN_TILT_TARGETS,
145+
default="none"
146+
)
105147
# register UI Panel
106148
bpy.utils.register_class(LightArtNetPanel)
107149

150+
def get_pan_target(self):
151+
return self.get("artnet_pan_target", "lz")
152+
153+
def set_pan_target(self, value):
154+
self.artnet_old_pan_target = get_pan_tilt_target_from_int(self.get("artnet_pan_target", 9))
155+
self["artnet_pan_target"] = value
156+
157+
def get_pan_tilt_target_from_int(value):
158+
for target in PAN_TILT_TARGETS:
159+
if target is not None:
160+
if target[3] == value:
161+
return target[0]
162+
163+
def get_tilt_target(self):
164+
return self.get("artnet_tilt_target", "lx")
165+
166+
def set_tilt_target(self, value):
167+
self.artnet_old_tilt_target = get_pan_tilt_target_from_int(self.get("artnet_tilt_target", 9))
168+
self["artnet_tilt_target"] = value
169+
108170
def unregister():
109171
"""Called from Blender"""
110172
if GLOBAL_DATA["ArtNetSocket"] is not None:
@@ -119,6 +181,8 @@ def unregister():
119181
del bpy.types.Light.artnet_fixture_type
120182
del bpy.types.Light.artnet_universe
121183
del bpy.types.Light.artnet_base_address
184+
del bpy.types.Light.artnet_pan_target
185+
del bpy.types.Light.artnet_tilt_target
122186

123187
def _light_data_change(data, context):
124188
"""One of the lights changed in the scene - update our internal data"""

src/blender_sync.py

+50-12
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def update_spot_light(self, obj, mapping, universe, raw_universe):
5959
# push the data
6060
obj.data.color = self._get_color(universe, raw_universe, base_address, fixture_type) or [0, 0, 0]
6161
obj.data.energy = self._get_power(universe, base_address, fixture_type)
62-
obj.rotation_euler = self._get_rotation(universe, base_address, fixture_type) or [0, 0, 0]
62+
self._set_rotation(obj, universe, base_address, fixture_type)
6363
obj.data.spot_size = self._get_zoom(universe, base_address, fixture_type) or 0
6464

6565
def update_area_light(self, obj, mapping, universe, raw_universe):
@@ -69,7 +69,7 @@ def update_area_light(self, obj, mapping, universe, raw_universe):
6969
# push the data
7070
obj.data.color = self._get_color(universe, raw_universe, base_address, fixture_type) or [0, 0, 0]
7171
obj.data.energy = self._get_power(universe, base_address, fixture_type)
72-
obj.rotation_euler = self._get_rotation(universe, base_address, fixture_type) or [0, 0, 0]
72+
self._set_rotation(obj, universe, base_address, fixture_type)
7373

7474
def _get_zoom(self, universe, base_address, fixture_type):
7575
try:
@@ -93,18 +93,56 @@ def _get_power(self, universe, base_address, fixture_type):
9393
return 1000 # because no data yet
9494

9595
def _get_rotation(self, universe, base_address, fixture_type):
96+
pan = universe[base_address + fixture_type["pan"]]
97+
tilt = universe[base_address + fixture_type["tilt"]]
98+
pan_range = fixture_type["panRange"]
99+
tilt_range = fixture_type["tiltRange"]
100+
pan -= 0.5
101+
tilt -= 0.5
102+
pan *= pan_range
103+
tilt *= tilt_range
104+
return [pan, tilt]
105+
106+
def _set_rotation(self, obj, universe, base_address, fixture_type):
107+
if obj.data.artnet_old_pan_target != "none":
108+
self.set_rotation_on_target(obj, obj.data.artnet_old_pan_target, 0)
109+
obj.data.artnet_old_pan_target = "none"
110+
111+
if obj.data.artnet_old_tilt_target != "none":
112+
self.set_rotation_on_target(obj, obj.data.artnet_old_tilt_target, 0)
113+
obj.data.artnet_old_tilt_target = "none"
114+
96115
try:
97-
pan = universe[base_address + fixture_type["pan"]]
98-
tilt = universe[base_address + fixture_type["tilt"]]
99-
pan_range = fixture_type["panRange"]
100-
tilt_range = fixture_type["tiltRange"]
101-
pan -= 0.5
102-
tilt -= 0.5
103-
pan *= pan_range
104-
tilt *= tilt_range
105-
return [0, tilt, pan]
116+
rotation = self._get_rotation(universe, base_address, fixture_type)
106117
except IndexError:
107-
return [0, 0, 0] # null movement, because no data yet
118+
print ('_set_rotation error')
119+
pass # null movement, because no data yet
120+
pan = rotation[0]
121+
tilt = rotation[1]
122+
self.set_rotation_on_target(obj, obj.data.artnet_pan_target, pan)
123+
self.set_rotation_on_target(obj, obj.data.artnet_tilt_target, tilt)
124+
125+
def set_rotation_on_target(self, obj, target, rotation):
126+
if target == "lx":
127+
obj.delta_rotation_euler.x = rotation
128+
elif target == "ly":
129+
obj.delta_rotation_euler.y = rotation
130+
elif target == "lz":
131+
obj.delta_rotation_euler.z = rotation
132+
elif obj.parent is not None:
133+
if target == "px":
134+
obj.parent.delta_rotation_euler.x = rotation
135+
elif target == "py":
136+
obj.parent.delta_rotation_euler.y = rotation
137+
elif target == "pz":
138+
obj.parent.delta_rotation_euler.z = rotation
139+
elif obj.parent.parent is not None:
140+
if target == "gpx":
141+
obj.parent.parent.delta_rotation_euler.x = rotation
142+
elif target == "gpy":
143+
obj.parent.parent.delta_rotation_euler.y = rotation
144+
elif target == "gpz":
145+
obj.parent.parent.delta_rotation_euler.z = rotation
108146

109147
def _get_color(self, universe, rawUniverse, base_address, fixture_type):
110148
color_mode = fixture_type["colorMode"]

src/ui/light_panel.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ def draw(self, context):
2828
return
2929

3030
layout = self.layout
31-
layout.prop(data, "artnet_fixture_type", text="Fixture Type")
32-
layout.prop(data, "artnet_universe", text="Universe")
33-
layout.prop(data, "artnet_base_address", text="Base DMX Address")
31+
layout.prop(data, "artnet_fixture_type")
32+
layout.prop(data, "artnet_universe")
33+
layout.prop(data, "artnet_base_address")
34+
layout.prop(data, "artnet_pan_target")
35+
layout.prop(data, "artnet_tilt_target")

0 commit comments

Comments
 (0)