EG/ui/panels/editor_panels_right_material.py

228 lines
11 KiB
Python

from imgui_bundle import imgui, imgui_ctx
class EditorPanelsRightMaterialMixin:
"""Auto-split mixin from editor_panels_right.py."""
def _draw_appearance_properties(self, node):
"""绘制外观属性"""
# 颜色属性
if hasattr(node, 'getColor'):
imgui.text("颜色")
try:
color = node.getColor()
# 确保颜色是有效的
if not color or len(color) < 3:
color = (1.0, 1.0, 1.0, 1.0) # 默认白色
except:
color = (1.0, 1.0, 1.0, 1.0) # 默认白色
# 颜色滑块
changed, new_r = imgui.slider_float("R##color_r", color[0], 0.0, 1.0)
if changed:
new_color = (new_r, color[1], color[2], color[3] if len(color) > 3 else 1.0)
node.setColor(new_color)
color = new_color
changed, new_g = imgui.slider_float("G##color_g", color[1], 0.0, 1.0)
if changed:
new_color = (color[0], new_g, color[2], color[3] if len(color) > 3 else 1.0)
node.setColor(new_color)
color = new_color
changed, new_b = imgui.slider_float("B##color_b", color[2], 0.0, 1.0)
if changed:
new_color = (color[0], color[1], new_b, color[3] if len(color) > 3 else 1.0)
node.setColor(new_color)
color = new_color
# 只有当颜色有alpha通道时才显示alpha滑块
if len(color) > 3:
changed, new_a = imgui.slider_float("A##color_a", color[3], 0.0, 1.0)
if changed:
new_color = (color[0], color[1], color[2], new_a)
node.setColor(new_color)
color = new_color
# 颜色预览和选择器
imgui.text("颜色预览")
color_with_alpha = (color[0], color[1], color[2], color[3] if len(color) > 3 else 1.0)
if imgui.color_button("颜色预览##preview", color_with_alpha, 0, (100, 30)):
# 点击颜色按钮打开颜色选择器
self.show_color_picker(node, 'color', color_with_alpha)
imgui.same_line()
if imgui.button("选择颜色##color_picker_btn"):
self.show_color_picker(node, 'color', (color.x, color.y, color.z, color.w))
# 透明度
if hasattr(node, 'setTransparency') and hasattr(node, 'getTransparency'):
imgui.text("透明度")
current_transparency = node.getTransparency()
# 将当前的透明度值转换为0.0-1.0范围用于显示
display_transparency = 1.0 - current_transparency if current_transparency <= 1 else 0.0
changed, new_transparency = imgui.slider_float("透明度", display_transparency, 0.0, 1.0)
if changed:
# 将0.0-1.0范围转换回Panda3D的透明度格式
panda_transparency = int((1.0 - new_transparency) * 255)
node.setTransparency(panda_transparency)
# 材质属性
self._draw_material_properties(node)
# 渲染状态
imgui.text("渲染状态")
if imgui.button("应用材质"):
self._apply_material_to_node(node)
imgui.same_line()
if imgui.button("重置材质"):
self._reset_material(node)
def _draw_material_properties(self, node):
"""绘制材质属性"""
materials = node.find_all_materials()
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}"):
# 材质基础颜色
base_color = self._get_material_base_color(material)
if base_color:
imgui.text("基础颜色")
changed, new_r = imgui.slider_float(f"R##mat_r_{i}", base_color[0], 0.0, 1.0)
if changed:
self._update_material_base_color(material, 'r', new_r)
base_color = (new_r, base_color[1], base_color[2], base_color[3])
changed, new_g = imgui.slider_float(f"G##mat_g_{i}", base_color[1], 0.0, 1.0)
if changed:
self._update_material_base_color(material, 'g', new_g)
base_color = (base_color[0], new_g, base_color[2], base_color[3])
changed, new_b = imgui.slider_float(f"B##mat_b_{i}", base_color[2], 0.0, 1.0)
if changed:
self._update_material_base_color(material, 'b', new_b)
base_color = (base_color[0], base_color[1], new_b, base_color[3])
changed, new_a = imgui.slider_float(f"A##mat_a_{i}", base_color[3], 0.0, 1.0)
if changed:
self._update_material_base_color(material, 'a', new_a)
base_color = (base_color[0], base_color[1], base_color[2], new_a)
# PBR属性
if hasattr(material, 'roughness') and material.roughness is not None:
imgui.text("PBR属性")
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)
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._draw_shading_model_panel(material, i)
# 显示当前纹理信息
self._display_current_textures(node, material)
def _draw_shading_model_panel(self, material, material_index):
"""绘制着色模型选择面板"""
try:
imgui.text("着色模型")
# RenderPipeline支持的着色模型
shading_models = ["默认", "自发光", "透明"]
current_model = 0 # 默认选择
# 安全地获取当前着色模型
try:
if hasattr(material, 'emission') and material.emission is not None:
current_model = int(material.emission.x)
except:
current_model = 0
# 着色模型选择
if imgui.begin_combo(f"着色模型##shading_{material_index}", shading_models[current_model]):
for j, model_name in enumerate(shading_models):
if imgui.selectable(model_name, j == current_model):
self._update_shading_model(material, j)
imgui.end_combo()
# 如果是透明着色模型,添加透明度控制
if current_model == 3: # 透明着色模型
imgui.text("透明度设置")
try:
if hasattr(material, 'shading_model_param0'):
current_opacity = material.shading_model_param0
else:
current_opacity = 1.0
changed, new_opacity = imgui.slider_float(f"不透明度##opacity_{material_index}", current_opacity, 0.0, 1.0)
if changed:
self._update_transparency(material, new_opacity)
except:
imgui.text_colored((0.7, 0.7, 0.7, 1.0), "透明度控制不可用")
except Exception as e:
print(f"绘制着色模型面板失败: {e}")