EG/ui/panels/editor_panels_right_material.py
2026-03-12 22:07:48 +08:00

222 lines
9.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from imgui_bundle import imgui, imgui_ctx
class EditorPanelsRightMaterialMixin:
"""Auto-split mixin from editor_panels_right.py."""
def _draw_appearance_properties(self, node):
"""绘制材质属性Unity风格主材质入口"""
materials = self.app._get_node_materials(node)
if not materials:
fallback_material = self.app._ensure_material_for_node(node)
materials = [fallback_material] if fallback_material else []
if not materials:
imgui.text_colored((1.0, 0.5, 0.5, 1.0), "无法获取材质")
return
material = materials[0]
# 历史上可能通过 node.setColor 留下了额外染色,先清掉避免与材质主颜色打架
try:
if node.hasColor():
node.clearColor()
if hasattr(node, "clearColorScale"):
node.clearColorScale()
except Exception:
pass
base_color = self.app._get_material_base_color(material)
def apply_primary_color(color):
for current_material in materials:
self.app._set_material_base_color(current_material, color)
self.app._apply_material_to_geom_states(node, current_material)
if self.app._get_material_surface_type(current_material) == 3:
self.app._set_material_opacity(node, current_material, color[3])
else:
self.app._apply_material_surface_state(node, current_material)
def apply_surface_type(surface_type):
for current_material in materials:
self.app._set_material_surface_type(
node,
current_material,
surface_type,
refresh_pipeline=False,
)
if materials:
self.app._apply_material_surface_state(node, materials[0])
self.app._refresh_pipeline_material_mode(node, materials[0])
def apply_opacity(opacity):
for current_material in materials:
self.app._set_material_opacity(node, current_material, opacity)
imgui.text("主颜色")
changed, new_color = imgui.color_edit4(
"##material_base_color",
base_color,
imgui.ColorEditFlags_.display_rgb.value,
)
if changed:
apply_primary_color(new_color)
imgui.same_line()
if imgui.button("颜色选择器##material_color_picker"):
self.show_color_picker(
target_object=None,
property_name=None,
initial_color=base_color,
callback=apply_primary_color,
)
surface_options = [
("不透明", 0),
("自发光", 1),
("透明", 3),
]
current_surface = self.app._get_material_surface_type(material)
current_surface_index = next(
(index for index, (_, value) in enumerate(surface_options) if value == current_surface),
0,
)
imgui.text("表面类型")
changed, selected_index = imgui.combo(
"##material_surface_type",
current_surface_index,
[label for label, _ in surface_options],
)
if changed:
apply_surface_type(surface_options[selected_index][1])
current_surface = surface_options[selected_index][1]
if self.app._get_material_surface_type(material) == 3:
opacity = self.app._get_material_opacity(material)
changed, new_opacity = imgui.slider_float("透明度", opacity, 0.0, 1.0)
if changed:
apply_opacity(new_opacity)
imgui.separator()
# 详细材质属性
self._draw_material_properties(node)
def _draw_material_properties(self, node):
"""绘制材质属性"""
materials = self.app._get_node_materials(node)
if not materials:
imgui.text_colored((0.5, 0.5, 0.5, 1.0), "无材质")
return
for i, material in enumerate(materials):
material_name = material.get_name() if hasattr(material, 'get_name') and material.get_name() else f"材质{i + 1}"
if imgui.collapsing_header(f"材质: {material_name}"):
# PBR属性
imgui.text("PBR")
if hasattr(material, 'roughness') and material.roughness is not None:
try:
roughness_value = float(material.roughness)
changed, new_roughness = imgui.slider_float(f"粗糙度##rough_{i}", roughness_value, 0.0, 1.0)
if changed:
self._update_material_roughness(material, new_roughness)
except:
imgui.text_colored((0.7, 0.7, 0.7, 1.0), "粗糙度: 不可用")
if hasattr(material, 'metallic') and material.metallic is not None:
try:
metallic_value = float(material.metallic)
changed, new_metallic = imgui.slider_float(f"金属性##metal_{i}", metallic_value, 0.0, 1.0)
if changed:
self._update_material_metallic(material, new_metallic)
except:
imgui.text_colored((0.7, 0.7, 0.7, 1.0), "金属性: 不可用")
if hasattr(material, 'refractive_index') and material.refractive_index is not None:
try:
ior_value = float(material.refractive_index)
changed, new_ior = imgui.slider_float(f"折射率##ior_{i}", ior_value, 1.0, 3.0)
if changed:
self._update_material_ior(material, new_ior)
except:
imgui.text_colored((0.7, 0.7, 0.7, 1.0), "折射率: 不可用")
# 材质预设
imgui.text("材质预设")
presets = ["默认", "金属", "塑料", "玻璃", "木材", "混凝土"]
current_preset = 0 # 默认选择
if imgui.begin_combo(f"预设##preset_{i}", presets[current_preset]):
for j, preset_name in enumerate(presets):
if imgui.selectable(preset_name, j == current_preset):
self._apply_material_preset(material, preset_name)
self._apply_material_surface_state(node, material)
imgui.end_combo()
# 纹理信息
imgui.text("纹理贴图")
if imgui.button(f"选择漫反射贴图##diffuse_{i}"):
self._select_texture_for_material(node, material, "diffuse")
imgui.same_line()
if imgui.button(f"选择法线贴图##normal_{i}"):
self._select_texture_for_material(node, material, "normal")
imgui.same_line()
if imgui.button(f"选择粗糙度贴图##roughness_{i}"):
self._select_texture_for_material(node, material, "roughness")
if imgui.button(f"选择金属性贴图##metallic_{i}"):
self._select_texture_for_material(node, material, "metallic")
imgui.same_line()
if imgui.button(f"选择自发光贴图##emission_{i}"):
self._select_texture_for_material(node, material, "emission")
imgui.same_line()
if imgui.button(f"清除所有贴图##clear_{i}"):
self._clear_all_textures(node)
# 显示当前纹理信息
self._display_current_textures(node, material)
imgui.separator()
if imgui.button("应用材质"):
self._apply_material_to_node(node)
imgui.same_line()
if imgui.button("重置材质"):
self._reset_material(node)
def _draw_shading_model_panel(self, node, material, material_index):
"""绘制着色模型选择面板"""
try:
imgui.text("着色模型")
shading_models = [
("默认", 0),
("自发光", 1),
("透明", 3),
]
current_model = self.app._get_material_surface_type(material)
current_index = next((idx for idx, (_, value) in enumerate(shading_models) if value == current_model), 0)
if imgui.begin_combo(f"着色模型##shading_{material_index}", shading_models[current_index][0]):
for index, (model_name, model_value) in enumerate(shading_models):
if imgui.selectable(model_name, index == current_index):
self.app._set_material_surface_type(node, material, model_value)
imgui.end_combo()
if self.app._get_material_surface_type(material) == 3:
imgui.text("透明度设置")
try:
current_opacity = self.app._get_material_opacity(material)
changed, new_opacity = imgui.slider_float(f"不透明度##opacity_{material_index}", current_opacity, 0.0, 1.0)
if changed:
self.app._set_material_opacity(node, material, new_opacity)
except:
imgui.text_colored((0.7, 0.7, 0.7, 1.0), "透明度控制不可用")
except Exception as e:
print(f"绘制着色模型面板失败: {e}")