Skip to content

Commit 842de3c

Browse files
committed
Merge branch '312-light-spill-custom' into develop
# Conflicts: # io_xplane2blender/xplane_config.py # io_xplane2blender/xplane_constants.py # io_xplane2blender/xplane_props.py # io_xplane2blender/xplane_types/xplane_material.py # tests/features/lights.test.blend
2 parents d93ea35 + 446bf28 commit 842de3c

18 files changed

Lines changed: 333 additions & 34 deletions

io_xplane2blender/xplane_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
# The current data model version, incrementing every time xplane_constants, xplane_props, or xplane_updater
2020
# changes. Builds earlier than 3.4.0-beta.5 have and a version of 0.
2121
# When merging, take the higher data model version of the two branches and add one
22-
CURRENT_DATA_MODEL_VERSION = 100
22+
CURRENT_DATA_MODEL_VERSION = 101
2323

2424
# The build number, hardcoded by the build script when there is one, otherwise it is xplane_constants.BUILD_NUMBER_NONE
2525
CURRENT_BUILD_NUMBER = xplane_constants.BUILD_NUMBER_NONE

io_xplane2blender/xplane_constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ def _get_all_manipulators():
240240
LIGHT_CUSTOM = "custom"
241241
LIGHT_PARAM = "param"
242242
LIGHT_AUTOMATIC = "automatic"
243+
LIGHT_SPILL_CUSTOM = "light_spill_custom"
243244
LIGHT_NON_EXPORTING = "nonexporting"
244245

245246
LIGHTS_OLD_TYPES = {

io_xplane2blender/xplane_props.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,9 +1853,10 @@ class XPlaneLightSettings(bpy.types.PropertyGroup):
18531853
(LIGHT_STROBE, "Strobe" + " (deprecated)", "Strobe" + " (deprecated)"),
18541854
(LIGHT_TRAFFIC, "Traffic" + " (deprecated)", "Traffic" + " (deprecated)"),
18551855
(LIGHT_NAMED, "Named" + " (deprecated)", "Makes named and named only lights, use automatic"),
1856-
(LIGHT_CUSTOM, "Custom", "Custom"),
1856+
(LIGHT_CUSTOM, "Custom Billboard", "Custom billboard light"),
18571857
(LIGHT_PARAM, "Manual Param (deprecated)", "Uses manual entry for parameters, not recommended"),
18581858
(LIGHT_AUTOMATIC, "Automatic", "Makes named and param lights with params taken from Blender light data"),
1859+
(LIGHT_SPILL_CUSTOM, "Custom Spill", "Custom spill light, with automatic parameter detection"),
18591860
(LIGHT_NON_EXPORTING, "Non-Exporting", "Light will not be in the OBJ"),
18601861
]
18611862
)
@@ -1880,7 +1881,7 @@ class XPlaneLightSettings(bpy.types.PropertyGroup):
18801881

18811882
dataref: bpy.props.StringProperty(
18821883
name = 'Dataref',
1883-
description = "A X-Plane Dataref",
1884+
description = "An X-Plane Dataref",
18841885
default = ""
18851886
)
18861887

io_xplane2blender/xplane_types/xplane_light.py

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import math
22
import re
33
from copy import deepcopy
4-
from itertools import takewhile, tee, zip_longest
4+
from dataclasses import dataclass, field
5+
from itertools import chain, takewhile, tee, zip_longest
56
from typing import Dict, List, Optional, Tuple, Union
67

78
import bpy
@@ -17,6 +18,45 @@
1718
from ..xplane_helpers import floatToStr, logger, vec_b_to_x, vec_x_to_b
1819

1920

