LUI添加3D

This commit is contained in:
Rowland 2026-05-25 14:53:16 +08:00
parent 1019179b8d
commit 3ee2be723d
3 changed files with 44 additions and 20 deletions

View File

@ -83,12 +83,12 @@ class LUIFunctionComponentsMixin:
'background': bg,
'render_mode': 'screen',
'world_position': (0.0, 8.0, 2.0),
'world_hpr': (25.0, 0.0, 0.0),
'world_hpr': (0.0, 0.0, 0.0),
'world_scale': (1.0, 1.0, 1.0),
'world_pixels_per_unit': 280.0,
'world_depth_test': True,
'world_interactive': True,
'world_two_sided': False,
'world_two_sided': True,
'fill_mode': True, # 默认开启填充模式
'margins': {
'left': 240,

View File

@ -120,12 +120,12 @@ class LUIManagerEditorMixin:
if canvas_data["render_mode"] != "world":
canvas_data["render_mode"] = "screen"
canvas_data.setdefault("world_position", (0.0, 8.0, 2.0))
canvas_data.setdefault("world_hpr", (25.0, 0.0, 0.0))
canvas_data.setdefault("world_hpr", (0.0, 0.0, 0.0))
canvas_data.setdefault("world_scale", (1.0, 1.0, 1.0))
canvas_data.setdefault("world_pixels_per_unit", 280.0)
canvas_data.setdefault("world_depth_test", True)
canvas_data.setdefault("world_interactive", True)
canvas_data.setdefault("world_two_sided", False)
canvas_data.setdefault("world_two_sided", True)
def _copy_canvas_node_transform_to_canvas(self, canvas_data):
node = (canvas_data or {}).get("node")
@ -151,7 +151,7 @@ class LUIManagerEditorMixin:
if hasattr(node, "isEmpty") and node.isEmpty():
return
node.setPos(*self._triplet_or_default(canvas_data.get("world_position"), (0.0, 8.0, 2.0)))
node.setHpr(*self._triplet_or_default(canvas_data.get("world_hpr"), (25.0, 0.0, 0.0)))
node.setHpr(*self._triplet_or_default(canvas_data.get("world_hpr"), (0.0, 0.0, 0.0)))
node.setScale(*self._triplet_or_default(canvas_data.get("world_scale"), (1.0, 1.0, 1.0)))
if canvas_data.get("render_mode") == "world":
node.setTag("is_lui_canvas", "1")
@ -199,12 +199,12 @@ class LUIManagerEditorMixin:
"margins": copy.deepcopy(canvas_data.get("margins", {})),
"render_mode": canvas_data.get("render_mode", "screen"),
"world_position": self._triplet_or_default(canvas_data.get("world_position"), (0.0, 8.0, 2.0)),
"world_hpr": self._triplet_or_default(canvas_data.get("world_hpr"), (25.0, 0.0, 0.0)),
"world_hpr": self._triplet_or_default(canvas_data.get("world_hpr"), (0.0, 0.0, 0.0)),
"world_scale": self._triplet_or_default(canvas_data.get("world_scale"), (1.0, 1.0, 1.0)),
"world_pixels_per_unit": world_pixels_per_unit,
"world_depth_test": bool(canvas_data.get("world_depth_test", True)),
"world_interactive": bool(canvas_data.get("world_interactive", True)),
"world_two_sided": bool(canvas_data.get("world_two_sided", False)),
"world_two_sided": bool(canvas_data.get("world_two_sided", True)),
"left": left,
"top": top,
"width": width,
@ -407,7 +407,7 @@ class LUIManagerEditorMixin:
)
canvas_data["world_hpr"] = self._triplet_or_default(
snapshot.get("world_hpr", canvas_data.get("world_hpr")),
(25.0, 0.0, 0.0),
(0.0, 0.0, 0.0),
)
canvas_data["world_scale"] = self._triplet_or_default(
snapshot.get("world_scale", canvas_data.get("world_scale")),
@ -426,7 +426,7 @@ class LUIManagerEditorMixin:
snapshot.get("world_interactive", canvas_data.get("world_interactive", True))
)
canvas_data["world_two_sided"] = bool(
snapshot.get("world_two_sided", canvas_data.get("world_two_sided", False))
snapshot.get("world_two_sided", canvas_data.get("world_two_sided", True))
)
panel = canvas_data.get("panel")
@ -1681,9 +1681,10 @@ class LUIManagerEditorMixin:
self._ensure_canvas_world_defaults(canvas)
canvas["render_mode"] = mode
if mode == "world":
current_hpr = self._triplet_or_default(canvas.get("world_hpr"), (0.0, 0.0, 0.0))
if not canvas.get("_world_hpr_user_set") and all(abs(float(v)) < 1e-6 for v in current_hpr):
canvas["world_hpr"] = (25.0, 0.0, 0.0)
if not canvas.get("_world_hpr_user_set"):
current_hpr = self._triplet_or_default(canvas.get("world_hpr"), (0.0, 0.0, 0.0))
if all(abs(float(v) - target) < 1e-6 for v, target in zip(current_hpr, (25.0, 0.0, 0.0))):
canvas["world_hpr"] = (0.0, 0.0, 0.0)
self._apply_canvas_world_transform(canvas)
if hasattr(self, "invalidate_world_space_canvas"):
try:
@ -1735,7 +1736,7 @@ class LUIManagerEditorMixin:
self.invalidate_world_space_canvas(self.current_canvas_index)
self._finish_lui_structure_snapshot_session("canvas_world_position")
hpr = self._triplet_or_default(canvas.get("world_hpr"), (25.0, 0.0, 0.0))
hpr = self._triplet_or_default(canvas.get("world_hpr"), (0.0, 0.0, 0.0))
changed, new_hpr = imgui.drag_float3("3D旋转(HPR)", hpr, 0.5, -360.0, 360.0)
if imgui.is_item_activated():
self._begin_lui_structure_snapshot_session("canvas_world_hpr")
@ -1784,7 +1785,7 @@ class LUIManagerEditorMixin:
lambda value=new_interactive: canvas.__setitem__("world_interactive", bool(value))
)
two_sided = bool(canvas.get("world_two_sided", False))
two_sided = bool(canvas.get("world_two_sided", True))
changed, new_two_sided = imgui.checkbox("双面显示", two_sided)
if changed:
self._apply_lui_structure_change_with_history(

View File

@ -157,6 +157,7 @@ class WorldSpaceLUIRuntime:
self._sync_world_canvas_screen_component_visibility(index)
self._ensure_reasonable_world_canvas_scale(index, canvas)
self._disable_billboard_mode(index, canvas)
self._normalize_legacy_default_hpr(canvas)
self._sync_canvas_node_transform(index, canvas)
signature = self._build_canvas_signature(index, canvas)
rebuilt = False
@ -233,6 +234,22 @@ class WorldSpaceLUIRuntime:
self._signatures.pop(index, None)
self._debug_log(f"canvas[{index}] disabled stale world_billboard flag")
def _normalize_legacy_default_hpr(self, canvas: Dict[str, Any]) -> None:
if canvas.get("_world_hpr_user_set") or canvas.get("_world_legacy_hpr_normalized"):
return
hpr = self._triplet(canvas.get("world_hpr"), (0.0, 0.0, 0.0))
if not all(abs(value - target) < 1e-6 for value, target in zip(hpr, (25.0, 0.0, 0.0))):
canvas["_world_legacy_hpr_normalized"] = True
return
canvas["world_hpr"] = (0.0, 0.0, 0.0)
canvas["_world_legacy_hpr_normalized"] = True
node = canvas.get("node")
try:
if node is not None and not node.isEmpty():
node.setHpr(0.0, 0.0, 0.0)
except Exception:
pass
def _remove_canvas_visual(self, index: int) -> None:
root = self._visual_roots.pop(index, None)
self._signatures.pop(index, None)
@ -252,10 +269,10 @@ class WorldSpaceLUIRuntime:
try:
if not canvas.get("_world_transform_initialized"):
pos = canvas.get("world_position", (0.0, 8.0, 2.0))
hpr = canvas.get("world_hpr", (25.0, 0.0, 0.0))
hpr = canvas.get("world_hpr", (0.0, 0.0, 0.0))
scale = canvas.get("world_scale", (1.0, 1.0, 1.0))
node.setPos(*self._triplet(pos, (0.0, 8.0, 2.0)))
node.setHpr(*self._triplet(hpr, (25.0, 0.0, 0.0)))
node.setHpr(*self._triplet(hpr, (0.0, 0.0, 0.0)))
node.setScale(*self._triplet(scale, (1.0, 1.0, 1.0)))
canvas["_world_transform_initialized"] = True
self._copy_node_transform_to_canvas(canvas, node)
@ -545,7 +562,7 @@ class WorldSpaceLUIRuntime:
f"rebuilt={rebuilt} sig={signature[:10]} comps={component_count} "
f"size=({width:.1f}x{height:.1f}) ppu={_num(canvas.get('world_pixels_per_unit'), 100.0):.1f} "
f"depth={bool(canvas.get('world_depth_test', True))} interactive={bool(canvas.get('world_interactive', True))} "
f"two_sided={bool(canvas.get('world_two_sided', False))}"
f"two_sided={bool(canvas.get('world_two_sided', True))}"
)
print(
"[LUI3D Debug] node "
@ -692,8 +709,8 @@ class WorldSpaceLUIRuntime:
"background_color": self._canvas_background_color(canvas),
"world_pixels_per_unit": _num(canvas.get("world_pixels_per_unit"), 100.0),
"world_depth_test": bool(canvas.get("world_depth_test", True)),
"world_two_sided": bool(canvas.get("world_two_sided", False)),
"renderer": "texture_rgba8_gbuffer_scene_fixed_v4",
"world_two_sided": bool(canvas.get("world_two_sided", True)),
"renderer": "texture_rgba8_gbuffer_scene_fixed_v5_flipped",
},
"components": components,
"hover": self._hover_hit.get("component_index") if self._hover_hit else -1,
@ -927,6 +944,12 @@ class WorldSpaceLUIRuntime:
for comp_index, comp in comps:
self._draw_canvas_component_2d(draw, image, comp_index, comp, tex_w, tex_h)
try:
transpose = getattr(Image, "Transpose", Image)
image = image.transpose(getattr(transpose, "FLIP_TOP_BOTTOM"))
except Exception:
pass
tex = p3d.Texture(f"lui_world_canvas_{canvas_index}")
tex.setup2dTexture(tex_w, tex_h, p3d.Texture.T_unsigned_byte, p3d.Texture.F_rgba8)
tex.setMinfilter(p3d.SamplerState.FT_linear)
@ -1010,7 +1033,7 @@ class WorldSpaceLUIRuntime:
width, height = self._canvas_size(canvas)
ppu = max(1.0, _num(canvas.get("world_pixels_per_unit"), 100.0))
depth_test = bool(canvas.get("world_depth_test", True))
two_sided = bool(canvas.get("world_two_sided", False))
two_sided = bool(canvas.get("world_two_sided", True))
canvas_texture = self._build_canvas_texture(canvas_index, canvas, width, height)
if canvas_texture is not None: