增加控制灯光的显示隐藏,并支持模型,GUI,灯光的显示隐藏保存场景后重新加载保存时的状态。
This commit is contained in:
parent
a3711c57ea
commit
3d5356a594
@ -90,7 +90,6 @@ class LightManager(RPObject):
|
||||
|
||||
def remove_light(self, light):
|
||||
""" Removes a light """
|
||||
print(f'333333333333333333333333333333,{light.casts_shadows}')
|
||||
# from RenderPipelineFile.rpcore.pynative.internal_light_manager import InternalLightManager
|
||||
# inter = InternalLightManager()
|
||||
# inter.remove_light(light)
|
||||
|
||||
@ -208,7 +208,6 @@ class RenderPipeline(RPObject):
|
||||
def remove_light(self, light):
|
||||
""" Removes a previously attached light, check out the LightManager
|
||||
remove_light documentation for further information. """
|
||||
print(f'222222222222222222222222222,{light.casts_shadows}')
|
||||
self.light_mgr.remove_light(light)
|
||||
|
||||
def load_ies_profile(self, filename):
|
||||
|
||||
@ -1238,6 +1238,8 @@ class SceneManager:
|
||||
light_obj = node.getPythonTag("rp_light_object")
|
||||
if light_obj:
|
||||
node.setTag("light_energy", str(light_obj.energy))
|
||||
if node.hasTag("stored_energy"):
|
||||
node.setTag("stored_energy", node.getTag("stored_energy"))
|
||||
node.setTag("light_radius", str(getattr(light_obj, 'radius', 0)))
|
||||
if hasattr(light_obj, 'fov'):
|
||||
node.setTag("light_fov", str(light_obj.fov))
|
||||
@ -2359,8 +2361,22 @@ class SceneManager:
|
||||
# 确保灯光节点有正确的标签,以便在场景树更新时被识别
|
||||
if not light_node.hasTag("is_scene_element"):
|
||||
light_node.setTag("is_scene_element", "1")
|
||||
light_node.setTag("is_scene_element", "1")
|
||||
light_node.setTag("element_type", "spotlight")
|
||||
light_node.setTag("tree_item_type", "LIGHT_NODE")
|
||||
|
||||
print(f"重新创建聚光灯: {light_node.getName()}")
|
||||
if light_node.hasTag("stored_energy"):
|
||||
stored_energy = float(light_node.getTag("stored_energy"))
|
||||
if stored_energy > 0:
|
||||
light_node.setTag("stored_energy", str(stored_energy))
|
||||
|
||||
user_visible = True
|
||||
if light_node.hasTag("user_visible"):
|
||||
user_visible = light_node.getTag("user_visible").lower() == "true"
|
||||
|
||||
light_node.setPythonTag("user_visible",user_visible)
|
||||
if not user_visible:
|
||||
self.toggleLightVisibility(light_node,False)
|
||||
except Exception as e:
|
||||
print(f"重新创建聚光灯失败: {str(e)}")
|
||||
import traceback
|
||||
@ -2404,7 +2420,23 @@ class SceneManager:
|
||||
if not light_node.hasTag("is_scene_element"):
|
||||
light_node.setTag("is_scene_element", "1")
|
||||
|
||||
print(f"重新创建点光源: {light_node.getName()}")
|
||||
light_node.setTag("is_scene_element", "1")
|
||||
light_node.setTag("element_type", "pointlight")
|
||||
light_node.setTag("tree_item_type", "LIGHT_NODE")
|
||||
|
||||
if light_node.hasTag("stored_energy"):
|
||||
stored_energy = float(light_node.getTag("stored_energy"))
|
||||
if stored_energy > 0:
|
||||
light_node.setTag("stored_energy", str(stored_energy))
|
||||
|
||||
user_visible = True
|
||||
if light_node.hasTag("user_visible"):
|
||||
user_visible = light_node.getTag("user_visible").lower()=="true"
|
||||
|
||||
light_node.setPythonTag("user_visible",user_visible)
|
||||
|
||||
if not user_visible:
|
||||
self.toggleLightVisibility(light_node,False)
|
||||
except Exception as e:
|
||||
print(f"重新创建点光源失败: {str(e)}")
|
||||
import traceback
|
||||
@ -2565,6 +2597,7 @@ class SceneManager:
|
||||
light_np.setTag("tree_item_type", "LIGHT_NODE")
|
||||
light_np.setTag("light_energy", str(light.energy))
|
||||
light_np.setTag("created_by_user", "1")
|
||||
light_np.setTag("element_type","spotlight")
|
||||
|
||||
# 保存光源对象引用
|
||||
light_np.setPythonTag("rp_light_object", light)
|
||||
@ -2673,6 +2706,7 @@ class SceneManager:
|
||||
light_np.setTag("tree_item_type", "LIGHT_NODE")
|
||||
light_np.setTag("light_energy", str(light.energy))
|
||||
light_np.setTag("created_by_user", "1")
|
||||
light_np.setTag("element_type","pointlight")
|
||||
|
||||
# 保存光源对象引用
|
||||
light_np.setPythonTag("rp_light_object", light)
|
||||
@ -2721,6 +2755,103 @@ class SceneManager:
|
||||
traceback.print_exc()
|
||||
return None
|
||||
|
||||
def isLightObject(self, nodePath):
|
||||
"""检查是否为灯光对象"""
|
||||
try:
|
||||
if not nodePath:
|
||||
return False
|
||||
|
||||
|
||||
# 方法1: 检查PythonTag
|
||||
if nodePath.hasPythonTag("rp_light_object"):
|
||||
rp_light = nodePath.getPythonTag("rp_light_object")
|
||||
if rp_light is not None:
|
||||
return True
|
||||
|
||||
# 方法2: 检查element_type标签
|
||||
if nodePath.hasTag("element_type"):
|
||||
element_type = nodePath.getTag("element_type")
|
||||
if element_type in ["spotlight", "pointlight"]:
|
||||
return True
|
||||
|
||||
# 方法3: 检查tree_item_type标签
|
||||
if nodePath.hasTag("tree_item_type"):
|
||||
tree_item_type = nodePath.getTag("tree_item_type")
|
||||
if tree_item_type == "LIGHT_NODE":
|
||||
return True
|
||||
|
||||
# 方法4: 通过名称模式匹配(作为后备方案)
|
||||
node_name = nodePath.getName().lower()
|
||||
if "spotlight" in node_name or "pointlight" in node_name:
|
||||
return True
|
||||
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"检查灯光对象时出错: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def toggleLightVisibility(self, light_node, visible):
|
||||
"""切换灯光可见性"""
|
||||
try:
|
||||
print(f"切换灯光可见性: {light_node.getName()}, 可见={visible}")
|
||||
|
||||
# 保存用户可见性状态到该特定节点
|
||||
light_node.setPythonTag("user_visible", visible)
|
||||
|
||||
# 获取该特定灯光对象
|
||||
rp_light_object = light_node.getPythonTag("rp_light_object")
|
||||
if not rp_light_object:
|
||||
print(f"错误: {light_node.getName()} 未找到RP灯光对象引用")
|
||||
return
|
||||
|
||||
# 获取RenderPipeline实例
|
||||
from QMeta3D.Meta3DWorld import get_render_pipeline
|
||||
render_pipeline = get_render_pipeline()
|
||||
|
||||
if not render_pipeline:
|
||||
print("错误: 无法获取RenderPipeline实例")
|
||||
return
|
||||
|
||||
try:
|
||||
if visible:
|
||||
if light_node.hasTag("stored_energy"):
|
||||
stored_energy = float(light_node.getTag("stored_energy"))
|
||||
rp_light_object.energy=stored_energy
|
||||
print(f"已恢复灯光强度: {light_node.getName()}, 能量={stored_energy}")
|
||||
# 启用特定灯光
|
||||
# render_pipeline.add_light(rp_light_object)
|
||||
# print(f"已添加灯光到渲染管线: {light_node.getName()}")
|
||||
else:
|
||||
# 禁用特定灯光
|
||||
current_energy = rp_light_object.energy
|
||||
if current_energy != 0.0:
|
||||
light_node.setTag("stored_energy", str(current_energy))
|
||||
elif light_node.hasTag("stored_energy"):
|
||||
stored_energy = float(light_node.getTag("stored_energy"))
|
||||
current_energy = stored_energy
|
||||
else:
|
||||
current_energy = 0.0
|
||||
rp_light_object.energy = 0.0
|
||||
print(f"已禁用灯光: {light_node.getName()}, 保存的能量={current_energy}")
|
||||
# render_pipeline.remove_light(rp_light_object)
|
||||
# print(f"已从渲染管线移除灯光: {light_node.getName()}")
|
||||
except Exception as e:
|
||||
print(f"操作RenderPipeline灯光时出错: {e}")
|
||||
|
||||
# 控制节点显示状态(可选,主要是视觉上的)
|
||||
if visible:
|
||||
light_node.show()
|
||||
else:
|
||||
light_node.hide()
|
||||
|
||||
print(f"灯光可见性设置完成: {visible}")
|
||||
except Exception as e:
|
||||
print(f"切换灯光可见性失败: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def _get_tree_widget(self):
|
||||
"""安全获取树形控件"""
|
||||
try:
|
||||
|
||||
@ -678,6 +678,7 @@ class PropertyPanelManager:
|
||||
self.active_check = QCheckBox()
|
||||
# 根据模型的实际可见性状态设置复选框
|
||||
self.active_check.setChecked(user_visible)
|
||||
self.active_check.stateChanged.connect(lambda state: self._toggleModelVisibility(model, state))
|
||||
self.name_input = QLineEdit(itemText)
|
||||
|
||||
self.name_input.returnPressed.connect(
|
||||
@ -690,14 +691,14 @@ class PropertyPanelManager:
|
||||
self.name_group.setLayout(name_layout)
|
||||
self._propertyLayout.addWidget(self.name_group)
|
||||
|
||||
if model:
|
||||
try:
|
||||
self.active_check.stateChanged.disconnect()
|
||||
except TypeError:
|
||||
pass
|
||||
self.active_check.stateChanged.connect(
|
||||
lambda state, m=model: self._setUserVisible(m, state == Qt.Checked)
|
||||
)
|
||||
# if model:
|
||||
# try:
|
||||
# self.active_check.stateChanged.disconnect()
|
||||
# except TypeError:
|
||||
# pass
|
||||
# self.active_check.stateChanged.connect(
|
||||
# lambda state, m=model: self._setUserVisible(m, state == Qt.Checked)
|
||||
# )
|
||||
# nameLabel = QLabel("名称:")
|
||||
# nameEdit = QLineEdit(itemText)
|
||||
# self._propertyLayout.addRow(nameLabel, nameEdit)
|
||||
@ -1136,6 +1137,15 @@ class PropertyPanelManager:
|
||||
node.setPythonTag("user_visible", visible)
|
||||
self._syncEffectiveVisibility(node)
|
||||
|
||||
def _setUserVisible_light(self, node, visible):
|
||||
"""设置用户可见性状态"""
|
||||
try:
|
||||
# 保存可见性状态
|
||||
node.setPythonTag("user_visible", visible)
|
||||
|
||||
except Exception as e:
|
||||
print(f"设置用户可见性失败: {e}")
|
||||
|
||||
def _syncEffectiveVisibility(self, start_node):
|
||||
"""广度优先,确保父隐藏则子一定隐藏"""
|
||||
# 获取起始节点的父节点
|
||||
@ -1171,19 +1181,52 @@ class PropertyPanelManager:
|
||||
for child in node.getChildren():
|
||||
q.append((child, eff))
|
||||
|
||||
# def _toggleModelVisibility(self, model, state):
|
||||
# """切换模型可见性状态"""
|
||||
# try:
|
||||
# visible = (state == Qt.Checked)
|
||||
# self._setUserVisible(model, visible)
|
||||
#
|
||||
# collision_nodes = model.findAllMatches("**/modelCollision_*")
|
||||
# for collision_node in collision_nodes:
|
||||
# collision_node.hide()
|
||||
#
|
||||
# except Exception as e:
|
||||
# print(f"切换模型可见性失败: {str(e)}")
|
||||
# import traceback
|
||||
# traceback.print_exc()
|
||||
|
||||
def _toggleModelVisibility(self, model, state):
|
||||
"""切换模型可见性状态"""
|
||||
try:
|
||||
# 用我们自己维护的可见性接口,而不是直接 show/hide
|
||||
visible = (state == Qt.Checked)
|
||||
self._setUserVisible(model, visible)
|
||||
|
||||
collision_nodes = model.findAllMatches("**/modelCollision_*")
|
||||
for collision_node in collision_nodes:
|
||||
collision_node.hide()
|
||||
|
||||
# 特殊处理灯光对象
|
||||
scene_manager = None
|
||||
if hasattr(self.world, 'scene_manager'):
|
||||
scene_manager = self.world.scene_manager
|
||||
|
||||
if scene_manager and hasattr(scene_manager, 'isLightObject'):
|
||||
is_light = scene_manager.isLightObject(model)
|
||||
|
||||
if is_light:
|
||||
visible = (state == Qt.Checked)
|
||||
self._setUserVisible_light(model, visible)
|
||||
if hasattr(scene_manager, 'toggleLightVisibility'):
|
||||
scene_manager.toggleLightVisibility(model, visible)
|
||||
return # 关键:这里必须return,避免执行下面的普通模型逻辑
|
||||
else:
|
||||
visible = (state == Qt.Checked)
|
||||
self._setUserVisible(model, visible)
|
||||
|
||||
collision_nodes = model.findAllMatches("**/modelCollision_*")
|
||||
for collision_node in collision_nodes:
|
||||
collision_node.hide()
|
||||
|
||||
except Exception as e:
|
||||
print(f"切换模型可见性失败: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def refreshModelValues(self, nodePath):
|
||||
"""刷新模型值显示"""
|
||||
@ -5502,11 +5545,22 @@ class PropertyPanelManager:
|
||||
light_group = QGroupBox("光源属性")
|
||||
light_layout = QGridLayout()
|
||||
|
||||
current_energy = light_object.energy
|
||||
stored_energy = None
|
||||
|
||||
if current_energy == 0.0 and model.hasTag("stored_energy"):
|
||||
try:
|
||||
stored_energy = float(model.getTag("stored_energy"))
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
display_energy = stored_energy if stored_energy is not None and stored_energy > 0 else current_energy
|
||||
|
||||
# 能量
|
||||
light_layout.addWidget(QLabel("能量:"), 0, 0)
|
||||
energySpinBox = QDoubleSpinBox()
|
||||
energySpinBox.setRange(0, 10000)
|
||||
energySpinBox.setValue(light_object.energy)
|
||||
energySpinBox.setValue(display_energy)
|
||||
energySpinBox.valueChanged.connect(lambda v: self._updateLightEnergy(light_object, v))
|
||||
light_layout.addWidget(energySpinBox, 0, 1, 1, 3)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user