21+
@dataclass
22+
class _LightSpillCustomParams:
23+
r: float
24+
g: float
25+
b: float
26+
27+
@property
28+
def a(self):
29+
return 1
30+
31+
size: float
32+
dx: float
33+
dy: float
34+
dz: float
35+
width: float
36+
dataref: str
37+
38+
def __str__(self):
39+
return " ".join(
40+
chain(
41+
map(
42+
floatToStr,
43+
(
44+
self.r,
45+
self.g,
46+
self.b,
47+
self.a,
48+
self.size,
49+
self.dx,
50+
self.dy,
51+
self.dz,
52+
self.width,
53+
),
54+
),
55+
(self.dataref,),
56+
)
57+
)
58+
59+
2060
class XPlaneLight(xplane_object.XPlaneObject):
2161
def __init__(self, blenderObject: bpy.types.Object):
2262
super().__init__(blenderObject)
@@ -63,6 +103,8 @@ def __init__(self, blenderObject: bpy.types.Object):
63103
self.params = {}
64104
elif self.lightType == LIGHT_PARAM:
65105
self.params = blenderObject.data.xplane.params
106+
elif self.lightType == LIGHT_SPILL_CUSTOM:
107+
self.params = _LightSpillCustomParams(*([0] * 8), "")
66108
else:
67109
self.params = None
68110

@@ -379,7 +421,50 @@ def convert_table(param: str) -> float:
379421
logger.warn(unknown_light_name_warning)
380422
# X-Plane Light Type | Light Type | parsed_light | light_param_defs | Result
381423
# -------------------|------------|--------------|------------------|-------
382-
# LIGHT_ old | * | N/A | N/A | Write
424+
# LIGHT_SPILL_CUSTOM |"POINT/SPOT"| N/A | N/A | Fillout params, write
425+
# LIGHT_SPILL_CUSTOM | Any others | N/A | N/A | Error
426+
elif self.lightType == LIGHT_SPILL_CUSTOM and light_data.type not in {
427+
"POINT",
428+
"SPOT",
429+
}:
430+
logger.error(
431+
f"Custom Spill lights must be a Point or Spot light, change {self.blenderObject.name}'s type or change it's X-Plane Light Type"
432+
)
433+
return
434+
elif self.lightType == LIGHT_SPILL_CUSTOM and light_data.type in {
435+
"POINT",
436+
"SPOT",
437+
}:
438+
p = self.params
439+
p.r, self.params.g, self.params.b = self.color
440+
p.size = self.size
441+
442+
def width_param_new_value() -> float:
443+
if light_data.type == "POINT":
444+
return 1
445+
elif light_data.type == "SPOT":
446+
# cos(half the cone angle)
447+
return XPlaneLight.WIDTH_for_spill(light_data.spot_size)
448+
449+
def new_dxyz_vec_x() -> Vector:
450+
"""
451+
Returns (potentially scaled) light direction
452+
or (0, 0, 0) for omni lights in X-Plane coords
453+
"""
454+
455+
if light_data.type == "POINT":
456+
return Vector((0, 0, 0))
457+
elif light_data.type == "SPOT":
458+
return vec_b_to_x(self.get_light_direction_b())
459+
else:
460+
assert False, f"What is this light_data.type {light_data.type}"
461+
462+
p.dx, p.dy, p.dz = new_dxyz_vec_x()
463+
p.width = width_param_new_value()
464+
p.dataref = self.dataref
465+
# X-Plane Light Type | Light Type | parsed_light | light_param_defs | Result
466+
# -------------------|------------|--------------|------------------|-------
467+
# LIGHT_{OLD_TYPES} | * | N/A | N/A | Write
383468
elif self.lightType in LIGHTS_OLD_TYPES:
384469
pass
385470
else:
@@ -587,6 +672,8 @@ def should_autocorrect_automatic() -> bool:
587672
f" {' '.join(map(floatToStr,self.uv))}"
588673
f" {self.dataref}\n"
589674
)
675+
elif self.lightType == LIGHT_SPILL_CUSTOM:
676+
o += f"{indent}LIGHT_SPILL_CUSTOM {translation_xp_str} {self.params}\n"
590677
# do not render lights with no indices
591678
elif self.indices[1] > self.indices[0]:
592679
offset = self.indices[0]

io_xplane2blender/xplane_types/xplane_material.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ def collect(self) -> None:
143143
elif xplane_blend_enum == BLEND_ON:
144144
self.attributes["ATTR_blend"].setValue(True)
145145
elif xplane_blend_enum == BLEND_SHADOW:
146-
self.attributes['ATTR_shadow_blend'].setValue(mat.xplane.blendRatio)
146+
self.attributes["ATTR_shadow_blend"].setValue(
147+
mat.xplane.blendRatio
148+
)
147149
elif xplane_version < 1000:
148150
if mat.xplane.blend:
149151
self.attributes["ATTR_no_blend"].setValue(

io_xplane2blender/xplane_ui.py

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,29 @@ def mesh_layout(layout: bpy.types.UILayout, obj: bpy.types.Object) -> None:
669669

670670
def light_layout(layout: bpy.types.UILayout, obj: bpy.types.Object) -> None:
671671
light_data = obj.data
672+
673+
def draw_dataref_search_window(
674+
dataref_row: bpy.types.UILayout, layout: bpy.types.UILayout
675+
):
676+
scene = bpy.context.scene
677+
expanded = (
678+
scene.xplane.dataref_search_window_state.dataref_prop_dest
679+
== "bpy.context.active_object.data.xplane.dataref"
680+
)
681+
if expanded:
682+
our_icon = "ZOOM_OUT"
683+
else:
684+
our_icon = "ZOOM_IN"
685+
dataref_search_toggle_op = row.operator(
686+
"xplane.dataref_search_toggle", text="", emboss=False, icon=our_icon
687+
)
688+
dataref_search_toggle_op.paired_dataref_prop = (
689+
"bpy.context.active_object.data.xplane.dataref"
690+
)
691+
# Finally, in the next row, if we are expanded, build the entire search list.
692+
if expanded:
693+
dataref_search_window_layout(layout)
694+
672695
layout.row().prop(light_data.xplane, "type")
673696

674697
if light_data.xplane.type == LIGHT_AUTOMATIC and light_data.type not in {
@@ -798,6 +821,30 @@ def draw_automatic_ui():
798821
# try_param("param_phase", "PHASE", "Phase")
799822

800823
draw_automatic_ui()
824+
elif light_data.xplane.type == LIGHT_SPILL_CUSTOM and light_data.type not in {
825+
"POINT",
826+
"SPOT",
827+
}:
828+
layout.row().label(
829+
text="Custom Spill lights must use Point or Spot Blender Lights"
830+
)
831+
elif light_data.xplane.type == LIGHT_SPILL_CUSTOM and light_data.type in {
832+
"POINT",
833+
"SPOT",
834+
}:
835+
layout.row().prop(light_data.xplane, "size")
836+
row = layout.row()
837+
row.prop(light_data.xplane, "dataref")
838+
draw_dataref_search_window(row, layout)
839+
debug_box = layout.box()
840+
debug_box.label(text="Calculated Values")
841+
if light_data.type == "POINT":
842+
WIDTH_val = "Omni"
843+
elif light_data.type == "SPOT":
844+
WIDTH_val = round(
845+
xplane_types.XPlaneLight.WIDTH_for_spill(light_data.spot_size), 5
846+
)
847+
debug_box.row().label(text=f"Width: {WIDTH_val}")
801848
elif light_data.xplane.type == LIGHT_NAMED:
802849
layout.row().prop(light_data.xplane, "name")
803850
elif light_data.xplane.type == LIGHT_PARAM:
@@ -809,24 +856,7 @@ def draw_automatic_ui():
809856
layout.row().prop(light_data.xplane, "uv", text="")
810857
row = layout.row()
811858
row.prop(light_data.xplane, "dataref", text="Dataref")
812-
scene = bpy.context.scene
813-
expanded = (
814-
scene.xplane.dataref_search_window_state.dataref_prop_dest
815-
== "bpy.context.active_object.data.xplane.dataref"
816-
)
817-
if expanded:
818-
our_icon = "ZOOM_OUT"
819-
else:
820-
our_icon = "ZOOM_IN"
821-
dataref_search_toggle_op = row.operator(
822-
"xplane.dataref_search_toggle", text="", emboss=False, icon=our_icon
823-
)
824-
dataref_search_toggle_op.paired_dataref_prop = (
825-
"bpy.context.active_object.data.xplane.dataref"
826-
)
827-
# Finally, in the next row, if we are expanded, build the entire search list.
828-
if expanded:
829-
dataref_search_window_layout(layout)
859+
draw_dataref_search_window(row, layout)
830860

831861
layout.row().prop(light_data.xplane, "enable_rgb_override")
832862
if light_data.xplane.enable_rgb_override:

pyproject.toml

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
line-length = 88
33
include = '\.pyi?$'
44
exclude = '''
5-
/(
6-
\.git
7-
| \.mypy_cache
8-
| \.vs
9-
| \.venv
10-
| _build
11-
| build
12-
| dist
13-
| tests
14-
)/
5+
(
6+
/(
7+
\.git
8+
| \.mypy_cache
9+
| \.vs
10+
| \.venv
11+
| _build
12+
| build
13+
| dist
14+
| tests
15+
)/
16+
| tests/template.py
17+
)
1518
'''

tests/features/lights.test.blend

1.7 KB
Binary file not shown.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
I
2+
800
3+
OBJ
4+
5+
POINT_COUNTS 0 0 0 0
6+
7+
# 0 ROOT
8+
# 1 Light: Spot_blank
9+
# LIGHT: Spot_blank weight: 10000
10+
LIGHT_SPILL_CUSTOM 0 1 -0 1 1 1 1 15 0 1 -0.00000015 0.92387953
11+
# 1 Light: Spot_none
12+
# LIGHT: Spot_none weight: 10000
13+
LIGHT_SPILL_CUSTOM 10 1 -0 1 1 1 1 15 0 1 -0.00000015 0.92387953 none
14+
# 1 Light: Spot_traffic_light
15+
# LIGHT: Spot_traffic_light weight: 10000
16+
LIGHT_SPILL_CUSTOM 20 1 -0 1 1 1 1 15 0 1 -0.00000015 0.92387953 sim/graphics/animation/lights/traffic_light
17+
18+
# Build with Blender 2.80 (sub 75) (build b'f6cb5f54494e'). Exported with XPlane2Blender 4.0.0-dev.0+90.NO_BUILD_NUMBR
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
I
2+
800
3+
OBJ
4+
5+
POINT_COUNTS 0 0 0 0
6+
7+
# 0 ROOT
8+
# 1 Light: Spot_aa_backish_68.5_-.907_0,087_-.413_pink
9+
# LIGHT: Spot_aa_backish_68.5_-.907_0,087_-.413_pink weight: 10000
10+
LIGHT_SPILL_CUSTOM 0 10 5 1 0 1 1 35 -0.54601967 0.35867152 0.75711119 0.92387953
11+
# 1 Light: Spot_down_0_0_0_red
12+
# LIGHT: Spot_down_0_0_0_red weight: 10000
13+
LIGHT_SPILL_CUSTOM -20 10 -0 1 0 0 1 35 0 -1 -0 0.92387953
14+
# 1 Light: Spot_forward_90_0_0_blue
15+
# LIGHT: Spot_forward_90_0_0_blue weight: 10000
16+
LIGHT_SPILL_CUSTOM -10 10 -0 0 0 1 1 35 0 0.00000004 -1 0.92387953
17+
# 1 Light: Spot_right_90_0_-90_green
18+
# LIGHT: Spot_right_90_0_-90_green weight: 10000
19+
LIGHT_SPILL_CUSTOM 0 10 -0 0 1 0 1 35 1 0.00000004 0.00000004 0.92387953
20+
21+
# Build with Blender 2.80 (sub 75) (build b'f6cb5f54494e'). Exported with XPlane2Blender 4.0.0-dev.0+90.NO_BUILD_NUMBR

0 commit comments

Comments
 (0)