diff --git a/core/vr_manager.py b/core/vr_manager.py index 07c4e778..daa2b300 100644 --- a/core/vr_manager.py +++ b/core/vr_manager.py @@ -3061,6 +3061,46 @@ class VRManager(DirectObject): if self.optimization: self.optimization.performance_mode_trigger_frame = value + # GC控制属性代理 - 修复'gc_control_enabled'属性访问问题 + @property + def _gc_control_enabled(self): + """GC控制启用状态 - 代理到优化模块""" + if self.optimization: + return self.optimization._gc_control_enabled + return True + + @_gc_control_enabled.setter + def _gc_control_enabled(self, value): + """GC控制启用状态设置 - 代理到优化模块""" + if self.optimization: + self.optimization._gc_control_enabled = value + + @property + def _gc_disabled(self): + """GC禁用状态 - 代理到优化模块""" + if self.optimization: + return self.optimization._gc_disabled + return False + + @_gc_disabled.setter + def _gc_disabled(self, value): + """GC禁用状态设置 - 代理到优化模块""" + if self.optimization: + self.optimization._gc_disabled = value + + @property + def _manual_gc_interval(self): + """手动GC间隔 - 代理到优化模块""" + if self.optimization: + return self.optimization._manual_gc_interval + return 900 + + @_manual_gc_interval.setter + def _manual_gc_interval(self, value): + """手动GC间隔设置 - 代理到优化模块""" + if self.optimization: + self.optimization._manual_gc_interval = value + # 分辨率缩放属性代理 @property def resolution_scale(self): diff --git a/ui/main_window.py b/ui/main_window.py index 594ab9eb..11d0c64e 100644 --- a/ui/main_window.py +++ b/ui/main_window.py @@ -3568,22 +3568,37 @@ class MainWindow(QMainWindow): if hasattr(self.world,'gui_manager') and self.world.gui_manager: self.world.gui_manager.createCesiumView() else: - QMessageBox.warning(self,"错误","GUI管理其不可用") - + UniversalMessageDialog.show_warning( + self, + "错误", + "GUI管理器不可用", + show_cancel=False, + confirm_text="确认" + ) def onToggleCesiumView(self): """切换 Cesium 视图显示状态""" if hasattr(self.world, 'gui_manager') and self.world.gui_manager: self.world.gui_manager.toggleCesiumView() else: - QMessageBox.warning(self, "错误", "GUI 管理器不可用") - + UniversalMessageDialog.show_warning( + self, + "错误", + "GUI 管理器不可用", + show_cancel=False, + confirm_text="确认" + ) def onRefreshCesiumView(self): """刷新 Cesium 视图""" if hasattr(self.world, 'gui_manager') and self.world.gui_manager: self.world.gui_manager.refreshCesiumView() else: - QMessageBox.warning(self, "错误", "GUI 管理器不可用") - + UniversalMessageDialog.show_warning( + self, + "错误", + "GUI 管理器不可用", + show_cancel=False, + confirm_text="确认" + ) def onUpdateCesiumURL(self): """更新 Cesium URL""" dialog = self.createStyledInputDialog( @@ -3599,7 +3614,13 @@ class MainWindow(QMainWindow): if hasattr(self.world, 'gui_manager') and self.world.gui_manager: self.world.gui_manager.updateCesiumURL(url) else: - QMessageBox.warning(self, "错误", "GUI 管理器不可用") + UniversalMessageDialog.show_warning( + self, + "错误", + "GUI 管理器不可用", + show_cancel=False, + confirm_text="确认" + ) def onAddModelClicked(self): @@ -4030,7 +4051,7 @@ class MainWindow(QMainWindow): print(f"✗ 创建3D示例天气信息面板失败: {e}") import traceback traceback.print_exc() - QMessageBox.critical(self, "错误", f"创建3D示例天气信息面板时出错: {str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"创建3D示例天气信息面板时出错: {str(e)}") # 更新 addInfoPanelToTree 方法以支持3D面板 def addInfoPanelToTree(self, panel, panel_name): @@ -4107,7 +4128,7 @@ class MainWindow(QMainWindow): print(f"✗ 创建系统状态信息面板失败: {e}") import traceback traceback.print_exc() - QMessageBox.critical(self, "错误", f"创建系统状态信息面板时出错: {str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"创建系统状态信息面板时出错: {str(e)}") def getSystemStatusData(self): """ @@ -4184,7 +4205,7 @@ class MainWindow(QMainWindow): print(f"✗ 创建传感器数据信息面板失败: {e}") import traceback traceback.print_exc() - QMessageBox.critical(self, "错误", f"创建传感器数据信息面板时出错: {str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"创建传感器数据信息面板时出错: {str(e)}") def getSensorData(self): """ @@ -4248,7 +4269,7 @@ class MainWindow(QMainWindow): print(f"✗ 创建场景信息面板失败: {e}") import traceback traceback.print_exc() - QMessageBox.critical(self, "错误", f"创建场景信息面板时出错: {str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"创建场景信息面板时出错: {str(e)}") def getSceneInfoData(self): """ @@ -4695,7 +4716,7 @@ class MainWindow(QMainWindow): print("🎨 图标管理器已打开") except Exception as e: print(f"❌ 打开图标管理器失败: {e}") - QMessageBox.warning(self, "错误", f"打开图标管理器失败:\n{str(e)}") + UniversalMessageDialog.show_warning(self, "警告", f"打开图标管理器失败: {str(e)}", show_cancel=False, confirm_text="确认") def closeEvent(self, event): """处理窗口关闭事件""" @@ -4886,7 +4907,7 @@ class MainWindow(QMainWindow): config_dialog = AssemblyDisassemblyConfigDialog(self, self.world) config_dialog.show() except Exception as e: - QMessageBox.critical(self, "错误", f"打开拆装配置界面失败: {str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"打开拆装配置界面失败: {str(e)}") import traceback traceback.print_exc() @@ -4911,7 +4932,7 @@ class MainWindow(QMainWindow): self.world.assembly_interaction.start_interaction_mode(mode=selected_mode) except Exception as e: - QMessageBox.critical(self, "错误", f"启动拆装交互失败: {str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"启动拆装交互失败: {str(e)}") import traceback traceback.print_exc() @@ -4966,11 +4987,11 @@ class MainWindow(QMainWindow): print(f"✅ 维修科目启动成功") else: print("❌ 维修科目启动失败") - QMessageBox.warning(self, "错误", "维修科目启动失败") + UniversalMessageDialog.show_warning(self, "错误", "维修科目启动失败",False,"确认") except Exception as e: print(f"❌ 启动维修科目失败: {e}") - QMessageBox.critical(self, "错误", f"启动维修科目失败:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"启动维修科目失败: {str(e)}") import traceback traceback.print_exc() @@ -4982,7 +5003,7 @@ class MainWindow(QMainWindow): except Exception as e: print(f"❌ 打开维修系统失败: {e}") - QMessageBox.critical(self, "错误", f"打开维修系统失败:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"打开维修系统失败: {str(e)}") import traceback traceback.print_exc() @@ -4999,14 +5020,21 @@ class MainWindow(QMainWindow): # 更新菜单状态 self.enterVRAction.setEnabled(False) self.exitVRAction.setEnabled(True) - QMessageBox.information(self, "成功", "VR模式已启用!\n请确保您的VR头显已正确连接。") + UniversalMessageDialog.show_info( + self, "成功", "VR模式已启用!\n请确保您的VR头显已正确连接。" + , False, "确认") else: - QMessageBox.warning(self, "错误", "无法启用VR模式!\n请检查:\n1. SteamVR是否正在运行\n2. VR头显是否已连接\n3. OpenVR库是否已正确安装") + UniversalMessageDialog.show_warning( + self, "错误", "无法启用VR模式!\n请检查:\n1. SteamVR是否正在运行\n2. VR头显是否已连接\n3. OpenVR库是否已正确安装" + , False, "确认") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning( + self, "错误", "VR管理器不可用!" + , False, "确认") except Exception as e: - QMessageBox.critical(self, "错误", f"启用VR模式时发生错误:\n{str(e)}") - + UniversalMessageDialog.show_error( + self, "错误", f"启用VR模式时发生错误:\n{str(e)}" + , False, "确认") def onExitVR(self): """退出VR模式""" try: @@ -5015,11 +5043,14 @@ class MainWindow(QMainWindow): # 更新菜单状态 self.enterVRAction.setEnabled(True) self.exitVRAction.setEnabled(False) - QMessageBox.information(self, "成功", "已退出VR模式") + UniversalMessageDialog.show_info(self, "成功", "已退出VR模式" + , False, "确认") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!" + , False, "确认") except Exception as e: - QMessageBox.critical(self, "错误", f"退出VR模式时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"退出VR模式时发生错误:\n{str(e)}" + , False, "确认") def onShowVRStatus(self): """显示VR状态""" @@ -5039,12 +5070,14 @@ class MainWindow(QMainWindow): - 如果VR不可用,请确保已安装SteamVR并连接VR头显 - 如果OpenVR库未安装,请运行:pip install openvr """ - - QMessageBox.information(self, "VR状态", status_text) + UniversalMessageDialog.show_info(self, "VR状态", status_text + , False, "确认") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!" + , False, "确认") except Exception as e: - QMessageBox.critical(self, "错误", f"获取VR状态时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"获取VR状态时发生错误:\n{str(e)}" + , False, "确认") def onShowVRSettings(self): """显示VR设置对话框""" @@ -5053,149 +5086,301 @@ class MainWindow(QMainWindow): dialog = self.createVRSettingsDialog() dialog.exec_() else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!" + , False, "确认") except Exception as e: - QMessageBox.critical(self, "错误", f"打开VR设置时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"打开VR设置时发生错误:\n{str(e)}" + , False, "确认") def createVRSettingsDialog(self): - """创建VR设置对话框""" + """创建VR设置对话框(统一为 NewProjectDialog 风格)""" dialog = QDialog(self) dialog.setWindowTitle("VR设置") dialog.setModal(True) - dialog.resize(400, 300) + dialog.resize(508, 420) + dialog.setObjectName("newProjectDialog") + dialog.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint) + dialog.setAttribute(Qt.WA_TranslucentBackground, True) - layout = QVBoxLayout(dialog) + dialog.setStyleSheet(""" + QDialog#newProjectDialog { background-color: transparent; color: #EBEBEB; border: none; } + QFrame#baseFrame { background-color: #000000; border: 1px solid #3E3E42; border-radius: 5px; } + QWidget#titleBar { background-color: transparent; border: none; border-radius: 5px 5px 0 0; min-height: 32px; max-height: 32px; } + QWidget#titleBar QWidget { background-color: transparent; border: none; } + QLabel#titleLabel { color: #FFFFFF; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 14px; font-weight: 500; letter-spacing: 0.7px; } + QWidget#controlButtons QPushButton { background-color: transparent; border: none; color: #EBEBEB; font-size: 14px; min-width: 18px; max-width: 18px; min-height: 18px; max-height: 18px; padding: 0px; border-radius: 3px; } + QWidget#controlButtons QPushButton:hover { background-color: #2A2D2E; color: #FFFFFF; } + QPushButton#closeButton { border-radius: 0px 5px 0px 0px; } + QPushButton#closeButton:hover { background-color: #2A2D2E; color: #FFFFFF; } + QWidget#contentWidget { background-color: transparent; border-radius: 0 0 5px 5px; } + QFrame#contentContainer { background-color: #19191B; border: 1px solid #2C2F36; border-radius: 5px; } + QLabel[role="sectionTitle"] { color: #EBEBEB; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 12px; font-weight: 500; letter-spacing: 0.6px; } + QLabel[role="fieldLabel"] { color: #EBEBEB; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 12px; font-weight: 400; letter-spacing: 0.6px; } + QLabel { color: #EBEBEB; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 11px; font-weight: 300; letter-spacing: 0.55px; } + QComboBox, QSpinBox, QDoubleSpinBox { color: #EBEBEB; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 11px; font-weight: 300; } + QCheckBox { color: #EBEBEB; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 11px; font-weight: 300; } + QLineEdit { background-color: rgba(89,100,113,0.2); color: #EBEBEB; border: 1px solid rgba(76,92,110,0.6); border-radius: 2px; padding: 6px 10px; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 11px; font-weight: 300; letter-spacing: 0.55px; min-height: 14px; max-height: 30px; } + QLineEdit:focus { border: 1px solid #3067C0; background-color: rgba(48,103,192,0.1); } + QLineEdit:hover { border: 1px solid #3067C0; background-color: rgba(89,100,113,0.3); } + QLineEdit:disabled { background-color: rgba(89,100,113,0.1); color: rgba(235,235,235,0.4); border: 1px solid rgba(76,92,110,0.2); } + QTextEdit { background-color: rgba(89,100,113,0.1); color: #EBEBEB; border: 1px solid rgba(76,92,110,0.4); border-radius: 4px; font-size: 11px; } + QPushButton { background-color: rgba(89,98,118,0.5); color: #EBEBEB; border: none; border-radius: 2px; padding: 0px 0px; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-weight: 300; font-size: 10px; letter-spacing: 0.5px; min-width: 90px; min-height: 30px; max-height: 30px; } + QPushButton:hover { background-color: #3067C0; color: #FFFFFF; } + QPushButton:pressed { background-color: #2556A0; color: #FFFFFF; } + QPushButton:disabled { background-color: rgba(89,98,118,0.3); color: rgba(235,235,235,0.4); } + QPushButton#primaryButton { background-color: rgba(89,98,118,0.5); border: none; color: #EBEBEB; font-weight: 300; min-width: 120px; max-width: 120px; } + QPushButton#primaryButton:hover { background-color: #2556A0; } + QPushButton#primaryButton:pressed { background-color: #1E4A8C; } + """) - # VR状态显示 - status_group = QGroupBox("VR状态") - status_layout = QVBoxLayout() + main_layout = QVBoxLayout(dialog) + main_layout.setContentsMargins(0, 0, 0, 0) + main_layout.setSpacing(0) + base_frame = QFrame() + base_frame.setObjectName('baseFrame') + base_frame.setFrameShape(QFrame.NoFrame) + base_frame.setAttribute(Qt.WA_StyledBackground, True) + base_layout = QVBoxLayout(base_frame) + base_layout.setContentsMargins(0, 0, 0, 0) + base_layout.setSpacing(0) + + # Title bar + title_bar = QWidget() + title_bar.setObjectName('titleBar') + tb_layout = QHBoxLayout(title_bar) + tb_layout.setContentsMargins(8, 0, 8, 0) + tb_layout.setSpacing(6) + control_buttons = QWidget() + control_buttons.setObjectName('controlButtons') + cb_layout = QHBoxLayout(control_buttons) + cb_layout.setContentsMargins(0, 0, 0, 0) + cb_layout.setSpacing(0) + close_btn = QPushButton() + close_btn.setObjectName('closeButton') + try: + close_btn.setIcon(get_icon('close_icon', QSize(18, 18))) + close_btn.setIconSize(QSize(18, 18)) + except Exception: + pass + close_btn.clicked.connect(dialog.reject) + cb_layout.addWidget(close_btn) + left_placeholder = QWidget() + left_placeholder.setFixedWidth(control_buttons.sizeHint().width()) + tb_layout.addWidget(left_placeholder) + title_label = QLabel("VR设置") + title_label.setObjectName('titleLabel') + title_label.setAlignment(Qt.AlignCenter) + tb_layout.addWidget(title_label, 1) + tb_layout.addWidget(control_buttons) + base_layout.addWidget(title_bar) + + # drag handlers + dragging_state = {'dragging': False, 'pos': QPoint()} + def _tb_press(event): + if event.button() == Qt.LeftButton: + dragging_state['dragging'] = True + dragging_state['pos'] = event.globalPos() - dialog.frameGeometry().topLeft() + event.accept() + else: + event.ignore() + def _tb_move(event): + if event.buttons() & Qt.LeftButton and dragging_state['dragging']: + dialog.move(event.globalPos() - dragging_state['pos']) + event.accept() + else: + event.ignore() + def _tb_release(event): + if event.button() == Qt.LeftButton: + dragging_state['dragging'] = False + event.accept() + else: + event.ignore() + title_bar.mousePressEvent = _tb_press + title_bar.mouseMoveEvent = _tb_move + title_bar.mouseReleaseEvent = _tb_release + + # Content + content_widget = QWidget() + content_widget.setObjectName('contentWidget') + content_layout = QVBoxLayout(content_widget) + content_layout.setContentsMargins(10, 10, 10, 10) + content_layout.setSpacing(0) + + content_container = QFrame() + content_container.setObjectName('contentContainer') + content_container.setFrameShape(QFrame.NoFrame) + content_container.setAttribute(Qt.WA_StyledBackground, True) + container_layout = QVBoxLayout(content_container) + container_layout.setContentsMargins(15, 10, 15, 10) + container_layout.setSpacing(10) + + # 左侧对齐辅助:统一字段列宽,并让小标题与控件左侧对齐 + label_column_width = 110 + def add_section_title(text): + title = QLabel(text) + title.setProperty('role', 'sectionTitle') + container_layout.addWidget(title) + + # VR 状态 + add_section_title("VR状态") + status_widget = QWidget() + status_vlayout = QVBoxLayout(status_widget) + status_vlayout.setContentsMargins(0, 0, 0, 0) + status_vlayout.setSpacing(6) if hasattr(self.world, 'vr_manager') and self.world.vr_manager: status = self.world.vr_manager.get_vr_status() - available_label = QLabel(f"VR可用性: {'是' if status['available'] else '否'}") - available_label.setStyleSheet(f"color: {'green' if status['available'] else 'red'};") - status_layout.addWidget(available_label) - + available_label.setStyleSheet(f"color: {'#2dffc4' if status['available'] else 'red'};") + status_vlayout.addWidget(available_label) enabled_label = QLabel(f"VR状态: {'已启用' if status['enabled'] else '未启用'}") - enabled_label.setStyleSheet(f"color: {'green' if status['enabled'] else 'gray'};") - status_layout.addWidget(enabled_label) - + enabled_label.setStyleSheet(f"color: {'#2dffc4' if status['enabled'] else 'gray'};") + status_vlayout.addWidget(enabled_label) resolution_label = QLabel(f"渲染分辨率: {status['eye_resolution'][0]}x{status['eye_resolution'][1]}") - status_layout.addWidget(resolution_label) + status_vlayout.addWidget(resolution_label) + container_layout.addWidget(status_widget) - status_group.setLayout(status_layout) - layout.addWidget(status_group) - - # 🎨 渲染模式设置 - render_mode_group = QGroupBox("渲染模式") - render_mode_layout = QVBoxLayout() - - # 创建单选按钮组 + # 渲染模式 + add_section_title("渲染模式") render_mode_button_group = QButtonGroup(dialog) - + row_mode1 = QWidget(); row_mode1_layout = QHBoxLayout(row_mode1); row_mode1_layout.setContentsMargins(0,0,0,0); row_mode1_layout.setSpacing(10) normal_render_radio = QRadioButton("普通渲染模式") + normal_render_radio.setStyleSheet(""" + QRadioButton { + color: #EBEBEB; + font-family: 'Inter', 'Microsoft YaHei', sans-serif; + font-size: 12px; + font-weight: 400; + letter-spacing: 0.6px; + } + """) + row_mode1_layout.addWidget(normal_render_radio) + row_mode1_layout.addStretch(); container_layout.addWidget(row_mode1) + row_mode2 = QWidget(); row_mode2_layout = QHBoxLayout(row_mode2); row_mode2_layout.setContentsMargins(0,0,0,0); row_mode2_layout.setSpacing(10) pipeline_render_radio = QRadioButton("RenderPipeline高级渲染(推荐)") - + pipeline_render_radio.setStyleSheet(""" + QRadioButton { + color: #EBEBEB; + font-family: 'Inter', 'Microsoft YaHei', sans-serif; + font-size: 12px; + font-weight: 400; + letter-spacing: 0.6px; + } + """) + row_mode2_layout.addWidget(pipeline_render_radio) + row_mode2_layout.addStretch(); container_layout.addWidget(row_mode2) render_mode_button_group.addButton(normal_render_radio, 0) render_mode_button_group.addButton(pipeline_render_radio, 1) - - # 根据当前模式设置选中状态 if hasattr(self.world, 'vr_manager') and self.world.vr_manager: - from core.vr import VRRenderMode - current_mode = self.world.vr_manager.get_vr_render_mode() - if current_mode == VRRenderMode.RENDER_PIPELINE: - pipeline_render_radio.setChecked(True) - else: + try: + from core.vr import VRRenderMode + current_mode = self.world.vr_manager.get_vr_render_mode() + if current_mode == VRRenderMode.RENDER_PIPELINE: + pipeline_render_radio.setChecked(True) + else: + normal_render_radio.setChecked(True) + except Exception: normal_render_radio.setChecked(True) else: normal_render_radio.setChecked(True) - - render_mode_layout.addWidget(normal_render_radio) - render_mode_layout.addWidget(pipeline_render_radio) - - # 添加说明文本 info_text = QTextEdit() info_text.setReadOnly(True) info_text.setMaximumHeight(60) - info_text.setPlainText( - "• 普通渲染:性能最优,适合低配置\n" - "• RenderPipeline:高级图形效果(阴影、AO等),需要较高性能" - ) - render_mode_layout.addWidget(info_text) - - render_mode_group.setLayout(render_mode_layout) - layout.addWidget(render_mode_group) - - # 保存按钮组引用以便后续使用 + info_text.setPlainText("• 普通渲染:性能最优,适合低配置\n• RenderPipeline:高级图形效果(阴影、AO等),需要较高性能") + container_layout.addWidget(info_text) dialog.render_mode_button_group = render_mode_button_group - # 🔧 加载配置 + # 载入配置 vr_config = {} if hasattr(self.world, 'vr_manager') and self.world.vr_manager and self.world.vr_manager.config_manager: vr_config = self.world.vr_manager.config_manager.load_config() # 渲染设置 - render_group = QGroupBox("渲染设置") - render_layout = QFormLayout() - - # 渲染质量 + add_section_title("渲染设置") + row_quality = QWidget() + row_quality_layout = QHBoxLayout(row_quality) + row_quality_layout.setContentsMargins(0,0,0,0) + row_quality_layout.setSpacing(10) + quality_label = QLabel("渲染质量:") + quality_label.setProperty('role','fieldLabel') + quality_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) + row_quality_layout.addWidget(quality_label) quality_combo = QComboBox() - quality_combo.addItems(["低", "中", "高"]) - # 从配置加载质量预设 + quality_combo.addItems(["低","中","高"]) quality_preset = vr_config.get("quality_preset", "balanced") - quality_map = {"performance": "低", "balanced": "中", "quality": "高"} - quality_combo.setCurrentText(quality_map.get(quality_preset, "中")) - render_layout.addRow("渲染质量:", quality_combo) - - # 抗锯齿 + quality_map={"performance":"低","balanced":"中","quality":"高"} + quality_combo.setCurrentText(quality_map.get(quality_preset,"中")) + row_quality_layout.addWidget(quality_combo,1) + container_layout.addWidget(row_quality) + row_aa = QWidget(); row_aa_layout = QHBoxLayout(row_aa) + row_aa_layout.setContentsMargins(0,0,0,0) + row_aa_layout.setSpacing(10) + aa_label = QLabel("抗锯齿:") + aa_label.setProperty('role','fieldLabel') + aa_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) + row_aa_layout.addWidget(aa_label) aa_combo = QComboBox() - aa_combo.addItems(["无", "2x", "4x", "8x"]) - aa_combo.setCurrentText(vr_config.get("anti_aliasing", "4x")) - render_layout.addRow("抗锯齿:", aa_combo) - - render_group.setLayout(render_layout) - layout.addWidget(render_group) + aa_combo.addItems(["无","2x","4x","8x"]) + aa_combo.setCurrentText(vr_config.get("anti_aliasing","4x")) + row_aa_layout.addWidget(aa_combo,1) + container_layout.addWidget(row_aa) # 性能设置 - perf_group = QGroupBox("性能设置") - perf_layout = QFormLayout() - - # 刷新率 + add_section_title("性能设置") + row_refresh = QWidget() + row_refresh_layout = QHBoxLayout(row_refresh) + row_refresh_layout.setContentsMargins(0,0,0,0) + row_refresh_layout.setSpacing(10) + refresh_label = QLabel("刷新率:") + refresh_label.setProperty('role','fieldLabel') + refresh_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) + row_refresh_layout.addWidget(refresh_label) refresh_combo = QComboBox() - refresh_combo.addItems(["72Hz", "90Hz", "120Hz", "144Hz"]) - refresh_combo.setCurrentText(vr_config.get("refresh_rate", "90Hz")) - perf_layout.addRow("刷新率:", refresh_combo) - - # 异步重投影 + refresh_combo.addItems(["72Hz","90Hz","120Hz","144Hz"]) + refresh_combo.setCurrentText(vr_config.get("refresh_rate","90Hz")) + row_refresh_layout.addWidget(refresh_combo,1) + container_layout.addWidget(row_refresh) + row_async = QWidget() + row_async_layout = QHBoxLayout(row_async) + row_async_layout.setContentsMargins(0,0,0,0) + row_async_layout.setSpacing(10) async_check = QCheckBox("启用异步重投影") - async_check.setChecked(vr_config.get("async_reprojection", True)) - perf_layout.addRow("", async_check) + async_check.setChecked(vr_config.get("async_reprojection",True)) + row_async_layout.addWidget(async_check) + row_async_layout.addStretch() + container_layout.addWidget(row_async) - perf_group.setLayout(perf_layout) - layout.addWidget(perf_group) - - # 保存控件引用到dialog对象 + # Save refs dialog.quality_combo = quality_combo dialog.aa_combo = aa_combo dialog.refresh_combo = refresh_combo dialog.async_check = async_check - # 按钮 - button_layout = QHBoxLayout() + # Separator before buttons + separator_buttons = QFrame() + separator_buttons.setFrameShape(QFrame.HLine) + separator_buttons.setFrameShadow(QFrame.Plain) + separator_buttons.setFixedHeight(1) + separator_buttons.setStyleSheet("background-color: #2C2F36; border: none;") + container_layout.addWidget(separator_buttons) + # Buttons + button_layout = QHBoxLayout() apply_button = QPushButton("应用") ok_button = QPushButton("确定") + # ok_button.setObjectName("primaryButton") cancel_button = QPushButton("取消") - button_layout.addWidget(apply_button) button_layout.addStretch() button_layout.addWidget(ok_button) button_layout.addWidget(cancel_button) + container_layout.addLayout(button_layout) - layout.addLayout(button_layout) + content_layout.addWidget(content_container, 0, Qt.AlignTop) + base_layout.addWidget(content_widget) + main_layout.addWidget(base_frame) - # 连接信号 + # signals apply_button.clicked.connect(lambda: self.applyVRSettings(dialog)) ok_button.clicked.connect(lambda: self.onVRSettingsOK(dialog)) cancel_button.clicked.connect(dialog.reject) @@ -5213,11 +5398,11 @@ class MainWindow(QMainWindow): """应用VR设置""" try: if not hasattr(self.world, 'vr_manager') or not self.world.vr_manager: - QMessageBox.warning(dialog, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(dialog, "错误", "VR管理器不可用!",False,"确定") return if not self.world.vr_manager.config_manager: - QMessageBox.warning(dialog, "错误", "VR配置管理器不可用!") + UniversalMessageDialog.show_warning(dialog, "错误", "VR配置管理器不可用!",False,"确定") return # 1️⃣ 读取所有UI控件的值 @@ -5252,25 +5437,21 @@ class MainWindow(QMainWindow): # 5️⃣ 如果渲染模式改变,询问用户确认 if mode_changed: - reply = QMessageBox.question( - dialog, - "确认切换", - f"确定要切换到{mode_name}模式吗?\n\n注意:切换渲染模式将重新创建VR缓冲区,可能需要几秒钟。", - QMessageBox.Yes | QMessageBox.No, - QMessageBox.No - ) + reply = UniversalMessageDialog.show_info(dialog, "确认切换", f"确定要切换到{mode_name}模式吗?\n\n注意:切换渲染模式将重新创建VR缓冲区,可能需要几秒钟。",True,"取消","确定") - if reply == QMessageBox.No: + if reply == QDialog.Rejected: # 用户取消渲染模式切换,但仍然保存其他设置 self.world.vr_manager.config_manager.save_config(config) - QMessageBox.information(dialog, "提示", "已保存其他设置(未切换渲染模式)") + UniversalMessageDialog.show_info(dialog, "提示", "已保存其他设置(未切换渲染模式)", + False, "确定") return # 应用渲染模式切换 success = self.world.vr_manager.set_vr_render_mode(new_mode) if not success: - QMessageBox.warning(dialog, "失败", f"切换到{mode_name}模式失败!\n请查看控制台输出了解详情。") + UniversalMessageDialog.show_warning(dialog, "失败", f"切换到{mode_name}模式失败!\n请查看控制台输出了解详情。", + False, "确定") return # 6️⃣ 保存配置(如果模式改变,set_vr_render_mode已经保存了,但我们需要确保其他设置也被保存) @@ -5282,12 +5463,15 @@ class MainWindow(QMainWindow): # 8️⃣ 显示成功消息 if mode_changed: - QMessageBox.information(dialog, "成功", f"VR设置已应用!\n• 渲染模式: {mode_name}\n• 渲染质量: {quality_text}\n配置已自动保存。") + UniversalMessageDialog.show_info(dialog, "成功", f"VR设置已应用!\n• 渲染模式: {mode_name}\n• 渲染质量: {quality_text}\n配置已自动保存。", + False, "确定") else: - QMessageBox.information(dialog, "成功", f"VR设置已保存!\n• 渲染质量: {quality_text}") + UniversalMessageDialog.show_info(dialog, "成功", f"VR设置已保存!\n• 渲染质量: {quality_text}", + False, "确定") except Exception as e: - QMessageBox.critical(dialog, "错误", f"应用VR设置时发生错误:\n{str(e)}") + UniversalMessageDialog.show_critical(dialog, "错误", f"应用VR设置时发生错误:\n{str(e)}", + False, "确定") import traceback traceback.print_exc() @@ -5301,11 +5485,14 @@ class MainWindow(QMainWindow): self.vrDebugToggleAction.setChecked(enabled) status = "启用" if enabled else "禁用" - QMessageBox.information(self, "VR调试", f"VR调试输出已{status}") + UniversalMessageDialog.show_info(self, "提示", f"已{status}VR调试输出", + False, "确定") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!", + False, "确定") except Exception as e: - QMessageBox.critical(self, "错误", f"切换VR调试时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"切换VR调试时发生错误:\n{str(e)}", + False, "确定") def onShowVRPerformance(self): """立即显示VR性能报告""" @@ -5313,13 +5500,17 @@ class MainWindow(QMainWindow): if hasattr(self.world, 'vr_manager') and self.world.vr_manager: if self.world.vr_manager.vr_enabled: self.world.vr_manager.force_performance_report() - QMessageBox.information(self, "VR性能", "性能报告已输出到控制台") + UniversalMessageDialog.show_info(self, "提示", "已立即显示VR性能报告", + False, "确定") else: - QMessageBox.warning(self, "提示", "请先启用VR模式") + UniversalMessageDialog.show_warning(self, "提示", "请先启用VR模式", + False, "确定") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!", + False, "确定") except Exception as e: - QMessageBox.critical(self, "错误", f"显示VR性能报告时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"显示VR性能报告时发生错误:\n{str(e)}", + False, "确定") def onSetVRDebugMode(self, mode): """设置VR调试模式""" @@ -5336,11 +5527,14 @@ class MainWindow(QMainWindow): self.vrDebugDetailedAction.setChecked(True) mode_name = "简短" if mode == 'brief' else "详细" - QMessageBox.information(self, "VR调试", f"调试模式已设置为:{mode_name}") + UniversalMessageDialog.show_info(self, "提示", f"已设置VR调试模式为:{mode_name}", + False, "确定") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!", + False, "确定") except Exception as e: - QMessageBox.critical(self, "错误", f"设置VR调试模式时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"设置VR调试模式时发生错误:\n{str(e)}", + False, "确定") def onToggleVRPerformanceMonitor(self): """切换VR性能监控""" @@ -5353,12 +5547,15 @@ class MainWindow(QMainWindow): self.world.vr_manager.disable_performance_monitoring() status = "启用" if enabled else "禁用" - QMessageBox.information(self, "VR性能监控", f"VR性能监控已{status}") + UniversalMessageDialog.show_info(self, "提示", f"已{status}VR性能监控", + False, "确定") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!", + False, "确定") self.vrPerformanceMonitorAction.setChecked(False) except Exception as e: - QMessageBox.critical(self, "错误", f"切换VR性能监控时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"切换VR性能监控时发生错误:\n{str(e)}", + False, "确定") def onToggleVRGpuTiming(self): """切换VR GPU时间监控""" @@ -5371,12 +5568,15 @@ class MainWindow(QMainWindow): self.world.vr_manager.disable_gpu_timing_monitoring() status = "启用" if enabled else "禁用" - QMessageBox.information(self, "VR GPU监控", f"VR GPU时间监控已{status}") + UniversalMessageDialog.show_info(self, "提示", f"已{status}VR GPU时间监控", + False, "确定") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!", + False, "确定") self.vrGpuTimingAction.setChecked(False) except Exception as e: - QMessageBox.critical(self, "错误", f"切换VR GPU时间监控时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"切换VR GPU时间监控时发生错误:\n{str(e)}", + False, "确定") def onToggleVRPipelineMonitor(self): """切换VR管线监控""" @@ -5387,10 +5587,12 @@ class MainWindow(QMainWindow): status = "启用" if enabled else "禁用" print(f"✓ VR管线监控已{status}") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!", + False, "确定") self.vrPipelineMonitorAction.setChecked(False) except Exception as e: - QMessageBox.critical(self, "错误", f"切换VR管线监控时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"切换VR管线监控时发生错误:\n{str(e)}", + False, "确定") def onSetVRPoseStrategy(self, strategy): """设置VR姿态策略""" @@ -5402,25 +5604,31 @@ class MainWindow(QMainWindow): 'render_callback': '渲染回调策略', 'update_task': '更新任务策略' } - QMessageBox.information(self, "VR姿态策略", - f"姿态策略已切换为:{strategy_names.get(strategy, strategy)}") + UniversalMessageDialog.show_info(self, "提示", f"已设置VR姿态策略为:{strategy_names.get(strategy, strategy)}", + False, "确定") else: - QMessageBox.warning(self, "错误", f"无效的姿态策略:{strategy}") + UniversalMessageDialog.show_warning(self, "错误", "设置VR姿态策略失败!", + False, "确定") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!", + False, "确定") except Exception as e: - QMessageBox.critical(self, "错误", f"设置VR姿态策略时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"设置VR姿态策略时发生错误:\n{str(e)}", + False, "确定") def onTestVRPipeline(self): """测试VR管线监控功能""" try: if hasattr(self.world, 'vr_manager') and self.world.vr_manager: self.world.vr_manager.test_pipeline_monitoring() - QMessageBox.information(self, "VR管线测试", "管线监控测试已完成,请查看控制台输出。") + UniversalMessageDialog.show_info(self, "提示", "VR管线监控测试已开始,请稍等...", + False, "确定") else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!", + False, "确定") except Exception as e: - QMessageBox.critical(self, "错误", f"测试VR管线监控时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"测试VR管线监控时发生错误:\n{str(e)}", + False, "确定") def onShowVRDebugSettings(self): """显示VR调试设置对话框""" @@ -5429,68 +5637,184 @@ class MainWindow(QMainWindow): dialog = self.createVRDebugSettingsDialog() dialog.exec_() else: - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!", + False, "确定") except Exception as e: - QMessageBox.critical(self, "错误", f"打开VR调试设置时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"打开VR调试设置时发生错误:\n{str(e)}", + False, "确定") def createVRDebugSettingsDialog(self): - """创建VR调试设置对话框""" + """创建VR调试设置对话框(统一为 NewProjectDialog 风格)""" from PyQt5.QtWidgets import QCheckBox, QSlider from PyQt5.QtCore import Qt dialog = QDialog(self) dialog.setWindowTitle("VR调试设置") dialog.setModal(True) - dialog.resize(450, 400) + dialog.resize(508, 460) + dialog.setObjectName("newProjectDialog") + dialog.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint) + dialog.setAttribute(Qt.WA_TranslucentBackground, True) - layout = QVBoxLayout(dialog) + dialog.setStyleSheet(""" + QDialog#newProjectDialog { background-color: transparent; color: #EBEBEB; border: none; } + QFrame#baseFrame { background-color: #000000; border: 1px solid #3E3E42; border-radius: 5px; } + QWidget#titleBar { background-color: transparent; border: none; border-radius: 5px 5px 0 0; min-height: 32px; max-height: 32px; } + QWidget#titleBar QWidget { background-color: transparent; border: none; } + QLabel#titleLabel { color: #FFFFFF; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 14px; font-weight: 500; letter-spacing: 0.7px; } + QWidget#controlButtons QPushButton { background-color: transparent; border: none; color: #EBEBEB; font-size: 14px; min-width: 18px; max-width: 18px; min-height: 18px; max-height: 18px; padding: 0px; border-radius: 3px; } + QWidget#controlButtons QPushButton:hover { background-color: #2A2D2E; color: #FFFFFF; } + QPushButton#closeButton { border-radius: 0px 5px 0px 0px; } + QPushButton#closeButton:hover { background-color: #2A2D2E; color: #FFFFFF; } + QWidget#contentWidget { background-color: transparent; border-radius: 0 0 5px 5px; } + QFrame#contentContainer { background-color: #19191B; border: 1px solid #2C2F36; border-radius: 5px; } + QLabel[role="sectionTitle"] { color: #EBEBEB; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 12px; font-weight: 500; letter-spacing: 0.6px; } + QLabel[role="fieldLabel"] { color: #EBEBEB; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 12px; font-weight: 400; letter-spacing: 0.6px; } + QLabel { color: #EBEBEB; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 11px; font-weight: 300; letter-spacing: 0.55px; } + QComboBox, QSpinBox, QDoubleSpinBox { color: #EBEBEB; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 11px; font-weight: 300; } + QCheckBox { color: #EBEBEB; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 11px; font-weight: 300; } + QLineEdit { background-color: rgba(89,100,113,0.2); color: #EBEBEB; border: 1px solid rgba(76,92,110,0.6); border-radius: 2px; padding: 6px 10px; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-size: 11px; font-weight: 300; letter-spacing: 0.55px; min-height: 14px; max-height: 30px; } + QLineEdit:focus { border: 1px solid #3067C0; background-color: rgba(48,103,192,0.1); } + QLineEdit:hover { border: 1px solid #3067C0; background-color: rgba(89,100,113,0.3); } + QLineEdit:disabled { background-color: rgba(89,100,113,0.1); color: rgba(235,235,235,0.4); border: 1px solid rgba(76,92,110,0.2); } + QPushButton { background-color: rgba(89,98,118,0.5); color: #EBEBEB; border: none; border-radius: 2px; padding: 0px 0px; font-family: 'Inter', 'Microsoft YaHei', sans-serif; font-weight: 300; font-size: 10px; letter-spacing: 0.5px; min-width: 90px; min-height: 30px; max-height: 30px; } + QPushButton:hover { background-color: #3067C0; color: #FFFFFF; } + QPushButton:pressed { background-color: #2556A0; color: #FFFFFF; } + QPushButton:disabled { background-color: rgba(89,98,118,0.3); color: rgba(235,235,235,0.4); } + QPushButton#primaryButton { background-color: rgba(89,98,118,0.5); border: none; color: #EBEBEB; font-weight: 300; min-width: 120px; max-width: 120px; } + QPushButton#primaryButton:hover { background-color: #2556A0; } + QPushButton#primaryButton:pressed { background-color: #1E4A8C; } + """) + + main_layout = QVBoxLayout(dialog) + main_layout.setContentsMargins(0,0,0,0) + main_layout.setSpacing(0) + base_frame = QFrame() + base_frame.setObjectName('baseFrame') + base_frame.setFrameShape(QFrame.NoFrame) + base_frame.setAttribute(Qt.WA_StyledBackground, True) + base_layout = QVBoxLayout(base_frame) + base_layout.setContentsMargins(0,0,0,0) + base_layout.setSpacing(0) + + title_bar = QWidget() + title_bar.setObjectName('titleBar') + tb_layout = QHBoxLayout(title_bar) + tb_layout.setContentsMargins(8,0,8,0) + tb_layout.setSpacing(6) + control_buttons = QWidget() + control_buttons.setObjectName('controlButtons') + cb_layout = QHBoxLayout(control_buttons) + cb_layout.setContentsMargins(0,0,0,0) + cb_layout.setSpacing(0) + close_btn = QPushButton() + close_btn.setObjectName('closeButton') + try: + close_btn.setIcon(get_icon('close_icon', QSize(18, 18))) + close_btn.setIconSize(QSize(18, 18)) + except Exception: pass + close_btn.clicked.connect(dialog.reject) + cb_layout.addWidget(close_btn) + left_placeholder = QWidget() + left_placeholder.setFixedWidth(control_buttons.sizeHint().width()) + tb_layout.addWidget(left_placeholder) + title_label = QLabel("VR调试设置") + title_label.setObjectName('titleLabel') + title_label.setAlignment(Qt.AlignCenter) + tb_layout.addWidget(title_label,1) + tb_layout.addWidget(control_buttons) + base_layout.addWidget(title_bar) + + dragging_state={'dragging':False,'pos':QPoint()} + def _tb_press(e): + if e.button()==Qt.LeftButton: dragging_state['dragging']=True; dragging_state['pos']=e.globalPos()-dialog.frameGeometry().topLeft(); e.accept() + else: e.ignore() + def _tb_move(e): + if e.buttons() & Qt.LeftButton and dragging_state['dragging']: dialog.move(e.globalPos()-dragging_state['pos']); e.accept() + else: e.ignore() + def _tb_release(e): + if e.button()==Qt.LeftButton: dragging_state['dragging']=False; e.accept() + else: e.ignore() + title_bar.mousePressEvent=_tb_press; title_bar.mouseMoveEvent=_tb_move; title_bar.mouseReleaseEvent=_tb_release + + content_widget = QWidget() + content_widget.setObjectName('contentWidget') + content_layout = QVBoxLayout(content_widget) + content_layout.setContentsMargins(10,10,10,10) + content_layout.setSpacing(0) + content_container = QFrame() + content_container.setObjectName('contentContainer') + content_container.setFrameShape(QFrame.NoFrame) + content_container.setAttribute(Qt.WA_StyledBackground, True) + container_layout = QVBoxLayout(content_container) + container_layout.setContentsMargins(15,10,15,10) + container_layout.setSpacing(10) # 获取当前设置 vr_manager = self.world.vr_manager debug_status = vr_manager.get_debug_status() perf_config = vr_manager.get_performance_monitoring_config() - # 调试状态显示 - status_group = QGroupBox("调试状态") - status_layout = QVBoxLayout() + # 左侧对齐辅助:统一字段列宽,并让小标题与控件左侧对齐 + label_column_width = 110 + def add_section_title(text): + title = QLabel(text) + title.setProperty('role','sectionTitle') + container_layout.addWidget(title) + + # 调试状态 + add_section_title("调试状态") + status_widget = QWidget() + status_layout = QVBoxLayout(status_widget) + status_layout.setContentsMargins(0,0,0,0) + status_layout.setSpacing(6) debug_enabled_label = QLabel(f"调试输出: {'启用' if debug_status['debug_enabled'] else '禁用'}") - debug_enabled_label.setStyleSheet(f"color: {'green' if debug_status['debug_enabled'] else 'red'};") + debug_enabled_label.setStyleSheet(f"color: {'#2dffc4' if debug_status['debug_enabled'] else 'red'};") status_layout.addWidget(debug_enabled_label) - debug_mode_label = QLabel(f"调试模式: {debug_status['debug_mode']}") status_layout.addWidget(debug_mode_label) - performance_label = QLabel(f"性能监控: {'启用' if debug_status['performance_monitoring'] else '禁用'}") - performance_label.setStyleSheet(f"color: {'green' if debug_status['performance_monitoring'] else 'red'};") + performance_label.setStyleSheet(f"color: {'#2dffc4' if debug_status['performance_monitoring'] else 'red'};") status_layout.addWidget(performance_label) - - status_group.setLayout(status_layout) - layout.addWidget(status_group) + container_layout.addWidget(status_widget) # 报告设置 - report_group = QGroupBox("报告设置") - report_layout = QFormLayout() - - # 报告间隔滑块 (5-120秒) + add_section_title("报告设置") + row_interval = QWidget() + row_interval_layout = QHBoxLayout(row_interval) + row_interval_layout.setContentsMargins(0,0,0,0) + row_interval_layout.setSpacing(10) + interval_text_label = QLabel("报告间隔:") + interval_text_label.setProperty('role','fieldLabel') + interval_text_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) + row_interval_layout.addWidget(interval_text_label) interval_slider = QSlider(Qt.Horizontal) interval_slider.setMinimum(5) interval_slider.setMaximum(120) interval_slider.setValue(int(debug_status['report_interval_seconds'])) interval_slider.setTickPosition(QSlider.TicksBelow) interval_slider.setTickInterval(15) - interval_label = QLabel(f"{int(debug_status['report_interval_seconds'])}秒") interval_slider.valueChanged.connect(lambda v: interval_label.setText(f"{v}秒")) + inner = QHBoxLayout() + inner.setContentsMargins(0,0,0,0) + inner.setSpacing(6) + inner.addWidget(interval_slider) + inner.addWidget(interval_label) + row_interval_layout.addLayout(inner,1) + container_layout.addWidget(row_interval) - interval_layout = QHBoxLayout() - interval_layout.addWidget(interval_slider) - interval_layout.addWidget(interval_label) - report_layout.addRow("报告间隔:", interval_layout) - - # 性能检查间隔 + row_check = QWidget() + row_check_layout = QHBoxLayout(row_check) + row_check_layout.setContentsMargins(0,0,0,0) + row_check_layout.setSpacing(10) + check_label = QLabel("性能检查间隔:") + check_label.setProperty('role','fieldLabel') + check_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) + row_check_layout.addWidget(check_label) check_interval_combo = QComboBox() - check_interval_combo.addItems(["0.1秒", "0.5秒", "1.0秒", "2.0秒"]) + check_interval_combo.addItems(["0.1秒","0.5秒","1.0秒","2.0秒"]) current_check_interval = perf_config['check_interval'] if current_check_interval == 0.1: check_interval_combo.setCurrentIndex(0) @@ -5500,93 +5824,92 @@ class MainWindow(QMainWindow): check_interval_combo.setCurrentIndex(2) else: check_interval_combo.setCurrentIndex(3) - report_layout.addRow("性能检查间隔:", check_interval_combo) + row_check_layout.addWidget(check_interval_combo,1) + container_layout.addWidget(row_check) - # 帧历史大小 + row_hist = QWidget(); row_hist_layout = QHBoxLayout(row_hist) + row_hist_layout.setContentsMargins(0,0,0,0) + row_hist_layout.setSpacing(10) + hist_label = QLabel("帧时间历史:") + hist_label.setProperty('role','fieldLabel') + hist_label.setAlignment(Qt.AlignRight|Qt.AlignVCenter) + row_hist_layout.addWidget(hist_label) frame_history_spin = QSpinBox() frame_history_spin.setMinimum(10) frame_history_spin.setMaximum(1000) frame_history_spin.setValue(perf_config['frame_history_size']) frame_history_spin.setSuffix(" 帧") - report_layout.addRow("帧时间历史:", frame_history_spin) - - report_group.setLayout(report_layout) - layout.addWidget(report_group) + row_hist_layout.addWidget(frame_history_spin,1) + container_layout.addWidget(row_hist) # 监控项目 - monitor_group = QGroupBox("监控项目") - monitor_layout = QVBoxLayout() - + add_section_title("监控项目") + monitor_widget = QWidget() + monitor_layout = QVBoxLayout(monitor_widget) + monitor_layout.setContentsMargins(0,0,0,0) + monitor_layout.setSpacing(6) cpu_check = QCheckBox("CPU使用率") cpu_check.setChecked(perf_config['psutil_available']) cpu_check.setEnabled(perf_config['psutil_available']) monitor_layout.addWidget(cpu_check) - memory_check = QCheckBox("内存使用率") memory_check.setChecked(perf_config['psutil_available']) memory_check.setEnabled(perf_config['psutil_available']) monitor_layout.addWidget(memory_check) - gpu_check = QCheckBox("GPU使用率") gpu_check.setChecked(perf_config['gputil_available'] or perf_config['nvidia_ml_available']) gpu_check.setEnabled(perf_config['gputil_available'] or perf_config['nvidia_ml_available']) monitor_layout.addWidget(gpu_check) - frame_time_check = QCheckBox("帧时间统计") frame_time_check.setChecked(True) monitor_layout.addWidget(frame_time_check) + container_layout.addWidget(monitor_widget) - monitor_group.setLayout(monitor_layout) - layout.addWidget(monitor_group) - - # 按钮 + separator_buttons = QFrame() + separator_buttons.setFrameShape(QFrame.HLine) + separator_buttons.setFrameShadow(QFrame.Plain) + separator_buttons.setFixedHeight(1) + separator_buttons.setStyleSheet("background-color: #2C2F36; border: none;") + container_layout.addWidget(separator_buttons) button_layout = QHBoxLayout() - apply_button = QPushButton("应用") reset_button = QPushButton("重置计数器") ok_button = QPushButton("确定") + # ok_button.setObjectName("primaryButton") cancel_button = QPushButton("取消") - button_layout.addWidget(apply_button) button_layout.addWidget(reset_button) button_layout.addStretch() button_layout.addWidget(ok_button) button_layout.addWidget(cancel_button) + container_layout.addLayout(button_layout) - layout.addLayout(button_layout) + content_layout.addWidget(content_container, 0, Qt.AlignTop) + base_layout.addWidget(content_widget); main_layout.addWidget(base_frame) - # 连接信号 def apply_settings(): try: - # 应用报告间隔 new_interval_seconds = interval_slider.value() - new_interval_frames = int(new_interval_seconds * 60) # 假设60fps + new_interval_frames = int(new_interval_seconds * 60) vr_manager.set_performance_report_interval(new_interval_frames) - - # 应用性能检查间隔 check_intervals = [0.1, 0.5, 1.0, 2.0] new_check_interval = check_intervals[check_interval_combo.currentIndex()] vr_manager.set_performance_check_interval(new_check_interval) - - # 应用帧历史大小 vr_manager.set_frame_time_history_size(frame_history_spin.value()) - - QMessageBox.information(dialog, "成功", "VR调试设置已应用!") + UniversalMessageDialog.show_success(dialog, "成功", "VR调试设置已应用!", False, "确定") except Exception as e: - QMessageBox.critical(dialog, "错误", f"应用设置时发生错误:\n{str(e)}") - + UniversalMessageDialog.show_error(dialog, "错误", f"应用设置时发生错误:\n{str(e)}", False, "确定") def reset_counters(): try: vr_manager.reset_performance_counters() - QMessageBox.information(dialog, "成功", "性能计数器已重置!") + UniversalMessageDialog.show_success(dialog, "成功", "性能计数器已重置!", False, "确定") except Exception as e: - QMessageBox.critical(dialog, "错误", f"重置计数器时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(dialog, "错误", f"重置计数器时发生错误:\n{str(e)}", False, "确定") apply_button.clicked.connect(apply_settings) reset_button.clicked.connect(reset_counters) ok_button.clicked.connect(lambda: (apply_settings(), dialog.accept())) cancel_button.clicked.connect(dialog.reject) - return dialog # ==================== VR测试模式事件处理 ==================== @@ -5599,26 +5922,31 @@ class MainWindow(QMainWindow): # 启用VR测试模式 success = self.world.vr_manager.enable_vr_test_mode(display_mode='stereo') if success: - QMessageBox.information(self, "VR测试模式", - "VR测试模式已启用!\n\n现在VR渲染内容将直接显示在PC屏幕上,无需VR头显。\n\n特点:\n- 显示VR左右眼视图\n- 实时性能监控HUD\n- 复用完整VR渲染管线\n- 可测量纯渲染性能") + UniversalMessageDialog.show_info(self, "VR测试模式", + "VR测试模式已启用!\n\n现在VR渲染内容将直接显示在PC屏幕上,无需VR头显。\n\n特点:\n- 显示VR左右眼视图\n- 实时性能监控HUD\n- 复用完整VR渲染管线\n- 可测量纯渲染性能", + False, "确定") print("✅ VR测试模式已启用") # 可选:自动开启性能测试 self.world.vr_manager.run_vr_performance_test(duration_seconds=10) else: self.vrTestModeAction.setChecked(False) - QMessageBox.warning(self, "错误", "启用VR测试模式失败!") + UniversalMessageDialog.show_warning(self, "错误", "启用VR测试模式失败!", + False, "确定") else: # 禁用VR测试模式 self.world.vr_manager.disable_vr_test_mode() - QMessageBox.information(self, "VR测试模式", "VR测试模式已禁用") + UniversalMessageDialog.show_info(self, "VR测试模式", "VR测试模式已禁用!", + False, "确定") print("✅ VR测试模式已禁用") else: self.vrTestModeAction.setChecked(False) - QMessageBox.warning(self, "错误", "VR管理器不可用!") + UniversalMessageDialog.show_warning(self, "错误", "VR管理器不可用!", + False, "确定") except Exception as e: self.vrTestModeAction.setChecked(False) - QMessageBox.critical(self, "错误", f"切换VR测试模式时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"切换VR测试模式时发生错误:\n{str(e)}", + False, "确定") def onToggleVRTestSubmitTexture(self): """切换VR测试模式纹理提交功能""" @@ -5627,7 +5955,8 @@ class MainWindow(QMainWindow): enabled = self.vrTestSubmitTextureAction.isChecked() self.world.vr_manager.set_test_mode_features(submit_texture=enabled) except Exception as e: - QMessageBox.critical(self, "错误", f"设置纹理提交功能时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"设置纹理提交功能时发生错误:\n{str(e)}", + False, "确定") def onToggleVRTestWaitPoses(self): """切换VR测试模式姿态等待功能""" @@ -5636,7 +5965,8 @@ class MainWindow(QMainWindow): enabled = self.vrTestWaitPosesAction.isChecked() self.world.vr_manager.set_test_mode_features(wait_poses=enabled) except Exception as e: - QMessageBox.critical(self, "错误", f"设置姿态等待功能时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"设置姿态等待功能时发生错误:\n{str(e)}", + False, "确定") def onSetVRTestStep(self, step): """设置VR测试步骤""" @@ -5646,24 +5976,29 @@ class MainWindow(QMainWindow): self.world.vr_manager.set_test_mode_features(submit_texture=False, wait_poses=False) self.vrTestSubmitTextureAction.setChecked(False) self.vrTestWaitPosesAction.setChecked(False) - QMessageBox.information(self, "VR测试", "已重置为基线状态:两个功能都禁用") + UniversalMessageDialog.show_info(self, "VR测试", "已重置为基线状态:两个功能都禁用", + False, "确定") elif step == 1: # 只启用纹理提交 self.world.vr_manager.set_test_mode_features(submit_texture=True, wait_poses=False) self.vrTestSubmitTextureAction.setChecked(True) self.vrTestWaitPosesAction.setChecked(False) - QMessageBox.information(self, "VR测试", "步骤1:只启用纹理提交\n观察FPS变化来判断submit_texture是否影响性能") + UniversalMessageDialog.show_info(self, "VR测试", "步骤1:只启用纹理提交\n观察FPS变化来判断submit_texture是否影响性能", + False, "确定") elif step == 2: # 只启用姿态等待 self.world.vr_manager.set_test_mode_features(submit_texture=False, wait_poses=True) self.vrTestSubmitTextureAction.setChecked(False) self.vrTestWaitPosesAction.setChecked(True) - QMessageBox.information(self, "VR测试", "步骤2:只启用姿态等待\n观察FPS变化来判断waitGetPoses是否影响性能") + UniversalMessageDialog.show_info(self, "VR测试", "步骤2:只启用姿态等待\n观察FPS变化来判断waitGetPoses是否影响性能", + False, "确定") elif step == 3: # 同时启用两者 self.world.vr_manager.set_test_mode_features(submit_texture=True, wait_poses=True) self.vrTestSubmitTextureAction.setChecked(True) self.vrTestWaitPosesAction.setChecked(True) - QMessageBox.information(self, "VR测试", "步骤3:同时启用两者\n这应该完全复现普通VR模式的36FPS问题") + UniversalMessageDialog.show_info(self, "VR测试", "步骤3:同时启用两者\n这应该完全复现普通VR模式的36FPS问题", + False, "确定") except Exception as e: - QMessageBox.critical(self, "错误", f"设置VR测试步骤时发生错误:\n{str(e)}") + UniversalMessageDialog.show_error(self, "错误", f"设置VR测试步骤时发生错误:\n{str(e)}", + False, "确定") def setup_main_window(world,path = None): """设置主窗口的便利函数""" diff --git a/功能与源代码对应关系清单.md b/功能与源代码对应关系清单.md new file mode 100644 index 00000000..688e5ddd --- /dev/null +++ b/功能与源代码对应关系清单.md @@ -0,0 +1,2362 @@ +# 功能与源代码对应关系清单 + +## 2.1.1 core模块核心文件 + +### 1. `core/__init__.py` +- **功能**: Python包初始化文件,导出核心类 +- **类**: + - `CoreWorld`: 核心世界类 + - `SelectionSystem`: 选择系统类 + - `EventHandler`: 事件处理器类 + - `ToolManager`: 工具管理器类 + - `ScriptManager`: 脚本管理器类 + - `ScriptBase`: 脚本基类 + - `ScriptComponent`: 脚本组件类 + +### 2. `core/world.py` +- **功能**: 核心世界功能类,负责基础的3D世界设置和核心功能 +- **类**: + - `CoreWorld`: 核心世界类 +- **方法**: + - `_setupResourcePaths()`: 设置资源路径 + - `_setupCamera()`: 设置相机 + - `_setupLighting()`: 设置光照 + - `_setupGround()`: 设置地面网格 + - `getChineseFont()`: 获取中文字体 + - `setQtWidget()`: 设置Qt部件引用 + - `getWindowSize()`: 获取准确的窗口尺寸 + - `wheelForward()`: 处理滚轮向前滚动(前进) + - `wheelBackward()`: 处理滚轮向后滚动(后退) + - `moveCamera()`: 移动相机位置(垂直移动) + - `mousePressEventRight()`: 处理鼠标右键按下事件 + - `mouseReleaseEventRight()`: 处理鼠标右键释放事件 + - `mouseMoveEvent()`: 处理鼠标移动事件 + - `getGroundNode()`: 获取地板节点 + - `getAmbientLight()`: 获取环境光 + - `getDirectionalLight()`: 获取定向光 + - `start_day_night_cycle()`: 让天空盒在指定时间内过渡 + - `_day_night_cycle_task()`: 天空盒过渡任务 + - `set_daytime()`: 设置时间 + - `get_render_pipeline()`: 获取 RenderPipeline 实例 + - `_setupSkybox()`: 设置静态天空盒 + - `createDirectionalLight()`: 创建平行光 + - `check_material_editor_connection()`: 检查材质编辑器连接状态 + - `create_material_editor_widget()`: 创建材质编辑器组件 + - `_delayed_material_test()`: 延迟执行的材质编辑器连接测试 + - `launch_day_time_editor()`: 启动光照编辑器 + - `setup_material_editor_network()`: 设置材质编辑器网络通信 + - `export_materials_to_file()`: 导出材质列表到文件 + - `update_material_from_editor()`: 从编辑器更新材质 + - `launch_material_editor()`: 启动材质编辑器 + - `create_sample_materials()`: 创建一些示例材质供编辑器使用 + - `load_test_models_with_materials()`: 加载一些测试模型以提供更多材质供编辑 + - `launch_plugin_configurator()`: 启动插件配置器 + +### 3. `core/vr_manager.py` +- **功能**: VR管理器主文件,负责VR系统的初始化和管理 +- **类**: + - `VRManager`: VR管理器类 +- **方法**: + - `initialize_vr()`: 初始化VR系统 + - `enable_vr()`: 启用VR模式 + - `disable_vr()`: 禁用VR模式 + - `update_vr()`: 更新VR状态 + - `render_vr()`: VR渲染处理 + - `set_vr_render_mode()`: 切换VR渲染模式 + - `get_vr_render_mode()`: 获取当前VR渲染模式 + - `cleanup()`: 清理VR资源 + - `get_vr_status()`: 获取VR状态信息 + - `submit_texture()`: 优化的VR纹理提交 + - `_batch_submit_textures()`: 批量提交两眼纹理 + - `_disable_main_cam()`: 禁用主相机 + - `_enable_main_cam()`: 恢复主相机 + - `_initialize_controllers()`: 初始化VR手柄控制器 + - `_detect_controllers()`: 检测并连接VR控制器 + - `_create_tracked_device_anchor()`: 为跟踪设备创建锚点节点 + - `update_tracked_devices()`: 更新所有跟踪设备的姿态 + - `get_controller_by_role()`: 根据角色获取控制器 + - `are_controllers_connected()`: 检查是否有控制器连接 + - `get_connected_controllers()`: 获取所有连接的控制器列表 + - `trigger_controller_haptic()`: 触发控制器震动反馈 + - `is_trigger_pressed()`: 检查扳机是否被按下 + - `is_trigger_just_pressed()`: 检查扳机是否刚刚被按下 + - `is_grip_pressed()`: 检查握把是否被按下 + - `is_grip_just_pressed()`: 检查握把是否刚刚被按下 + - `is_menu_pressed()`: 检查菜单按钮是否被按下 + - `is_trackpad_touched()`: 检查触摸板是否被触摸 + - `get_trackpad_position()`: 获取触摸板位置 + - `get_selected_object()`: 获取指定手选中的对象 + - `get_grabbed_object()`: 获取指定手抓取的对象 + - `is_grabbing_object()`: 检查是否正在抓取对象 + - `force_release_all_grabs()`: 强制释放所有抓取的对象 + - `add_interactable_object()`: 将对象标记为可交互 + - `enable_gc_control()`: 启用垃圾回收控制 + - `disable_gc_control()`: 禁用垃圾回收控制 + - `set_manual_gc_interval()`: 设置手动垃圾回收间隔 + - `force_manual_gc()`: 强制执行一次垃圾回收 + - `get_object_pool_status()`: 获取对象池状态 + - `set_resolution_scale()`: 设置VR分辨率缩放系数 + - `set_quality_preset()`: 设置VR质量预设 + - `cycle_quality_preset()`: 循环切换质量预设 + - `get_resolution_info()`: 获取分辨率相关信息 + - `print_resolution_info()`: 输出分辨率信息 + - `enable_performance_mode()`: 手动启用性能模式 + - `disable_performance_mode()`: 禁用性能模式 + - `set_performance_mode_trigger_frame()`: 设置性能模式自动触发的帧数 + - `get_performance_mode_status()`: 获取性能模式状态 + - 其他VR系统管理方法 + +### 4. `core/selection.py` +- **功能**: 选择系统模块,实现3D场景中对象的选择功能 +- **类**: + - `SelectionSystem`: 选择系统类 +- **方法**: + - `createSelectionBox()`: 创建选择框 + - `updateSelectionBoxGeometry()`: 更新选择框的几何形状和位置 + - `updateSelectionBoxTask()`: 选择框更新任务 + - `clearSelectionBox()`: 清除选择框 + - `createGizmo()`: 创建变换控制器 + - `createGizmoGeometry()`: 创建坐标轴的几何体 + - `updateGizmoTask()`: 更新变换控制器任务 + - `clearGizmo()`: 清除坐标轴 + - `setGizmoAxisColor()`: 设置坐标轴颜色 + - `setGizmoRotAxisColor()`: 设置旋转坐标轴颜色 + - `checkGizmoClick()`: 检查是否点击了坐标轴 + - `updateGizmoHighlight()`: 更新坐标轴高亮状态 + - `startGizmoDrag()`: 开始坐标轴拖拽 + - `updateGizmoDrag()`: 更新坐标轴拖拽 + - `stopGizmoDrag()`: 停止坐标轴拖拽 + - `updateSelection()`: 更新选择状态 + - `_setCursor()`: 设置光标 + - `_resetCursor()`: 重置光标 + - `_setupGizmoRendering()`: 设置坐标轴渲染属性 + - `setupGizmoCollision()`: 设置坐标轴碰撞检测 + - `detectGizmoAxisAtMouse()`: 统一的坐标轴检测方法 + - `distanceToLine()`: 计算点到线段的距离 + - `_safeUpdatePropertyPanel()`: 安全地更新属性面板 + - 其他选择和变换相关方法 + +### 5. `core/tool_manager.py` +- **功能**: 工具管理器模块,管理各种编辑工具 +- **类**: + - `ToolManager`: 工具管理器类 +- **方法**: + - `setCurrentTool()`: 设置当前工具 + - `getCurrentTool()`: 获取当前工具 + - `isSelectionTool()`: 检查是否是选择工具 + - `isMoveTool()`: 检查是否是移动工具 + - `isRotateTool()`: 检查是否是旋转工具 + - `isScaleTool()`: 检查是否是缩放工具 + - `isDayTimeEditorTool()`: 检查是否是光照编辑工具 + - `isPlugincongiguratorTool()`: 检查是否是图形编辑工具 + - `launch_day_time_editor()`: 启动光照编辑器 + - `openSunLightingTool()`: 打开太阳光照系统工具的便捷方法 + - `launch_plugin_configurator()`: 启动插件配置器 + +### 6. `core/script_system.py` +- **功能**: 脚本系统模块,管理游戏对象的脚本挂载和执行 +- **类**: + - `ScriptBase`: 脚本基类 + - `ScriptComponent`: 脚本组件类 + - `ScriptManager`: 脚本管理器类 + - `ScriptEngine`: 脚本引擎类 + - `ScriptLoader`: 脚本加载器类 + - `ScriptAPI`: 脚本API类 +- **方法**: + - `attach_script()`: 为对象挂载脚本 + - `detach_script()`: 为对象卸载脚本 + - `reload_script()`: 重载脚本 + - `get_script_info()`: 获取脚本信息 + - `start_system()`: 启动脚本系统 + - `stop_system()`: 停止脚本系统 + - `load_script_from_file()`: 从文件加载脚本 + - `load_all_scripts_from_directory()`: 从目录加载所有脚本 + - `add_script_to_object()`: 为对象添加脚本 + - `remove_script_from_object()`: 从游戏对象移除脚本 + - `get_scripts_on_object()`: 获取对象上的所有脚本 + - `get_script_on_object()`: 获取对象上的特定脚本 + - `get_available_scripts()`: 获取所有可用的脚本名称 + - `list_all_scripts()`: 列出所有脚本信息 + - `save_object_scripts()`: 保存对象脚本 + - 其他脚本管理方法 + +### 7. `core/gui_manager.py` +- **功能**: GUI管理器模块,负责2D和3D GUI元素的创建和管理 +- **类**: + - `GUIManager`: GUI管理器类 +- **方法**: + - `createGUIButton()`: 创建GUI按钮 + - `createGUILabel()`: 创建GUI标签 + - `createGUIEntry()`: 创建GUI输入框 + - `createGUI2DImage()`: 创建2D图像 + - `createGUI3DText()`: 创建3D文本 + - `createGUI3DImage()`: 创建3D图像 + - `createVideoScreen()`: 创建视频屏幕 + - `createGUI2DVideoScreen()`: 创建2D视频屏幕 + - `createSphericalVideo()`: 创建球形视频 + - `createGUIVirtualScreen()`: 创建虚拟屏幕 + - `findClickedGUI()`: 查找被点击的GUI元素 + - `selectGUIInTree()`: 在树形控件中选中GUI元素 + - `createGUIAtPosition()`: 在指定位置创建GUI元素 + - `editGUIElement()`: 编辑GUI元素属性 + - `deleteGUIElement()`: 删除GUI元素 + - `duplicateGUIElement()`: 复制GUI元素 + - `editGUIElementDialog()`: 显示GUI元素编辑对话框 + - `onGUIButtonClick()`: GUI按钮点击事件处理 + - `onGUIEntrySubmit()`: GUI输入框提交事件处理 + - `toggleGUIEditMode()`: 切换GUI编辑模式 + - `enterGUIEditMode()`: 进入GUI编辑模式 + - `exitGUIEditMode()`: 退出GUI编辑模式 + - `createGUIEditPanel()`: 创建GUI编辑面板 + - `openGUIPreviewWindow()`: 打开独立的GUI预览窗口 + - `closeGUIPreviewWindow()`: 关闭GUI预览窗口 + - `setGUICreateTool()`: 设置GUI创建工具 + - `deleteSelectedGUI()`: 删除选中的GUI元素 + - `copySelectedGUI()`: 复制选中的GUI元素 + - `handleGUIEditClick()`: 处理GUI编辑模式下的点击 + - `createGUIAtPosition()`: 在指定位置创建GUI元素 + - `findClickedGUI()`: 查找被点击的GUI元素 + - `selectGUIInTree()`: 在树形控件中选中GUI元素 + - `updateGUISelection()`: 更新GUI元素选择状态 + - `updateGUIPropertyPanel()`: 更新GUI元素属性面板 + - `selectGUIColor()`: 选择GUI元素颜色 + - `update3DImageTexture()`: 更新3D图像纹理 + - `update2DImageTexture()`: 更新2D图片纹理 + - `editGUI2DPosition()`: 编辑2D GUI元素位置 + - `editGUI3DPosition()`: 编辑3D GUI元素位置 + - `editGUIScale()`: 编辑GUI元素缩放 + - `createCesiumView()`: 创建 Cesium 视图窗口 + - `toggleCesiumView()`: 切换 Cesium 视图显示状态 + - `refreshCesiumView()`: 刷新 Cesium 视图 + - `updateCesiumURL()`: 更新 Cesium 视图的 URL + - `addModelToCesium()`: 向 Cesium 添加模型 + - `addCesiumTilesetToScene()`: 在 Panda3D 场景中添加 Cesium 3D Tiles + - `removeModelFromCesium()`: 从 Cesium 移除模型 + - `updateCesiumModelPosition()`: 更新 Cesium 中模型的位置 + - `getAllCesiumModels()`: 获取 Cesium 中所有模型的列表 + - `addLocalModelToCesium()`: 向 Cesium 添加本地模型文件 + - `_create_screen_text()`: 为虚拟屏幕创建文本节点 + - `_get_tree_widget()`: 安全获取树形控件 + - `_resizeButtonToText()`: 根据文本内容调整按钮大小 + - `constrain2DPosition()`: 限制2D GUI元素位置在屏幕范围内 + - `_ensureVideoScreenMaterial()`: 确保视频屏幕有正确的材质设置 + - `_debugVideoScreenTextures()`: 调试视频屏幕的纹理状态 + - `playVideo()`: 播放视频 + - `_getMovieTextureFromScreen()`: 从视频屏幕获取视频纹理 + - `pauseVideo()`: 暂停视频 + - `stopVideo()`: 停止视频 + - `setVideoTime()`: 设置视频播放时间 + - `loadVideoFile()`: 为视频屏幕加载新的视频文件 + - `_loadMovieTexture()`: 加载视频纹理的兼容方法 + - `_configureVideoTexture()`: 配置视频纹理属性 + - `load2DVideoFile()`: 为2D视频屏幕加载新的视频文件 + - `play2DVideo()`: 播放2D视频 + - `pause2DVideo()`: 暂停2D视频 + - `stop2DVideo()`: 停止2D视频 + - `createSphericalVideo()`: 创建球形视频 + - `_createSphereGeometry()`: 创建球形几何体 + - `playSphericalVideo()`: 播放球形视频 + - `pauseSphericalVideo()`: 暂停球形视频 + - `setSphericalVideoTime()`: 设置球形视频时间 + - 其他GUI元素创建和管理方法 + +### 8. `core/terrain_manager.py` +- **功能**: 地形管理器模块,处理3D地形的创建、编辑和渲染 +- **类**: + - `TerrainManager`: 地形管理器类 +- **方法**: + - `createTerrainFromHeightMap()`: 从高度图创建地形 + - `createFlatTerrain()`: 创建平面地形 + - `_applyTerrainMaterial()`: 为地形应用材质 + - `updateTerrain()`: 更新所有地形的LOD + - `setTerrainLODThreshold()`: 设置地形LOD阈值 + - `getTerrainHeight()`: 获取地形上指定点的高度 + - `modifyTerrainHeight()`: 修改地形高度 + - `deleteTerrain()`: 删除地形 + - `getTerrainByName()`: 根据名称查找地形 + - `getAllTerrainNames()`: 获取所有地形名称 + - `setTerrainColor()`: 设置地形颜色 + - `setTerrainTexture()`: 为地形设置纹理 + - `saveTerrainData()`: 保存地形数据到文件 + - `_recreateTerrain()`: 重新创建地形 + - `_get_tree_widget()`: 安全获取树形控件 + +### 9. `core/collision_manager.py` +- **功能**: 碰撞管理器模块,管理场景中的碰撞检测和响应 +- **类**: + - `CollisionManager`: 碰撞管理器类 + - `CollisionPerformanceMonitor`: 碰撞检测性能监控器 + - `OctreeNode`: 八叉树节点 +- **方法**: + - `enableModelCollisionDetection()`: 启用/禁用模型间碰撞检测 + - `detectModelCollisions()`: 检测模型间碰撞 + - `_checkModelPairCollision()`: 检查两个模型是否碰撞 + - `_findCollisionNode()`: 查找模型的碰撞节点 + - `_logCollisionInfo()`: 输出碰撞信息日志 + - `getCollisionHistory()`: 获取碰撞历史记录 + - `clearCollisionHistory()`: 清除碰撞历史记录 + - `getCollisionStatistics()`: 获取碰撞统计信息 + - `createCollisionShape()`: 为模型创建指定类型的碰撞体 + - `_determineOptimalShape()`: 根据模型特征自动确定最适合的碰撞体形状 + - `_getTransformedModelInfo()`: 获取考虑变换后的模型信息 + - `createMouseRay()`: 创建鼠标射线 + - `performRaycast()`: 执行射线检测 + - `getCollisionMask()`: 获取碰撞掩码 + - `createCollisionGroup()`: 创建碰撞分组 + - `addToCollisionGroup()`: 将模型添加到碰撞分组 + - `enableCollisionGroup()`: 启用/禁用碰撞分组 + - `registerCollisionCallback()`: 注册碰撞回调函数 + - `_executeCollisionCallbacks()`: 执行碰撞回调 + - `_getModelMaskType()`: 获取模型的掩码类型 + - `enableSpatialPartitioning()`: 启用空间分割优化 + - `_buildOctree()`: 构建八叉树 + - `detectModelCollisionsOptimized()`: 使用空间分割优化的碰撞检测 + - `cleanup()`: 清理碰撞管理器资源 + - `setupAdvancedCollision()`: 高级碰撞设置方法 + - `example_usage()`: 碰撞系统使用示例 + - `recordDetection()`: 记录射线检测性能 + - `recordModelCollisionDetection()`: 记录模型间碰撞检测性能 + - `getAverageTime()`: 获取平均射线检测时间 + - `getAverageModelCollisionTime()`: 获取平均模型间碰撞检测时间 + - `getPerformanceReport()`: 获取完整性能报告 + - `insert()`: 插入模型到八叉树 + - `query()`: 查询可能与指定模型碰撞的模型列表 + - `_contains()`: 检查模型是否在此节点范围内 + - `_subdivide()`: 分割节点为8个子节点 + +### 10. `core/event_handler.py` +- **功能**: 事件处理器模块,处理用户输入事件和系统事件 +- **类**: + - `EventHandler`: 事件处理器类 +- **方法**: + - `showClickRay()`: 显示鼠标点击的射线 + - `_addHitMarker()`: 在碰撞点添加标记 + - `clearRay()`: 清除当前显示的射线 + - `clearRayTask()`: 清除射线的任务回调 + - `toggleRayDisplay()`: 切换射线显示状态 + - `mousePressEventLeft()`: 鼠标左键按下事件 + - `mousePressEventRight()`: 鼠标右键按下事件 + - `_handleTerrainEdit()`: 处理地形编辑 + - `_handleSelectionClick()`: 处理选择工具的点击事件 + - `mouseReleaseEventLeft()`: 鼠标左键释放事件 + - `wheelForward()`: 处理滚轮向前滚动(前进) + - `wheelBackward()`: 处理滚轮向后滚动(后退) + - `mousePressEventMiddle()`: 处理鼠标中键按下事件 + - `mouseReleaseEventMiddle()`: 处理鼠标中键释放事件 + - `mouseMoveEvent()`: 处理鼠标移动事件 + +### 11. `core/Command_System.py` +- **功能**: 命令系统模块,实现命令模式,支持撤销/重做功能 +- **类**: + - `Command`: 命令基类 + - `CommandManager`: 命令管理器类 + - `MoveNodeCommand`: 节点移动命令类 + - `DeleteNodeCommand`: 节点删除命令类 + - `RotateNodeCommand`: 节点旋转命令类 + - `ScaleNodeCommand`: 节点缩放命令类 + - `CreateNodeCommand`: 节点创建命令类 + - `ReparentNodeCommand`: 节点重新父化命令类 + - `CompositeCommand`: 组合命令类 + - `MoveLightCommand`: 灯光移动命令类 +- **方法**: + - `execute()`: 执行命令 + - `undo()`: 撤销命令 + - `redo()`: 重做命令 + - `execute_command()`: 执行命令 + - `can_undo()`: 检查是否可以撤销 + - `can_redo()`: 检查是否可以重做 + - `clear_history()`: 清空所有历史记录 + - `get_undo_count()`: 获取可撤销的命令数量 + - `get_redo_count()`: 获取可重做的命令数量 + +### 12. `core/InfoPanelManager.py` +- **功能**: 信息面板管理器模块,管理场景中信息面板的显示和更新 +- **类**: + - `InfoPanelManager`: 信息面板管理器类 +- **方法**: + - `createInfoPanel()`: 创建信息面板 + - `setPanelBackgroundImage()`: 为指定面板设置背景图片 + - `_getPanelContent()`: 根据面板ID获取固定的标题和内容 + - `updatePanelContent()`: 更新面板内容 + - `registerDataSource()`: 注册数据源,定期更新面板内容 + - `_updateDataThread()`: 数据更新线程 + - `_is3DPanel()`: 判断面板是否为3D面板 + - `_is2DPanel()`: 判断面板是否为2D面板 + - `unregisterDataSource()`: 注销数据源 + - `updatePanelProperties()`: 更新面板属性 + - `showPanel()`: 显示指定面板 + - `hidePanel()`: 隐藏指定面板 + - `togglePanel()`: 切换面板显示/隐藏状态 + - `getPanelNode()`: 获取面板的节点 + - `removePanel()`: 移除指定面板 + - `removeAllPanels()`: 移除所有面板 + - `createHTTPInfoPanel()`: 创建HTTP信息面板 + - `updateHTTPInfoPanel()`: 更新HTTP信息面板的请求参数 + - `create3DInfoPanel()`: 创建简化版3D信息面板 + - `update3DPanelContent()`: 更新3D面板内容 + - `update3DPanelProperties()`: 更新3D面板属性 + - `create3DHTTPInfoPanel()`: 创建3D HTTP信息面板 + - `serializePanelData()`: 序列化面板数据用于保存 + - `getAllPanelData()`: 获取所有面板的序列化数据 + - `recreatePanelFromData()`: 从序列化数据重新创建面板 + - `onCreateSampleInfoPanel()`: 创建示例天气信息面板 + - `getRealWeatherData()`: 获取真实天气数据 + - 其他信息面板管理方法 + +### 13. `core/patrol_system.py` +- **功能**: 巡检系统模块,实现自动化巡检路径和逻辑 +- **类**: + - `PatrolSystem`: 巡检系统类 +- **方法**: + - `add_patrol_point()`: 添加巡检点 + - `add_auto_heading_patrol_point()`: 添加自动计算朝向的巡检点 + - `add_patrol_point_looking_at()`: 添加朝向指定位置的巡检点 + - `clear_patrol_points()`: 清空巡检点 + - `set_patrol_speed()`: 设置巡检速度 + - `start_patrol()`: 开始巡检 + - `stop_patrol()`: 停止巡检 + - `pause_patrol()`: 暂停巡检 + - `resume_patrol()`: 恢复巡检 + - `reset_to_original_position()`: 重置相机到原始位置 + - `_patrol_task()`: 巡检主任务 + - `_handle_moving_state()`: 处理移动状态 + - `_handle_turning_to_target_state()`: 处理转向目标状态 + - `_handle_waiting_state()`: 处理等待状态 + - `_handle_turning_back_state()`: 处理转回原朝向状态 + - `_normalize_angle()`: 规范化角度到-180到180度之间 + - `_look_at_to_hpr()`: 将方向向量转换为HPR角度 + - `get_patrol_status()`: 获取巡检状态信息 + - `list_patrol_points()`: 列出所有巡检点 + - `remove_patrol_point()`: 移除指定索引的巡检点 + - `insert_patrol_point()`: 在指定位置插入巡检点 + - `update_patrol_point()`: 更新指定巡检点的信息 + - `goto_patrol_point()`: 直接跳转到指定巡检点 + - `cleanup()`: 清理巡检系统资源 + +### 14. `core/assembly_interaction.py` +- **功能**: 装配交互模块,处理复杂装配体的交互逻辑 +- **类**: + - `AssemblyInteractionManager`: 装配交互管理器类 + - `StepGuideDialog`: 步骤指引对话框类 +- **方法**: + - `init_exam_mode()`: 初始化考核模式 + - `play_step_audio()`: 播放步骤音频 + - `play_audio_with_pygame()`: 使用pygame播放音频 + - `play_audio_fallback()`: 备用音频播放方法 + - `set_operation_enabled()`: 设置操作是否启用 + - `check_operation_permission()`: 检查操作权限 + - `check_tool_match()`: 检查工具是否匹配 + - `record_tool_error()`: 记录工具错误 + - `start_interaction_mode()`: 启动交互模式 + - `load_configuration()`: 加载配置文件 + - `load_original_positions_from_config()`: 从配置文件中加载模型的原始位置信息 + - `check_step_completeness()`: 检查配置文件的步骤完整性 + - `setup_picking()`: 设置用于鼠标拾取的碰撞检测系统 + - `show_step_dialog()`: 显示步骤指引对话框 + - `start_current_step()`: 开始当前步骤 + - `prepare_interaction()`: 准备交互 + - `find_model_node()`: 在场景中查找指定名称的模型节点 + - `list_scene_models()`: 列出场景中的所有模型 + - `show_models_status()`: 显示所有模型的当前状态 + - `record_current_positions()`: 将当前所有模型的位置记录为原始位置 + - `normalize_step_type()`: 标准化步骤类型 + - `normalize_operation_type()`: 标准化操作类型 + - `analyze_final_state()`: 分析最终状态 + - `qt_mouse_press_event()`: Qt鼠标按下事件处理 + - `is_click_in_gui_area()`: 检查鼠标点击是否在GUI区域 + - `handle_gui_button_click()`: 直接处理GUI按钮点击 + - `qt_mouse_release_event()`: Qt鼠标释放事件处理 + - `handle_qt_mouse_click()`: 处理Qt鼠标点击 + - `perform_ray_cast()`: 执行射线检测 + - `is_target_model_hit()`: 检查击中的节点是否是目标模型 + - `on_mouse_down()`: 鼠标按下事件 + - `start_dragging()`: 开始拖拽模型 + - `drag_task()`: 拖拽任务 + - `stop_dragging()`: 停止拖拽 + - `on_mouse_up()`: 鼠标抬起事件 + - `check_step_completion()`: 检查步骤是否完成 + - `complete_current_step()`: 完成当前步骤 + - `finish_interaction()`: 完成所有交互 + - `stop_interaction()`: 用户主动停止交互 + - `show_exam_results()`: 显示考核结果 + - `save_exam_results()`: 保存考核结果到文件 + - `stop_interaction_mode()`: 停止交互模式 + - `trigger_drag_by_keyboard()`: 通过键盘触发拖拽 + - `trigger_click_movement()`: 触发点击位移动画 + - `perform_disassemble_click_movement()`: 执行拆卸点击位移 + - `perform_assemble_click_movement()`: 执行安装点击位移 + +### 15. `core/CustomMouseController.py` +- **功能**: 自定义鼠标控制器模块,提供定制化的鼠标操作控制 +- **类**: + - `CustomMouseController`: 自定义鼠标控制器类 +- **方法**: + - `__init__()`: 初始化鼠标控制器 + - `setUp()`: 设置控制器参数 + - `setKey()`: 设置按键状态 + - `move()`: 处理相机移动和旋转 + +### 16. `core/maintenance_gui.py` +- **功能**: 维护GUI模块,提供设备维护相关的GUI界面 +- **类**: + - `MaintenanceGUI`: 维护GUI管理器类 +- **方法**: + - `__init__()`: 初始化维护GUI + - `setup_gui()`: 设置GUI界面 + - `start_mouse_monitor()`: 启动鼠标监控任务 + - `test_mouse_monitor()`: 测试鼠标监控功能 + - `monitor_mouse_clicks()`: 监控鼠标点击并手动检测按钮 + - `check_button_click()`: 检查鼠标点击是否在按钮区域 + - `handle_mouse_click()`: 直接处理鼠标点击 + - `get_aspect2d_reference()`: 获取aspect2d引用 + - `create_step_text()`: 创建步骤显示文本 + - `create_tool_buttons()`: 创建工具选择按钮 + - `create_current_tool_text()`: 创建当前工具显示文本 + - `create_stop_button()`: 创建停止按钮 + - `create_warning_text()`: 创建警告文本 + - `button_press_handler()`: 按钮按下事件处理 + - `button_release_handler()`: 按钮释放事件处理 + - `on_tool_selected()`: 工具选择回调 + - `on_stop_clicked()`: 停止按钮点击回调 + - `update_tool_button_styles()`: 更新工具按钮样式 + - `update_step_info()`: 更新步骤信息 + - `show_warning()`: 显示警告信息 + - `hide_warning()`: 隐藏警告信息 + - `test_tool_selection()`: 测试工具选择功能 + - `test_specific_button()`: 测试特定按钮 + - `print_button_positions()`: 打印所有按钮的位置信息 + - `show_exam_results()`: 显示考核结果 + - `create_exam_result_gui()`: 创建考核结果GUI界面 + - `close_exam_results()`: 关闭考核结果界面 + - `start_countdown_timer()`: 启动10秒倒计时 + - `update_countdown()`: 更新倒计时显示 + - `get_current_tool()`: 获取当前选择的工具 + - `set_mode()`: 设置模式 + - `cleanup_gui()`: 清理GUI元素 + - `show_gui()`: 显示GUI + - `hide_gui()`: 隐藏GUI + +## 2.1.2 VR子模块 + +### 1. VR配置管理 (core/vr/config/) + +**文件**: vr_config.py +- **功能**: VR基础配置管理,负责VR设置的保存、加载和管理 +- **类**: VRConfigManager + - `__init__(self, config_dir=None)` - 初始化配置管理器 + - `load_config(self)` - 加载VR配置 + - `save_config(self, config)` - 保存VR配置 + - `get_render_mode(self)` - 获取渲染模式配置 + - `set_render_mode(self, mode)` - 设置渲染模式并保存 + - `get_resolution_scale(self)` - 获取分辨率缩放配置 + - `set_resolution_scale(self, scale)` - 设置分辨率缩放并保存 + - `get_quality_preset(self)` - 获取质量预设 + - `set_quality_preset(self, preset)` - 设置质量预设并保存 + - `get_pipeline_config(self)` - 获取RenderPipeline VR配置 + - `update_pipeline_config(self, pipeline_config)` - 更新RenderPipeline VR配置 + - `reset_to_defaults(self)` - 重置为默认配置 + - `apply_config_to_vr_manager(self, vr_manager)` - 将配置应用到VR管理器 + - `save_from_vr_manager(self, vr_manager)` - 从VR管理器保存当前配置 + +**文件**: joystick_config.py +- **功能**: VR摇杆配置管理,提供摇杆交互的配置选项和预设 +- **枚举**: TurnMode + - SMOOTH - 平滑转向 + - SNAP - 分段转向 +- **枚举**: JoystickProfile + - COMFORTABLE - 舒适模式 + - STANDARD - 标准模式 + - GAMING - 游戏模式 + - ACCESSIBLE - 无障碍模式 +- **类**: VRJoystickConfig + - `__init__(self)` - 初始化默认配置 + - `apply_profile(self, profile)` - 应用预设配置 + - `_apply_comfortable_profile(self)` - 舒适模式配置 + - `_apply_standard_profile(self)` - 标准模式配置 + - `_apply_gaming_profile(self)` - 游戏模式配置 + - `_apply_accessible_profile(self)` - 无障碍模式配置 + - `set_turn_mode(self, mode)` - 设置转向模式 + - `set_turn_sensitivity(self, sensitivity)` - 设置转向灵敏度 + - `set_deadzone(self, deadzone)` - 设置摇杆死区 + - `set_teleport_range(self, range_meters)` - 设置传送范围 + - `set_player_height(self, height_meters)` - 设置玩家站立高度偏移 + - `enable_haptic_feedback(self, enabled)` - 启用或禁用震动反馈 + - `get_config_dict(self)` - 获取配置字典 + - `apply_to_joystick_manager(self, joystick_manager)` - 将配置应用到摇杆管理器 +- **变量**: COMFORTABLE_CONFIG - 舒适模式预设配置实例 +- **变量**: STANDARD_CONFIG - 标准模式预设配置实例 +- **变量**: GAMING_CONFIG - 游戏模式预设配置实例 +- **变量**: ACCESSIBLE_CONFIG - 无障碍模式预设配置实例 +- **函数**: create_custom_config(**kwargs) - 创建自定义配置 +- **函数**: print_usage_guide() - 打印使用指南 + +**文件**: shadow_stage.py +- **功能**: VR专用阴影Stage,为VR渲染管线提供阴影支持 +- **类**: VRShadowStage + - `__init__(self, name, pipeline, use_shared_atlas=True)` - 初始化VR阴影Stage + - `create(self, width, height)` - 创建阴影Stage + - `_create_shared_shadow_atlas(self)` - 复用主Pipeline的ShadowAtlas + - `_create_independent_shadow_atlas(self, width, height)` - 为VR创建独立的ShadowAtlas + - `_make_pcf_state(self)` - 创建PCF采样器状态 + - `get_shadow_atlas_tex(self)` - 获取阴影Atlas纹理 + - `get_shadow_atlas_pcf(self)` - 获取带PCF的阴影Atlas + - `bind_to_stage(self, target_stage)` - 将阴影数据绑定到目标stage + - `cleanup(self)` - 清理资源 + +**文件**: __init__.py +- **功能**: VR配置子系统初始化文件 +- **变量**: __all__ - 导出模块列表 + +### 2. VR交互系统 (core/vr/interaction/) + +**文件**: actions.py +- **类**: VRActionManager + - `__init__(self, vr_manager)` - 初始化VR动作管理器 + - `initialize(self)` - 初始化VR动作系统 + - `_create_action_manifest(self)` - 创建VR动作清单文件 + - `_create_default_bindings(self, manifest_dir)` - 创建默认的控制器绑定文件 + - `_load_action_handles(self)` - 加载动作句柄 + - `_setup_action_sets(self)` - 设置动作集 + - `update_actions(self)` - 更新动作状态 + - `is_digital_action_pressed(self, action_name, device_path=None)` - 检查数字动作是否被按下 + - `is_digital_action_just_pressed(self, action_name, device_path=None)` - 检查数字动作是否刚刚被按下 + - `is_digital_action_just_released(self, action_name, device_path=None)` - 检查数字动作是否刚刚被释放 + - `get_analog_action_value(self, action_name, device_path=None)` - 获取模拟动作值 + - `get_pose_action_data(self, action_name, device_path=None)` - 获取姿态动作数据 + - `trigger_haptic_pulse(self, action_name, duration=0.001, frequency=1.0, amplitude=1.0, device_path=None)` - 触发震动反馈 + - `cleanup(self)` - 清理资源 + +**文件**: grab.py +- **类**: VRInteractionManager + - `__init__(self, vr_manager)` - 初始化VR交互管理器 + - `initialize(self)` - 初始化交互系统 + - `_create_ray_casters(self)` - 创建射线投射节点 + - `_create_controller_ray(self, controller_name, anchor_node)` - 为控制器创建射线投射节点 + - `_setup_collision_detection(self)` - 设置碰撞检测系统 + - `_setup_scene_collision_objects(self)` - 为场景对象设置碰撞体 + - `_add_collision_to_object(self, node_path)` - 为对象添加碰撞体 + - `update(self)` - 更新交互系统 + - `_perform_collision_detection(self)` - 执行碰撞检测 + - `_update_selections(self)` - 更新对象选择状态 + - `_get_closest_hit_object(self, controller_name)` - 获取指定控制器射线最近的碰撞对象 + - `_update_grabbing(self)` - 更新对象抓取状态 + - `_start_grab(self, controller, obj)` - 开始抓取对象 + - `_update_grabbed_object(self, controller)` - 更新被抓取对象的位置 + - `_release_grab(self, controller)` - 释放抓取的对象 + - `_highlight_object(self, obj, color)` - 高亮显示对象 + - `_restore_object_color(self, obj)` - 恢复对象原始颜色 + - `_clear_selection_highlights(self)` - 清除所有选择高亮 + - `get_selected_object(self, controller_name)` - 获取指定控制器选中的对象 + - `get_grabbed_object(self, controller_name)` - 获取指定控制器抓取的对象 + - `is_grabbing(self, controller_name)` - 检查指定控制器是否正在抓取对象 + - `force_release_all(self)` - 强制释放所有抓取的对象 + - `cleanup(self)` - 清理资源 + +**文件**: joystick.py +- **类**: JoystickState + - `__init__(self)` - 初始化摇杆状态 + - `update(self, new_input)` - 更新摇杆状态 + - `is_input_changed(self, threshold=0.01)` - 检查输入是否发生变化 +- **类**: VRJoystickManager + - `__init__(self, vr_manager)` - 初始化VR摇杆管理器 + - `initialize(self, teleport_system)` - 初始化摇杆系统 + - `update(self, dt)` - 更新摇杆系统 + - `_update_controller_joystick(self, controller, joystick_state, hand, dt)` - 更新单个控制器的摇杆状态 + - `_update_interaction_modes(self, dt)` - 更新互斥交互模式状态 + - `_set_controller_mode(self, hand, mode)` - 设置控制器交互模式 + - `_can_use_mode(self, hand, requested_mode)` - 检查是否可以使用指定的交互模式 + - `_get_joystick_input(self, controller, hand)` - 获取摇杆输入 + - `_apply_deadzone(self, input_vec)` - 应用摇杆死区 + - `_handle_turning(self, input_vec, hand, dt)` - 处理摇杆转向 + - `_apply_rotation(self, angle_degrees)` - 应用旋转到VR跟踪空间 + - `_handle_teleport(self, controller, input_vec, joystick_state, hand)` - 处理摇杆传送 + - `_calculate_teleport_direction(self, controller, input_vec)` - 计算传送方向向量 + - `_execute_teleport(self, controller)` - 执行传送 + - `set_turning_mode(self, smooth=True)` - 设置转向模式 + - `set_turn_sensitivity(self, sensitivity)` - 设置转向灵敏度 + - `apply_config(self, config)` - 应用配置 + - `get_current_config(self)` - 获取当前配置 + - `_print_debug_status(self)` - 打印调试状态信息 + - `cleanup(self)` - 清理摇杆系统资源 + +**文件**: teleport.py +- **类**: VRTeleportSystem + - `__init__(self, vr_manager)` - 初始化VR传送系统 + - `initialize(self)` - 初始化传送系统 + - `_create_teleport_visuals(self)` - 创建传送可视化元素 + - `_create_target_marker(self)` - 创建传送目标标记 + - `_create_invalid_marker(self)` - 创建无效位置标记 + - `_setup_ground_detection(self)` - 设置地面检测 + - `start_teleport_preview(self, controller, direction)` - 开始传送预览 + - `_calculate_teleport_trajectory(self, start_pos, direction)` - 计算传送抛物线轨迹 + - `_calculate_ground_intersection(self, p1, p2)` - 计算与地面的精确交点 + - `_create_arc_geometry(self, points)` - 创建抛物线几何体 + - `_show_teleport_visuals(self)` - 显示传送可视化 + - `stop_teleport_preview(self)` - 停止传送预览 + - `execute_teleport(self)` - 执行传送 + - `update_teleport_preview(self, controller, direction)` - 更新传送预览 + - `cleanup(self)` - 清理传送系统资源 + +### 3. VR性能优化 (core/vr/performance/) + +**文件**: monitoring.py +- **类**: VRPerformanceMonitor + - `__init__(self, vr_manager)` - 初始化性能监控系统 + - `_init_performance_monitoring(self)` - 初始化性能监控库 + - `_update_performance_metrics(self)` - 更新系统性能指标 + - `_update_gpu_metrics(self)` - 更新GPU相关指标 + - `_track_frame_time(self)` - 记录帧时间 + - `_get_gpu_frame_timing(self, frames_ago=0)` - 获取GPU渲染时间统计 + - `enable_gpu_timing_monitoring(self)` - 启用GPU时间监控 + - `disable_gpu_timing_monitoring(self)` - 禁用GPU时间监控 + - `_start_timing(self, operation_name)` - 开始计时操作 + - `_end_timing(self, timing_data)` - 结束计时并记录结果 + - `_get_pipeline_stats(self)` - 获取渲染管线统计信息 + - `test_pipeline_monitoring(self)` - 测试管线监控功能 + - `set_prediction_time(self, prediction_time_ms)` - 设置预测时间 + - `_print_render_callback_diagnostics(self)` - 输出渲染回调诊断信息 + - `_check_rendering_optimizations(self)` - 检查渲染优化状态 + - `_diagnose_opengl_state(self)` - 诊断OpenGL渲染状态 + - `enable_debug_output(self)` - 启用调试输出 + - `disable_debug_output(self)` - 禁用调试输出 + - `set_debug_mode(self, mode)` - 设置调试模式 + - `toggle_debug_output(self)` - 切换调试输出状态 + - `get_debug_status(self)` - 获取调试状态 + - `set_performance_check_interval(self, interval)` - 设置性能检查间隔 + - `set_frame_time_history_size(self, size)` - 设置帧时间历史记录大小 + - `set_performance_report_interval(self, frames)` - 设置性能报告输出间隔 + - `get_performance_stats(self)` - 获取详细的性能统计信息 + - `get_current_performance_summary(self)` - 获取当前性能摘要 + - `get_performance_monitoring_config(self)` - 获取当前性能监控配置 + - `print_performance_monitoring_status(self)` - 输出性能监控状态 + - `enable_performance_monitoring(self)` - 启用性能监控 + - `disable_performance_monitoring(self)` - 禁用性能监控 + - `force_performance_report(self)` - 强制输出一次性能报告 + - `reset_performance_counters(self)` - 重置性能计数器 + +**文件**: optimization.py +- **类**: VROptimization + - `__init__(self, vr_manager)` - 初始化VR优化系统 + - `_initialize_object_pools(self)` - 初始化对象池 + - `_get_pooled_matrix(self)` - 从对象池获取Mat4对象 + - `_return_pooled_matrix(self, matrix)` - 将Mat4对象返回对象池 + - `_manual_gc_control(self)` - 手动垃圾回收控制 + - `enable_gc_control(self)` - 启用垃圾回收控制 + - `disable_gc_control(self)` - 禁用垃圾回收控制 + - `set_manual_gc_interval(self, frames)` - 设置手动垃圾回收间隔 + - `force_manual_gc(self)` - 强制执行一次垃圾回收 + - `get_object_pool_status(self)` - 获取对象池状态 + - `set_resolution_scale(self, scale)` - 设置VR分辨率缩放系数 + - `set_quality_preset(self, preset_name)` - 设置VR质量预设 + - `cycle_quality_preset(self)` - 循环切换质量预设 + - `_apply_resolution_scale(self)` - 应用分辨率缩放,重新创建VR缓冲区 + - `get_resolution_info(self)` - 获取分辨率相关信息 + - `print_resolution_info(self)` - 输出分辨率信息 + - `enable_performance_mode(self)` - 手动启用性能模式 + - `disable_performance_mode(self)` - 禁用性能模式 + - `set_performance_mode_trigger_frame(self, frame_count)` - 设置性能模式自动触发的帧数 + - `get_performance_mode_status(self)` - 获取性能模式状态 + +### 4. VR渲染系统 (core/vr/rendering/) + +**文件**: stages.py +- **函数**: _load_rp_shader(shader_name) - 加载RenderPipeline shader +- **类**: VRGBufferStage + - `__init__(self, name, pipeline)` - 初始化VR GBuffer Stage + - `create(self, width, height, vr_camera)` - 创建GBuffer渲染目标 + - `get_gbuffer_textures(self)` - 获取GBuffer纹理字典 + - `make_gbuffer_ubo(self)` - 创建GBuffer UBO + - `get_internal_buffer(self)` - 获取内部GraphicsOutput + - `cleanup(self)` - 清理资源 +- **类**: VRLightingStage + - `__init__(self, name, pipeline)` - 初始化VR光照Stage + - `create(self, width, height, gbuffer_stage)` - 创建光照渲染目标 + - `_bind_pipeline_inputs(self)` - 从主Pipeline获取光照相关shader inputs + - `_bind_pipeline_pipes(self)` - 从主Pipeline获取光照相关pipes + - `_set_vr_scene_data(self)` - 创建VR专用的MainSceneData UBO + - `get_shaded_texture(self)` - 获取光照计算后的纹理 + - `cleanup(self)` - 清理资源 +- **类**: VRAmbientStage + - `__init__(self, name, pipeline)` - 初始化VR环境光Stage + - `create(self, width, height, lighting_stage, gbuffer_stage)` - 创建环境光渲染目标 + - `_bind_environment_inputs(self)` - 从主Pipeline获取环境相关shader inputs + - `_set_vr_scene_data(self)` - 创建VR专用的MainSceneData UBO + - `get_ambient_scene_texture(self)` - 获取带环境光的场景纹理 + - `cleanup(self)` - 清理资源 +- **类**: VRFinalStage + - `__init__(self, name, pipeline)` - 初始化VR最终合成Stage + - `create(self, width, height, ambient_stage)` - 创建最终合成目标 + - `_set_vr_scene_data(self)` - 创建VR专用的MainSceneData UBO + - `get_final_texture(self)` - 获取最终输出纹理 + - `get_internal_buffer(self)` - 获取内部GraphicsOutput + - `cleanup(self)` - 清理资源 +- **类**: VRPipelineController + - `__init__(self, pipeline)` - 初始化VR Pipeline控制器 + - `create_eye_pipeline(self, eye_name, width, height, vr_camera)` - 为单个眼睛创建完整的渲染管线 + - `create_stereo_pipeline(self, width, height, left_camera, right_camera)` - 创建立体渲染管线 + - `get_left_textures(self)` - 获取左眼的所有纹理 + - `get_right_textures(self)` - 获取右眼的所有纹理 + - `get_left_buffer(self)` - 获取左眼Final stage的内部buffer + - `get_right_buffer(self)` - 获取右眼Final stage的内部buffer + - `cleanup_left(self)` - 清理左眼资源 + - `cleanup_right(self)` - 清理右眼资源 + - `cleanup_all(self)` - 清理所有VR渲染资源 + +### 5. VR测试调试 (core/vr/testing/) + +**文件**: test_mode.py +- **类**: VRTestMode + - `__init__(self, vr_manager)` - 初始化VR测试模式系统 + - `enable_vr_test_mode(self, display_mode='stereo')` - 启用VR测试模式 + - `disable_vr_test_mode(self)` - 禁用VR测试模式 + - `switch_test_display_mode(self, display_mode)` - 切换测试显示模式 + - `_ensure_test_mode_textures(self)` - 确保VR测试模式的纹理资源已正确初始化 + - `_create_cached_ovr_textures(self)` - 创建缓存的OpenVR Texture对象 + - `_initialize_test_display(self)` - 初始化测试显示系统 + - `_update_test_display(self)` - 更新测试显示内容 + - `_create_stereo_display(self)` - 创建左右眼并排显示 + - `_cleanup_test_display(self)` - 清理测试显示 + - `_initialize_test_performance_hud(self)` - 初始化性能HUD + - `_update_test_performance_hud(self)` - 更新性能HUD显示 + - `_cleanup_test_performance_hud(self)` - 清理性能HUD + - `get_test_mode_status(self)` - 获取测试模式状态 + - `get_test_mode_features(self)` - 获取当前测试模式功能设置 + - `set_test_mode_features(self, submit_texture=None, wait_poses=None)` - 设置测试模式功能开关 + - `run_vr_performance_test(self, duration_seconds=30, display_mode='stereo')` - 运行VR性能测试 + +### 6. VR跟踪系统 (core/vr/tracking/) + +**文件**: controllers.py +- **类**: VRController + - `__init__(self, vr_manager, name, hand_path, device_index=None)` - 初始化VR手柄 + - `_create_anchor(self)` - 创建手柄锚点节点 + - `_create_visualizer(self)` - 创建手柄可视化器 + - `set_device_index(self, device_index)` - 设置OpenVR设备索引 + - `update_pose(self, pose_data)` - 更新手柄姿态 + - `update_input_state(self, vr_system)` - 更新输入状态 + - `is_button_pressed(self, button_id)` - 检查按钮是否被按下 + - `is_button_just_pressed(self, button_id)` - 检查按钮是否刚刚被按下 + - `is_button_just_released(self, button_id)` - 检查按钮是否刚刚被释放 + - `is_trigger_pressed(self, threshold=0.1)` - 检查扳机是否被按下 + - `is_grip_pressed(self, threshold=0.1)` - 检查握把是否被按下 + - `show_ray(self, show=True)` - 显示或隐藏交互射线 + - `set_ray_color(self, color)` - 设置射线颜色 + - `trigger_haptic_feedback(self, duration=0.001, strength=1.0)` - 触发震动反馈 + - `get_world_position(self)` - 获取手柄在世界坐标系中的位置 + - `get_world_rotation(self)` - 获取手柄在世界坐标系中的旋转 + - `get_forward_direction(self)` - 获取手柄指向的方向向量 + - `is_joystick_touched(self)` - 检查摇杆是否被触摸 + - `is_joystick_pressed(self)` - 检查摇杆是否被按下 + - `get_joystick_position(self)` - 获取摇杆位置 + - `get_joystick_delta(self)` - 获取摇杆位置变化 + - `is_joystick_moved(self, threshold=0.01)` - 检查摇杆是否移动 + - `_debug_axis_data(self, axis_data)` - 调试输出轴数据 + - `recreate_visualizer(self)` - 重新创建visualizer + - `cleanup(self)` - 清理资源 +- **类**: LeftController - 左手控制器 +- **类**: RightController - 右手控制器 + +### 7. VR可视化系统 (core/vr/visualization/) + +**文件**: controllers.py +- **类**: VRControllerVisualizer + - `__init__(self, controller, render_node)` - 初始化手柄可视化器 + - `_create_visual_components(self)` - 创建可视化组件 + - `_create_controller_model(self)` - 创建手柄3D模型 + - `_load_steamvr_model(self)` - 加载SteamVR官方手柄模型 + - `_fix_model_material(self, model)` - 修复模型材质 + - `_apply_controller_identity_marker(self, model)` - 为控制器添加身份标记 + - `_apply_steamvr_textures(self, model, base_path)` - 为SteamVR模型应用纹理 + - `_load_combined_steamvr_model(self, base_path)` - 尝试组合加载多个SteamVR模型部件 + - `_create_fallback_model(self)` - 创建改进的程序化手柄模型作为后备方案 + - `_create_box_geometry(self, width, length, height)` - 创建立方体几何体 + - `_create_disc_geometry(self, radius, thickness)` - 创建圆盘几何体 + - `_create_interaction_ray(self)` - 创建交互射线 + - `_create_sphere_geometry(self, radius)` - 创建球体几何体 + - `_create_button_indicators(self)` - 创建按钮状态指示器 + - `update(self)` - 更新可视化状态 + - `_update_button_indicators(self)` - 更新按钮指示器状态 + - `_update_ray_display(self)` - 更新射线显示 + - `show(self)` - 显示手柄可视化 + - `hide(self)` - 隐藏手柄可视化 + - `show_ray(self)` - 显示交互射线 + - `hide_ray(self)` - 隐藏交互射线 + - `set_ray_color(self, color)` - 设置射线颜色 + - `set_ray_length(self, length)` - 设置射线长度 + - `_apply_render_mode_settings(self, model_node)` - 根据当前渲染模式应用渲染设置 + - `_set_always_on_top(self, model_node)` - 设置手柄模型始终显示在上层 + - `cleanup(self)` - 清理资源 + +**文件**: effects.py +- **类**: VREffectsManager + - `__init__(self, pipeline)` - 初始化VR Effects Manager + - `apply_effects_to_scene(self, scene_root)` - 为场景根节点下的所有模型应用effects + - `apply_effect_to_model(self, model_node, effect_config=None)` - 为单个模型节点应用RenderPipeline effect + - `apply_effect_to_model_simple(self, model_node)` - 为模型应用简化版effect + - `_should_apply_effect(self, node)` - 判断是否应该为节点应用effect + - `apply_effects_to_new_models(self, model_list)` - 为新添加的模型列表批量应用effects + - `update_effect_config(self, new_config)` - 更新默认effect配置 + - `get_applied_models_count(self)` - 获取已应用effects的模型数量 + - `clear_applied_models_cache(self)` - 清空已应用模型的缓存 +- **函数**: setup_vr_model_effects(world, vr_root=None) - 便捷函数:为VR场景设置RenderPipeline Effects + +### 8. VR主管理器 (core/vr_manager.py) + +**枚举**: VRRenderMode +- NORMAL - 普通渲染模式 +- RENDER_PIPELINE - RenderPipeline高级渲染模式 + +**类**: VRManager +- `__init__(self, world)` - 初始化VR管理器 +- `convert_mat(self, mat)` - 将OpenVR矩阵转换为Panda3D矩阵 +- `is_vr_available(self)` - 检查VR系统是否可用 +- `initialize_vr(self)` - 初始化VR系统 +- `_create_vr_buffers(self)` - 创建VR渲染缓冲区 +- `_create_vr_texture(self, name)` - 创建VR纹理对象 +- `_prepare_and_cache_textures(self)` - 准备纹理并缓存OpenGL ID +- `_create_vr_buffer(self, name, texture, width, height)` - 创建VR渲染缓冲区 +- `_diagnose_buffer_performance(self, buffer, name, width, height)` - 诊断VR缓冲区性能特性 +- `_create_vr_buffers_with_pipeline(self)` - 创建带RenderPipeline的VR渲染缓冲区 +- `_apply_pipeline_vr_effects(self)` - 为VR场景应用RenderPipeline效果配置 +- `_check_skybox_status(self)` - 检查并报告天空盒状态 +- `_create_vr_skybox(self)` - 为VR创建天空盒 +- `_setup_vr_cameras(self)` - 设置VR相机 +- `_get_eye_offset(self, eye)` - 获取眼睛相对于头显的偏移 +- `_optimize_vr_rendering(self)` - 优化VR模式下的渲染管线 +- `_apply_lightweight_rendering(self, buffer, eye_name)` - 为VR缓冲区应用轻量级渲染设置 +- `_disable_vr_buffer_extras(self)` - 禁用VR缓冲区的额外功能以提升性能 +- `_start_vr_task(self)` - 启动VR更新任务 +- `_update_vr(self, task)` - VR更新任务 +- `_sync_gpu_if_needed(self)` - 可选的GPU同步 +- `simple_left_cb(self, cbdata)` - 简化的左眼渲染回调 +- `simple_right_cb(self, cbdata)` - 简化的右眼渲染回调 +- `_wait_get_poses(self)` - 调用VRCompositor的waitGetPoses来获取焦点和姿态数据 +- `_wait_get_poses_immediate(self)` - 立即获取VR姿态 +- `_wait_get_poses_with_prediction(self)` - 使用预测时间获取VR姿态 +- `_cache_poses_for_next_frame(self)` - 缓存当前姿态供下一帧渲染使用 +- `_reset_waitgetposes_flag(self, task)` - 重置WaitGetPoses标记 +- `_update_tracking_data(self)` - 更新VR追踪数据 +- `_convert_openvr_matrix_to_panda(self, ovr_matrix)` - 将OpenVR矩阵转换为Panda3D矩阵 +- `update_hmd(self, pose)` - 更新HMD锚点 +- `_update_camera_poses(self)` - 更新相机姿态 +- `_update_camera_poses_with_cache(self)` - 使用缓存姿态更新相机 +- `enable_vr(self)` - 启用VR模式 +- `disable_vr(self)` - 禁用VR模式 +- `set_vr_render_mode(self, mode)` - 切换VR渲染模式 +- `get_vr_render_mode(self)` - 获取当前VR渲染模式 +- `_cleanup_vr_buffers(self)` - 清理VR渲染缓冲区 +- `cleanup(self)` - 清理VR资源 +- `get_vr_status(self)` - 获取VR状态信息 +- `submit_texture(self, eye, texture)` - 优化的VR纹理提交 +- `_smart_gpu_sync(self)` - 智能GPU同步策略 +- `_disable_main_cam(self)` - 禁用主相机 +- `_enable_main_cam(self)` - 恢复主相机 +- `_initialize_controllers(self)` - 初始化VR手柄控制器 +- `_detect_controllers(self)` - 检测并连接VR控制器 +- `_create_tracked_device_anchor(self, device_index, name)` - 为跟踪设备创建锚点节点 +- `update_tracked_devices(self)` - 更新所有跟踪设备的姿态 +- `get_controller_by_role(self, role)` - 根据角色获取控制器 +- `are_controllers_connected(self)` - 检查是否有控制器连接 +- `get_connected_controllers(self)` - 获取所有连接的控制器列表 +- `trigger_controller_haptic(self, role, duration=0.001, strength=1.0)` - 触发控制器震动反馈 +- `is_trigger_pressed(self, hand='any')` - 检查扳机是否被按下 +- `is_trigger_just_pressed(self, hand='any')` - 检查扳机是否刚刚被按下 +- `is_grip_pressed(self, hand='any')` - 检查握把是否被按下 +- `is_grip_just_pressed(self, hand='any')` - 检查握把是否刚刚被按下 +- `is_menu_pressed(self, hand='any')` - 检查菜单按钮是否被按下 +- `is_trackpad_touched(self, hand='any')` - 检查触摸板是否被触摸 +- `get_trackpad_position(self, hand='any')` - 获取触摸板位置 +- `get_selected_object(self, hand='any')` - 获取指定手选中的对象 +- `get_grabbed_object(self, hand='any')` - 获取指定手抓取的对象 +- `is_grabbing_object(self, hand='any')` - 检查是否正在抓取对象 +- `force_release_all_grabs(self)` - 强制释放所有抓取的对象 +- `add_interactable_object(self, object_node)` - 将对象标记为可交互 +- `_disable_async_reprojection(self)` - 禁用异步重投影 +- `enable_async_reprojection_disable(self)` - 启用异步重投影禁用选项 +- `disable_async_reprojection_disable(self)` - 禁用异步重投影禁用选项 +- `_batch_submit_textures(self)` - 批量提交两眼纹理 + +## 2.2 gui模块 + +### 1. `gui/__init__.py` +- **功能**: GUI模块初始化文件,导出GUI管理器类 +- **类**: + - `GUIManager`: GUI管理器类 + +### 2. `gui/gui_manager.py` +- **功能**: GUI管理器模块,负责2D和3D GUI元素的创建和管理 +- **类**: + - `GUIManager`: GUI管理器类 +- **方法**: + - `__init__()`: 初始化GUI管理系统 + - `createGUIButton()`: 创建2D GUI按钮 + - `createGUILabel()`: 创建2D GUI标签 + - `createGUIEntry()`: 创建2D GUI文本输入框 + - `createGUI2DImage()`: 创建2D GUI图片 + - `constrain2DPosition()`: 限制2dGUI元素位置在屏幕范围内 + - `createGUI3DText()`: 创建3D空间文本 + - `createGUI3DImage()`: 创建3D空间图片 + - `createVideoScreen()`: 创建3D视频播放屏幕 + - `_ensureVideoScreenMaterial()`: 确保视频屏幕有正确的材质设置 + - `_debugVideoScreenTextures()`: 调试视频屏幕的纹理状态 + - `playVideo()`: 播放视频 + - `_getMovieTextureFromScreen()`: 从视频屏幕获取视频纹理 + - `pauseVideo()`: 暂停视频 + - `stopVideo()`: 停止视频 + - `setVideoTime()`: 设置视频播放时间 + - `loadVideoFile()`: 为视频屏幕加载新的视频文件 + - `_loadMovieTexture()`: 加载视频纹理的兼容方法 + - `_configureVideoTexture()`: 配置视频纹理属性 + - `createGUI2DVideoScreen()`: 创建2D视频播放屏幕 + - `load2DVideoFile()`: 为2D视频屏幕加载新的视频文件 + - `play2DVideo()`: 播放2D视频 + - `pause2DVideo()`: 暂停2D视频 + - `stop2DVideo()`: 停止2D视频 + - `createSphericalVideo()`: 创建球形视频(360度视频) + - `_createSphereGeometry()`: 创建球形几何体 + - `playSphericalVideo()`: 播放球形视频 + - `pauseSphericalVideo()`: 暂停球形视频 + - `setSphericalVideoTime()`: 设置球形视频播放时间 + - `createGUIVirtualScreen()`: 创建3D虚拟屏幕 + - `_create_screen_text()`: 为虚拟屏幕创建文本节点 + - `_get_tree_widget()`: 安全获取树形控件 + - `createGUISlider()`: 创建2D GUI滑块 + - `deleteGUIElement()`: 删除GUI元素 + - `editGUIElement()`: 编辑GUI元素属性 + - `_resizeButtonToText()`: 根据文本内容调整按钮大小 + - `duplicateGUIElement()`: 复制GUI元素 + - `editGUIElementDialog()`: 显示GUI元素编辑对话框 + - `onGUIButtonClick()`: GUI按钮点击事件处理 + - `onGUIEntrySubmit()`: GUI输入框提交事件处理 + - `toggleGUIEditMode()`: 切换GUI编辑模式 + - `enterGUIEditMode()`: 进入GUI编辑模式 + - `exitGUIEditMode()`: 退出GUI编辑模式 + - `createGUIEditPanel()`: 创建GUI编辑面板 + - `openGUIPreviewWindow()`: 打开独立的GUI预览窗口 + - `closeGUIPreviewWindow()`: 关闭GUI预览窗口 + - `setGUICreateTool()`: 设置GUI创建工具 + - `deleteSelectedGUI()`: 删除选中的GUI元素 + - `copySelectedGUI()`: 复制选中的GUI元素 + - `handleGUIEditClick()`: 处理GUI编辑模式下的点击 + - `createGUIAtPosition()`: 在指定位置创建GUI元素 + - `findClickedGUI()`: 查找被点击的GUI元素 + - `selectGUIInTree()`: 在树形控件中选中GUI元素 + - `updateGUISelection()`: 更新GUI元素选择状态 + - `updateGUIPropertyPanel()`: 更新GUI元素属性面板 + - `selectGUIColor()`: 选择GUI元素颜色 + - `update3DImageTexture()`: 更新3D图像纹理 + - `_preserveChildNodeTextures()`: 保护子节点的纹理不被父节点纹理影响 + - `_is3DTextElement()`: 检查节点是否为3D文本元素 + - `_isOtherSpecialElement()`: 检查节点是否为其他需要特殊处理的元素 + - `_restore3DTextTexture()`: 恢复3D文本的纹理设置 + - `update2DImageTexture()`: 更新2D图片纹理 + - `editGUI2DPosition()`: 编辑2D GUI元素位置并应用边界约束 + - `editGUI3DPosition()`: 编辑3D GUI元素位置 + - `editGUIScale()`: 编辑GUI元素缩放 + - `createCesiumView()`: 创建 Cesium 视图窗口(离线版本) + - `toggleCesiumView()`: 切换 Cesium 视图显示状态 + - `refreshCesiumView()`: 刷新 Cesium 视图 + - `updateCesiumURL()`: 更新 Cesium 视图的 URL + - `addModelToCesium()`: 向 Cesium 添加模型 + - `addCesiumTilesetToScene()`: 在 Panda3D 场景中添加 Cesium 3D Tiles + - `removeModelFromCesium()`: 从 Cesium 移除模型 + - `updateCesiumModelPosition()`: 更新 Cesium 中模型的位置 + - `getAllCesiumModels()`: 获取 Cesium 中所有模型的列表 + - `addLocalModelToCesium()`: 向 Cesium 添加本地模型文件 + +## 2.3 project模块 + +### 1. `project/__init__.py` +- **功能**: 项目管理模块初始化文件,导出项目管理器类和新建项目对话框 +- **类**: + - `ProjectManager`: 项目管理器类 + - `NewProjectDialog`: 新建项目对话框类 + +### 2. `project/project_manager.py` +- **功能**: 项目管理器模块,负责项目的生命周期管理,处理项目创建、打开、保存、打包等功能 +- **类**: + - `ProjectManager`: 项目管理器类 +- **方法**: + - `__init__()`: 初始化项目管理器 + - `createNewProject()`: 创建新项目 + - `openProject()`: 打开项目 + - `openProjectForPath()`: 通过路径打开项目 + - `saveProject()`: 保存项目 + - `buildPackage()`: 打包项目为可执行文件 + - `_createStandardBuildFiles()`: 创建标准的Panda3D打包文件 + - `_copyScriptsToBuild()`: 复制脚本文件到构建目录的scripts文件夹 + - `_copyScriptSystemToBuild()`: 复制脚本系统文件到构建目录 + - `_saveGUIElementsToJSON()`: 保存GUI元素到JSON文件 + - `_updateResourcePaths()`: 更新资源路径 + - `_createRequirementsFile()`: 创建requirements.txt文件 + - `copy_folder()`: 将一个文件夹从源路径复制到目标路径下的resources文件夹中 + - `_copyResourcesToBuild()`: 复制GUI资源到构建目录的resources文件夹 + - `_collectResourceFiles()`: 收集项目中GUI使用的资源文件 + - `_extractResourcesFromScene()`: 从场景文件中提取资源引用 + - `_isMediaFile()`: 判断是否为媒体文件(图片或视频) + - `_createAppFile()`: 创建应用程序主文件 + - `_createStandardSetupFile()`: 创建优化的标准setup.py文件 + - `_executeStandardBuild()`: 执行标准的Panda3D打包命令 + - `_tryBuildAppsThreaded()`: 尝试使用 build_apps 命令(线程安全版本) + - `_tryBuildApps()`: 尝试使用 build_apps 命令 + - `updateWindowTitle()`: 更新窗口标题 + - `_clearCurrentScene()`: 清空当前场景 + - `getCurrentProjectPath()`: 获取当前项目路径 + - `getCurrentProjectConfig()`: 获取当前项目配置 + - `isProjectOpen()`: 检查是否有项目打开 + - `getProjectName()`: 获取当前项目名称 + - `getProjectInfo()`: 获取项目信息 + +## 2.4 QPanda3D模块 + +### 1. `QPanda3D/__init__.py` +- **功能**: QPanda3D模块初始化文件,导出核心类 +- **类**: + - 无 +- **方法**: + - 无 +- **导出项**: + - `QPanda3DWidget`: QPanda3D部件类 + - `Panda3DWorld`: Panda3D世界类 + - `QPanda3D_Keys_Translation`: 键盘事件翻译类 + +### 2. `QPanda3D/Panda3DWorld.py` +- **功能**: Panda3D世界类,处理Panda3D环境设置和渲染管理 +- **类**: + - `Panda3DWorld`: Panda3D世界类,继承自ShowBase +- **方法**: + - `__init__(self, width=1380, height=750, is_fullscreen=False, size=1.0, clear_color=LVecBase4f(0, 0.5, 0, 1), name="qpanda3D")`: 初始化Panda3D世界 + - `_handle_transform_error(self)`: 处理TransformState相关的错误 + - `render_pipeline(self)`: 获取RenderPipeline实例 + - `set_parent(self, parent: QWidget)`: 设置父部件 + - `getAspectRatio(self, win = None)`: 获取宽高比 + - `resize_buffer(self, width: int, height: int)`: 根据新窗口尺寸调整Panda3D渲染输出尺寸 + +### 3. `QPanda3D/QPanda3DWidget.py` +- **功能**: QPanda3D部件类,作为Panda3D内容在Qt应用程序中的容器 +- **类**: + - `QPanda3DSynchronizer`: Panda3D同步器类,继承自QTimer + - `QPanda3DWidget`: QPanda3D部件类,继承自QWidget +- **方法**: + - `QPanda3DSynchronizer.__init__(self, qPanda3DWidget, FPS=60)`: 初始化同步器 + - `QPanda3DSynchronizer.tick(self)`: 同步器定时更新方法 + - `get_panda_key_modifiers(evt)`: 获取Panda3D按键修饰符 + - `get_panda_key_modifiers_prefix(evt)`: 获取Panda3D按键修饰符前缀 + - `QPanda3DWidget.__init__(self, panda3DWorld, parent=None, FPS=60, debug=False)`: 初始化QPanda3D部件 + - `QPanda3DWidget.mousePressEvent(self, evt)`: 鼠标按下事件处理 + - `QPanda3DWidget.mouseMoveEvent(self, evt:QtGui.QMouseEvent)`: 鼠标移动事件处理 + - `QPanda3DWidget.mouseReleaseEvent(self, evt)`: 鼠标释放事件处理 + - `QPanda3DWidget.wheelEvent(self, evt)`: 鼠标滚轮事件处理 + - `QPanda3DWidget.keyPressEvent(self, evt)`: 键盘按下事件处理 + - `QPanda3DWidget.keyReleaseEvent(self, evt)`: 键盘释放事件处理 + - `QPanda3DWidget.resizeEvent(self, evt)`: 窗口大小调整事件处理 + - `QPanda3DWidget.minimumSizeHint(self)`: 最小尺寸提示 + - `QPanda3DWidget.paintEvent(self, event)`: 绘制事件处理 + - `QPanda3DWidget.sync_panda3d_window_size(self, width, height)`: 同步Panda3D窗口尺寸到Qt窗口尺寸 + +### 4. `QPanda3D/QMouseWatcherNode.py` +- **功能**: 鼠标观察节点类,通过父级QWidget访问鼠标位置和按钮状态 +- **类**: + - `QMouseWatcherNode`: 鼠标观察节点类,继承自MouseWatcher +- **方法**: + - `__init__(self, parent)`: 初始化鼠标观察节点 + - `getMouse(self, *args, **kwargs)`: 获取鼠标位置 + - `hasMouse(self)`: 检查是否有鼠标 + +### 5. `QPanda3D/QPanda3D_Keys_Translation.py` +- **功能**: 键盘事件翻译字典,将Qt键盘事件翻译为Panda3D键盘事件 +- **类**: + - 无 +- **方法**: + - 无 +- **变量**: + - `QPanda3D_Key_translation`: Qt到Panda3D键盘事件的翻译字典 + +### 6. `QPanda3D/QPanda3D_Buttons_Translation.py` +- **功能**: 鼠标事件翻译字典,将Qt鼠标事件翻译为Panda3D鼠标事件 +- **类**: + - 无 +- **方法**: + - 无 +- **变量**: + - `QPanda3D_Button_translation`: Qt到Panda3D鼠标事件的翻译字典 + +### 7. `QPanda3D/QPanda3D_Modifiers_Translation.py` +- **功能**: 键盘修饰符翻译字典,将Qt键盘事件翻译为Panda3D键盘事件 +- **类**: + - 无 +- **方法**: + - 无 +- **变量**: + - `QPanda3D_Modifier_translation`: Qt到Panda3D键盘修饰符的翻译字典 + +### 8. `QPanda3D/Helpers/__init__.py` +- **功能**: QPanda3D辅助模块初始化文件,导出辅助类 +- **类**: + - 无 +- **方法**: + - 无 +- **导出项**: + - `Env_Grid_Maker`: 环境网格生成器类 + +### 9. `QPanda3D/Helpers/Env_Grid_Maker.py` +- **功能**: 环境网格生成器,创建3D网格实现以显示坐标轴 +- **类**: + - `Env_Grid_Maker`: 环境网格生成器类 +- **方法**: + - `__init__(self, XYPlaneShow = True, XZPlaneShow = False, YZPlaneShow = False, endCapLinesShow = True, XSize = 50, YSize = 50, ZSize = 50, gridStep = 10, subdiv = 10)`: 初始化环境网格生成器 + - `create(self)`: 创建网格 + - `myfrange(self, start, stop=None, step=None)`: 浮点数范围生成器 + +### 10. `QPanda3D/Tools/__init__.py` +- **功能**: QPanda3D工具模块初始化文件,导出工具类 +- **类**: + - 无 +- **方法**: + - 无 +- **导出项**: + - `generate_qt_to_pd3d_translator`: Qt到Panda3D翻译生成器 + +### 11. `QPanda3D/Tools/generate_qt_to_pd3d_translator.py` +- **功能**: 生成Qt到Panda3D事件翻译的工具脚本 +- **类**: + - 无 +- **方法**: + - 无 +- **变量**: + - `H`: Qt模块字典 + - `lst`: 以"Key_"开头的Qt键列表 + - `QPanda3D_Key_translation`: 生成的Qt到Panda3D键盘事件翻译字符串 + +## 2.5 scene模块 + +### 1. `scene/__init__.py` +- **功能**: scene模块初始化文件,导出场景管理器类 +- **类**: + - `SceneManager`: 场景管理器类 +- **方法**: + - 无 + +### 2. `scene/scene_manager.py` +- **功能**: 场景管理器模块,负责场景和模型管理的核心功能,处理模型导入、场景树构建、材质系统、碰撞设置等 +- **类**: + - `SceneManager`: 场景管理器类 + - `CesiumIntegration`: Cesium集成类 +- **方法**: + - `__init__(self, world)`: 初始化场景管理器 + - `importModel(self, filepath, apply_unit_conversion=False, normalize_scales=True, auto_convert_to_glb=True)`: 导入模型 + - `_fixModelStructure(self, model)`: 修复模型结构 + - `_validateAndFixAllTransforms(self, model)`: 验证并修复模型中所有节点的变换矩阵 + - `_validateAndFixTransform(self, node_path)`: 验证并修复单个节点的变换矩阵 + - `_applyModelScale(self, model, scale_factor)`: 应用模型特定缩放 + - `_applyMaterialsToModel(self, model)`: 递归应用材质到模型的所有GeomNode + - `_adjustModelToGround(self, model)`: 智能调整模型到地面,但保持原有缩放结构 + - `_normalizeModelScales(self, model)`: 智能标准化模型缩放层级 + - `_collectScaleInfo(self, node, scale_info, depth=0)`: 递归收集节点缩放信息 + - `_findCommonLargeScale(self, large_scales)`: 找到最常见的大缩放值 + - `_applyScaleNormalization(self, node, normalize_factor, depth=0)`: 安全地应用缩放标准化 + - `importModelAsync(self, filepath)`: 异步导入模型 + - `processMaterials(self, model)`: 处理模型材质 + - `processModelGeometry(self, model)`: 处理模型几何体 + - `setupCollision(self, model)`: 为模型设置碰撞检测(增强版本) + - `updateSceneTree(self)`: 更新场景树显示 - 代理到interface_manager + - `_collectGUIElementInfo(self, gui_node)`: 收集GUI元素的信息用于保存 + - `_get_script_file_path(self, script_class, script_name)`: 获取脚本文件路径的可靠方法 + - `saveScene(self, filename, project_path)`: 保存场景到BAM文件 - 完整版,支持GUI元素,地形 + - `take_screenshot(self, projectpath)`: 截图并保存到指定的完整路径 + - `loadScene(self, filename)`: 从BAM文件加载场景 + - `_rebuildParentChildRelationships(self, loaded_nodes)`: 重建父子关系 + - `_inferParentChildRelationships(self, loaded_nodes)`: 从场景结构推断父子关系 + - `_shouldSkipNodeInTree(self, nodePath)`: 判断节点是否应该在场景树中跳过显示 + - `_recreateGUIElementsFromData(self, gui_data)`: 根据保存的GUI数据重新创建GUI元素 + - `_findOrCreateQtTreeItem(self, tree_widget, target_element, element_name)`: 在Qt树中查找或创建指定元素对应的项 + - `_findQtTreeItem(self, tree_widget, target_element)`: 在Qt树中查找指定元素对应的项 + - `_find_script_in_directory(self, script_name)`: 在脚本目录中查找脚本文件 + - `_recreateSpotLight(self, light_node)`: 重新创建聚光灯 + - `_recreatePointLight(self, light_node)`: 重新创建点光源 + - `_cleanupAuxiliaryNodes(self)`: 清理场景中可能存在的辅助节点 + - `deleteModel(self, model)`: 删除模型 + - `clearAllModels(self)`: 清除所有模型 + - `getModels(self)`: 获取模型列表 + - `getModelCount(self)`: 获取模型数量 + - `findModelByName(self, name)`: 根据名称查找模型 + - `processLoadedModel(self, model)`: 处理加载完成的模型(用于异步加载回调) + - `createSpotLight(self, pos=(0, 0, 0))`: 创建聚光灯 - 支持多选创建,优化版本 + - `createPointLight(self, pos=(0, 0, 0))`: 创建点光源 - 支持多选创建,优化版本 + - `_get_tree_widget(self)`: 安全获取树形控件 + - `_shouldConvertToGLB(self, filepath)`: 判断是否应该转换为GLB格式 + - `_convertToGLBWithProgress(self, filepath)`: 带进度显示的GLB转换 + - `_convertToGLB(self, filepath, progress=None)`: 将模型文件转换为GLB格式 + - `_convertWithBlender(self, input_path, output_path, progress=None)`: 使用 Blender 进行转换 + - `_convertWithFBX2glTF(self, input_path, output_path, progress=None)`: 使用 FBX2glTF 进行转换(仅支持FBX) + - `_convertWithAssimp(self, input_path, output_path, progress=None)`: 使用 PyAssimp 进行转换 + - `load_cesium_tileset(self, tileset_url, position=(0, 0, 0))`: 加载 Cesium 3D Tileset - 采用新的创建逻辑,支持多选和更完善的UI交互 + - `_load_tileset_async(self, tileset_url, tileset_info)`: 异步加载 tileset 数据 + - `_check_async_task(self, panda3d_task)`: 检查 asyncio 任务是否完成 + - `_parse_tileset(self, tileset_data, tileset_info)`: 解析 tileset 数据 + - `_parse_tile(self, tile_data, parent_node, tileset_info)`: 解析 tile 数据 + - `_create_tile_geometry(self, parent_node)`: 为 tile 创建占位几何体 + - `_create_placeholder_geometry(self, parent_node)`: 创建一个简单的占位符几何体,让用户能看到节点 + - `serializeNode(self, node)`: 序列化节点为字典数据 + - `deserializeNode(self, node_data, parent_node)`: 从字典数据反序列化节点 + - `serializeNodeForCopy(self, node)`: 序列化节点用于复制操作,完整保存视觉属性 + - `_serializeGUIData(self, node)`: 序列化GUI元素数据 + - `_serializeModelData(self, node)`: 序列化模型数据,包括材质信息 + - `recreateNodeFromData(self, node_data, parent_node)`: 根据数据重建节点,并确保在场景树中显示 + - `_findTreeItemForNode(self, node)`: 根据节点查找对应的场景树项 + - `_findTreeItemForNodeRecursive(self, item, target_node)`: 递归查找场景树项 + - `_recreateLightFromData(self, node_data, parent_node, name)`: 根据数据重建光源 + - `_recreateTilesetFromData(self, node_data, parent_node, name)`: 根据数据重建Tileset + - `_recreateGUIFromData(self, node_data, parent_node, name)`: 根据数据重建GUI元素 + - `_recreateModelFromData(self, node_data, parent_node, name)`: 根据数据重建模型,保持材质 + - `_restoreModelMaterial(self, model, model_data)`: 恢复模型材质 + - `_createBasicNodeFromData(self, node_data, parent_node, name)`: 创建基本节点,保持视觉属性 + - `_generateUniqueName(self, base_name, parent_node)`: 生成唯一节点名称 + +### 3. `scene/util.py` +- **功能**: 跨平台路径处理工具,提供标准化模型文件路径的功能 +- **类**: + - `CrossPlatformPathHandler`: 跨平台路径处理器 +- **方法**: + - `__init__(self)`: 初始化路径处理器 + - `normalize_model_path(self, filepath)`: 标准化模型文件路径 + - `_check_file_exists(self, filepath)`: 检查文件是否存在 + - `_panda3d_normalize(self, filepath)`: 使用Panda3D标准化路径 + - `_attempt_path_fixes(self, filepath)`: 尝试各种路径修复方法 + - `_fix_path_separators(self, filepath)`: 修复路径分隔符 + - `_convert_to_relative_path(self, filepath)`: 转换绝对路径为相对路径 + - `_clean_special_characters(self, filepath)`: 清理路径中的特殊字符 + - `_smart_file_search(self, filepath)`: 智能文件搜索 + - `_search_in_common_directories(self, filename)`: 在常见目录中搜索 + - `_recursive_search(self, filename, max_depth=3)`: 递归搜索文件 + - `_search_user_directories(self, filename)`: 搜索用户常用目录 + - `_handle_path_not_found(self, filepath)`: 处理路径未找到的情况 + - `suggest_file_placement(self, filename)`: 建议文件放置位置 +- **函数**: + - `normalize_model_path(filepath)`: 便捷函数:标准化模型路径 + - `suggest_file_placement(filename)`: 便捷函数:建议文件放置位置 + +## 2.6 scripts模块 + +### 1. `scripts/a.py` +- **功能**: 自定义脚本示例 +- **类**: + - `A`: 自定义脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化脚本 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新 + - `on_destroy(self)`: 脚本销毁时调用 + +### 2. `scripts/BouncerScript.py` +- **功能**: 跳跃脚本,让对象产生上下跳跃效果 +- **类**: + - `BouncerScript`: 跳跃脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化脚本参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现跳跃效果 + - `set_bounce_parameters(self, height=None, speed=None, bounce_type=None)`: 设置跳跃参数 + - `toggle_bouncing(self)`: 切换跳跃状态 + - `reverse_direction(self)`: 反转跳跃方向 + - `reset_position(self)`: 重置到原始高度 + - `jump_once(self)`: 执行一次跳跃 + - `on_destroy(self)`: 脚本销毁时调用 + +### 3. `scripts/ColorChangerScript.py` +- **功能**: 颜色变化脚本,让对象颜色产生循环变化 +- **类**: + - `ColorChangerScript`: 颜色变化脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化颜色参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现颜色变化效果 + - `_calculate_rainbow_color(self)`: 计算彩虹颜色 + - `_calculate_pulse_color(self)`: 计算脉冲颜色 + - `_calculate_fade_color(self)`: 计算淡入淡出颜色 + - `_calculate_strobe_color(self)`: 计算闪烁颜色 + - `set_color_parameters(self, speed=None, mode=None, base_color=None, intensity=None)`: 设置颜色参数 + - `toggle_color_change(self)`: 切换颜色变化状态 + - `reset_color(self)`: 重置到原始颜色 + - `set_solid_color(self, r=1.0, g=1.0, b=1.0, a=1.0)`: 设置固定颜色 + - `on_destroy(self)`: 脚本销毁时调用 + +### 4. `scripts/ComboAnimatorScript.py` +- **功能**: 复合动画脚本,结合旋转和跳跃效果 +- **类**: + - `ComboAnimatorScript`: 复合动画脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化脚本 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现旋转和跳跃效果 + - `on_destroy(self)`: 脚本销毁时调用 + +### 5. `scripts/example_script.py` +- **功能**: 示例脚本,演示如何编写脚本 +- **类**: + - `ExampleScript`: 示例脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化脚本 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新 + - `on_destroy(self)`: 脚本销毁时调用 + - `on_enable(self)`: 脚本启用时调用 + - `on_disable(self)`: 脚本禁用时调用 + +### 6. `scripts/FollowerScript.py` +- **功能**: 跟随脚本,让对象跟随指定的目标对象 +- **类**: + - `FollowerScript`: 跟随脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化跟随参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现跟随效果 + - `set_target(self, target)`: 设置跟随目标 + - `on_destroy(self)`: 脚本销毁时调用 + +### 7. `scripts/MoverScript.py` +- **功能**: 移动脚本,让对象在指定方向上来回移动 +- **类**: + - `MoverScript`: 移动脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化移动参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现移动效果 + - `set_move_parameters(self, distance=None, speed=None, axis=None)`: 设置移动参数 + - `toggle_movement(self)`: 切换移动状态 + - `reset_position(self)`: 重置到起始位置 + - `on_destroy(self)`: 脚本销毁时调用 + +### 8. `scripts/R_P.py` +- **功能**: 旋转脚本,让对象持续旋转(围绕P轴) +- **类**: + - `RotatorScript`: 旋转脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化旋转参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现旋转效果 + - `set_max_angle(self, new_max_angle)`: 设置新的最大旋转角度 + - `set_rotation_speed(self, new_speed)`: 设置新的旋转速度 + - `pause_rotation(self)`: 暂停旋转 + - `resume_rotation(self)`: 恢复旋转 + - `reset_to_initial_angle(self)`: 重置到初始角度 + - `get_current_info(self)`: 获取当前旋转信息 + - `on_destroy(self)`: 脚本销毁时调用 + +### 9. `scripts/R_R.py` +- **功能**: 旋转脚本,让对象持续旋转(围绕R轴) +- **类**: + - `RotatorScript`: 旋转脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化旋转参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现旋转效果 + - `set_max_angle(self, new_max_angle)`: 设置新的最大旋转角度 + - `set_rotation_speed(self, new_speed)`: 设置新的旋转速度 + - `pause_rotation(self)`: 暂停旋转 + - `resume_rotation(self)`: 恢复旋转 + - `reset_to_initial_angle(self)`: 重置到初始角度 + - `get_current_info(self)`: 获取当前旋转信息 + - `on_destroy(self)`: 脚本销毁时调用 + +### 10. `scripts/Rotate_H_Script.py` +- **功能**: 机器人式旋转脚本,让对象围绕H轴旋转并带有停顿效果 +- **类**: + - `RotatorScript`: 旋转脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化旋转参数和机器人模式参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现机器人式旋转效果 + - `set_robot_mode(self, enabled=True)`: 启用或禁用机器人模式 + - `set_pause_duration(self, duration)`: 设置停顿时间 + - `set_max_angle(self, new_max_angle)`: 设置新的最大旋转角度 + - `set_rotation_speed(self, new_speed)`: 设置新的旋转速度 + - `pause_rotation(self)`: 暂停旋转 + - `resume_rotation(self)`: 恢复旋转 + - `reset_to_initial_angle(self)`: 重置到初始角度 + - `get_current_info(self)`: 获取当前旋转信息 + - `set_slow_robot_mode(self)`: 预设:慢速机器人模式 + - `set_fast_robot_mode(self)`: 预设:快速机器人模式 + - `set_smooth_mode(self)`: 预设:平滑模式(非机器人) + - `on_destroy(self)`: 脚本销毁时调用 + +### 11. `scripts/Rotate_P_Script.py` +- **功能**: 机器人式旋转脚本,让对象围绕P轴旋转并带有停顿效果 +- **类**: + - `RotatorScript`: 旋转脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化旋转参数和机器人模式参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现机器人式旋转效果 + - `set_robot_mode(self, enabled=True)`: 启用或禁用机器人模式 + - `set_pause_duration(self, duration)`: 设置停顿时间 + - `set_max_angle(self, new_max_angle)`: 设置新的最大旋转角度 + - `set_rotation_speed(self, new_speed)`: 设置新的旋转速度 + - `pause_rotation(self)`: 暂停旋转 + - `resume_rotation(self)`: 恢复旋转 + - `reset_to_initial_angle(self)`: 重置到初始角度 + - `get_current_info(self)`: 获取当前旋转信息 + - `set_slow_robot_mode(self)`: 预设:慢速机器人模式 + - `set_fast_robot_mode(self)`: 预设:快速机器人模式 + - `set_smooth_mode(self)`: 预设:平滑模式(非机器人) + - `on_destroy(self)`: 脚本销毁时调用 + +### 12. `scripts/Rotate_R_Script.py` +- **功能**: 旋转脚本,让对象围绕R轴旋转 +- **类**: + - `RotatorScript`: 旋转脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化旋转参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现旋转效果 + - `on_destroy(self)`: 脚本销毁时调用 + +### 13. `scripts/RotatorScript.py` +- **功能**: 旋转脚本,让对象持续旋转 +- **类**: + - `RotatorScript`: 旋转脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化旋转参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现旋转效果 + - `on_destroy(self)`: 脚本销毁时调用 + +### 14. `scripts/ScalerScript.py` +- **功能**: 缩放脚本,让对象产生呼吸般的缩放效果 +- **类**: + - `ScalerScript`: 缩放脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化缩放参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现缩放效果 + - `set_scale_parameters(self, base=None, amplitude=None, speed=None, uniform=None)`: 设置缩放参数 + - `toggle_scaling(self)`: 切换缩放状态 + - `reset_scale(self)`: 重置到原始缩放 + - `pulse_once(self)`: 执行一次脉冲缩放 + - `on_destroy(self)`: 脚本销毁时调用 + +### 15. `scripts/test_quick_script.py` +- **功能**: 测试快速脚本示例 +- **类**: + - `TestQuickScript`: 测试快速脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化脚本 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新 + - `on_destroy(self)`: 脚本销毁时调用 + +### 16. `scripts/TestMover.py` +- **功能**: 测试移动脚本 +- **类**: + - `Testmover`: 测试移动脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化移动参数 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新,实现移动效果 + - `on_destroy(self)`: 脚本销毁时调用 + +### 17. `scripts/TestRotator.py` +- **功能**: 测试旋转脚本 +- **类**: + - `Testrotator`: 测试旋转脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化脚本 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新 + - `on_destroy(self)`: 脚本销毁时调用 + +### 18. `scripts/TestScaler.py` +- **功能**: 测试缩放脚本 +- **类**: + - `Testscaler`: 测试缩放脚本类,继承自ScriptBase +- **方法**: + - `__init__(self)`: 初始化脚本 + - `start(self)`: 脚本开始时调用 + - `update(self, dt)`: 每帧更新 + - `on_destroy(self)`: 脚本销毁时调用 + +## 2.8 ui模块 + +### 1. `ui/__init__.py` +- **功能**: ui模块初始化文件,导出UI组件类 +- **类**: + - 无 +- **方法**: + - 无 +- **导出项**: + - `CustomPanda3DWidget`: 自定义Panda3D部件类 + - `CustomFileView`: 自定义文件视图类 + - `CustomTreeWidget`: 自定义树形控件类 + - `MainWindow`: 主窗口类 + - `setup_main_window`: 设置主窗口函数 + +### 2. `ui/assembly_disassembly_config_simple.py` +- **功能**: 拆装交互配置界面 - 简化版本,实现模型的分步拆装交互功能配置 +- **类**: + - `AssemblyDisassemblyConfigDialog`: 拆装配置主对话框 - 简化版本 +- **方法**: + - `__init__(self, parent=None, world=None)`: 初始化拆装配置对话框 + - `setupUI(self)`: 设置界面 + - `createModelsTab(self)`: 创建模型选择标签页 + - `createStepsTab(self)`: 创建步骤配置标签页 + - `createToolsTab(self)`: 创建工具配置标签页 + - `createSettingsTab(self)`: 创建全局设置标签页 + - `connectSignals(self)`: 连接信号槽 + - `loadSceneModels(self)`: 加载场景中的模型 + - `_addNodeToTree(self, node, parent_item)`: 递归添加节点到树形控件 + - `filterSceneModels(self, search_text)`: 根据搜索文本过滤场景模型 + - `addModelsToConfig(self)`: 添加选中的模型到配置 + - `removeModelsFromConfig(self)`: 从配置中移除选中的模型 + - `addStep(self)`: 添加步骤 + - `removeStep(self)`: 删除步骤 + - `moveStepUp(self)`: 上移步骤 + - `moveStepDown(self)`: 下移步骤 + - `renumberSteps(self)`: 重新编号步骤 + - `onStepSelectionChanged(self)`: 步骤选择改变 + - `_clearStepConfigurationUI(self)`: 清空步骤配置界面 + - `loadStepConfiguration(self, step_data)`: 加载步骤配置到界面 + - `disconnectStepConfigSignals(self)`: 断开步骤配置的信号连接 + - `connectStepConfigSignals(self)`: 连接步骤配置的信号 + - `saveCurrentStepConfig(self)`: 保存当前步骤的配置到list_item的UserRole数据中 + - `addTool(self)`: 添加工具 + - `editTool(self)`: 编辑工具 + - `deleteTool(self)`: 删除工具 + - `browseAudioFile(self)`: 浏览音频文件 + - `saveConfiguration(self)`: 保存配置 + - `loadConfiguration(self)`: 加载配置 + - `loadConfigurationData(self, data)`: 加载配置数据到界面 + - `_loadModelConfiguration(self, saved_models)`: 加载模型配置,通过路径精确匹配场景中的模型节点 + - `_buildSceneModelMap(self, node, model_map)`: 递归构建场景模型名称到节点的映射 + - `_getNodePath(self, node)`: 获取节点的完整路径,用于精确定位 + - `_findNodeByPath(self, root_node, node_path)`: 根据路径在场景中查找节点 + - `_findNodeByNameAndParent(self, root_node, node_name, parent_name)`: 根据节点名称和父节点名称查找节点 + - `previewConfiguration(self)`: 预览配置效果 + - `applyConfiguration(self)`: 应用配置 + +### 3. `ui/assembly_disassembly_config.py` +- **功能**: 拆装交互配置界面,实现模型的分步拆装交互功能配置 +- **类**: + - `AssemblyDisassemblyConfigDialog`: 拆装配置主对话框 +- **方法**: + - `__init__(self, parent=None, world=None)`: 初始化拆装配置对话框 + - `setupUI(self)`: 设置界面 + - `createLeftPanel(self)`: 创建左侧面板 + - `createRightPanel(self)`: 创建右侧面板 + - `createStepsTab(self)`: 创建步骤配置标签页 + - `createStepConfigWidget(self)`: 创建步骤详细配置部件 + - `createSettingsTab(self)`: 创建全局设置标签页 + - `connectSignals(self)`: 连接信号槽 + - `loadSceneModels(self)`: 加载场景中的模型 + - `_addNodeToTree(self, node, parent_item)`: 递归添加节点到树形控件 + - `filterSceneModels(self, text)`: 过滤场景模型列表 + - `addModelsToConfig(self)`: 添加选中的模型到配置 + - `removeModelsFromConfig(self)`: 从配置中移除选中的模型 + - `addTool(self)`: 添加工具 + - `editTool(self)`: 编辑工具 + - `removeTool(self)`: 删除工具 + - `addStep(self)`: 添加步骤 + - `removeStep(self)`: 删除步骤 + - `moveStepUp(self)`: 上移步骤 + - `moveStepDown(self)`: 下移步骤 + - `renumberSteps(self)`: 重新编号步骤 + - `onStepSelectionChanged(self)`: 步骤选择改变 + - `loadStepConfiguration(self, step_data)`: 加载步骤配置到界面 + - `onInteractionTypeChanged(self, interaction_type)`: 交互方式改变 + - `updateCurrentStep(self)`: 更新当前步骤数据 + - `browseAudioFile(self)`: 浏览音频文件 + - `saveConfiguration(self)`: 保存配置 + - `loadConfiguration(self)`: 加载配置 + - `loadConfigurationData(self, data)`: 加载配置数据到界面 + - `previewConfiguration(self)`: 预览配置效果 + - `applyConfiguration(self)`: 应用配置 + +### 4. `ui/icon_manager_gui.py` +- **功能**: 图标管理器GUI工具,提供图形界面来管理和查看图标 +- **类**: + - `IconPreviewWidget`: 图标预览控件 + - `IconManagerDialog`: 图标管理器对话框 +- **方法**: + - `IconPreviewWidget.__init__(self)`: 初始化图标预览控件 + - `IconPreviewWidget.setupUI(self)`: 设置UI + - `IconPreviewWidget.showIcon(self, icon_name: str, icon: QIcon)`: 显示图标 + - `IconManagerDialog.__init__(self, parent=None)`: 初始化图标管理器对话框 + - `IconManagerDialog.setupUI(self)`: 设置UI + - `IconManagerDialog.loadIcons(self)`: 加载图标列表 + - `IconManagerDialog.onIconSelected(self)`: 当选择图标时 + - `IconManagerDialog.refreshIcons(self)`: 刷新图标 + - `IconManagerDialog.addIcon(self)`: 添加新图标 + - `IconManagerDialog.showDebugInfo(self)`: 显示调试信息 + - `show_icon_manager(parent=None)`: 显示图标管理器对话框 + +### 5. `ui/icon_manager.py` +- **功能**: 图标管理工具,负责统一管理应用程序中的所有图标 +- **类**: + - `IconManager`: 图标管理器类 +- **方法**: + - `__init__(self)`: 初始化图标管理器 + - `_get_icon_directory(self)`: 获取图标目录的绝对路径 + - `_create_default_icon(self)`: 创建默认图标 + - `_preload_icons(self)`: 预加载常用图标 + - `get_icon(self, icon_name: str, size: Optional[QSize] = None)`: 获取图标 + - `get_icon_path(self, icon_name: str)`: 获取图标文件的完整路径 + - `has_icon(self, icon_name: str)`: 检查图标是否存在 + - `add_icon(self, icon_name: str, icon_path: str)`: 添加新图标到缓存 + - `refresh_cache(self)`: 刷新图标缓存 + - `get_available_icons(self)`: 获取所有可用的图标列表 + - `get_cache_info(self)`: 获取缓存信息 + - `debug_info(self)`: 打印调试信息 + - `get_icon_manager()`: 获取全局图标管理器实例 + - `get_icon(icon_name: str, size: Optional[QSize] = None)`: 便捷函数:获取图标 + - `get_icon_path(icon_name: str)`: 便捷函数:获取图标路径 + - `has_icon(icon_name: str)`: 便捷函数:检查图标是否存在 + +### 6. `ui/interface_manager.py` +- **功能**: 界面管理器,处理树形控件和UI交互 +- **类**: + - `InterfaceManager`: 界面管理器类 +- **方法**: + - `__init__(self, world)`: 初始化界面管理器 + - `setTreeWidget(self, treeWidget)`: 设置树形控件引用并更新场景树 + - `onTreeWidgetClicked(self, index)`: 处理树形控件点击事件(包括空白区域) + - `onTreeCurrentItemChanged(self, current, previous)`: 处理树形控件当前选中项改变事件 + - `onTreeItemClicked(self, item, column)`: 处理树形控件项目点击事件 + - `isModelOrChild(self, item)`: 检查是否是模型节点或其子节点 + - `deleteNode(self, nodePath, item)`: 删除节点 + - `_cleanupAllLightsInSubtree(self, parentNode)`: 清理节点树中的灯光 + - `updateSceneTree(self)`: 更新场景树显示 - 实际实现 + - `findTreeItem(self, node, parentItem)`: 在树形控件中查找指定的节点项 + - `_collect_expanded(self, item=None, prefix="")`: 收集展开的节点路径 + - `_restore_expanded(self, item=None, prefix="")`: 恢复展开的节点状态 + - `syncVisibilityDownward(self)`: 向下同步可见性 + +### 7. `ui/main_window.py` + +#### 类: StyledTerrainDialog +- **功能**: 与新建项目对话框风格一致的参数输入对话框 +- **方法**: + - `__init__(self, parent, title, fields, primary_text="确认", secondary_text="取消")`: 初始化对话框 + - `createTitleBar(self)`: 创建标题栏 + - `_applyTitleBarIcons(self)`: 应用标题栏图标 + - `setWindowTitle(self, title)`: 设置窗口标题 + - `mousePressEvent(self, event)`: 鼠标按下事件 + - `mouseMoveEvent(self, event)`: 鼠标移动事件 + - `mouseReleaseEvent(self, event)`: 鼠标释放事件 + - `get_value(self, name)`: 获取字段值 + +#### 类: MainWindow +- **功能**: 主窗口类,负责创建和管理应用程序的主界面 +- **方法**: + - `__init__(self, world)`: 初始化主窗口 + - `setupMessageBoxStyles(self)`: 设置消息框样式 + - `createStyledInputDialog(self, parent, title, label, mode=QLineEdit.Normal, text="")`: 创建带样式的输入对话框 + - `createStyledFileDialog(self, parent, caption, directory="", filter="")`: 创建带样式的文件对话框 + - `setupCenterWidget(self)`: 设置窗口中央部件 + - `move_center(self)`: 将窗口移动到屏幕中央 + - `get_icon_path(self, icon_name)`: 获取图标文件路径 + - `setupEmbeddedToolbar(self)`: 创建内嵌工具栏 + - `toolbarMousePressEvent(self, event)`: 工具栏鼠标按下事件 + - `toolbarMouseMoveEvent(self, event)`: 工具栏鼠标移动事件 + - `toolbarMouseReleaseEvent(self, event)`: 工具栏鼠标释放事件 + - `snapToNearestPosition(self)`: 自动吸附到最近的预设位置 + - `setupMenus(self)`: 创建菜单栏 + - `refreshAssetsView(self)`: 刷新资源视图 + - `setupCreateMenuActions(self)`: 设置创建菜单动作 + - `setupViewMenuActions(self)`: 设置视图菜单动作 + - `onViewPerspective(self)`: 切换到透视视图 + - `onViewOrthographic(self)`: 切换到正交视图 + - `onViewTop(self)`: 切换到俯视图 + - `onViewFront(self)`: 切换到前视图 + - `onViewGrid(self)`: 切换网格显示 + - `_createGridView(self)`: 创建网格视图 + - `_saveCurrentCameraSettings(self)`: 保存当前相机设置 + - `_setupOrthographicLens(self)`: 设置正交镜头 + - `_updateViewMenuText(self)`: 更新视图菜单文本 + - `_onWindowResized(self)`: 窗口大小改变时的处理 + - `connectCreateMenuActions(self)`: 连接创建菜单动作 + - `getCreateMenuActions(self)`: 获取所有创建菜单动作 + - `setupDockWindows(self)`: 创建停靠窗口 + - `setupToolbar(self)`: 创建工具栏 + - `setupScriptPanel(self, layout)`: 创建脚本管理面板 + - `connectEvents(self)`: 连接事件信号 + - `onCopy(self)`: 复制操作 + - `onCut(self)`: 剪切操作 + - `onPaste(self)`: 粘贴操作 + - `_serializeNode(self, node)`: 序列化节点 + - `_deserializeNode(self, node_data, parent_node)`: 反序列化节点 + - `_deleteNode(self, node, tree_item)`: 删除节点 + - `onUndo(self)`: 撤销操作 + - `onRedo(self)`: 重做操作 + - `onCreateCesiumView(self)`: 创建 Cesium 视图 + - `onToggleCesiumView(self)`: 切换 Cesium 视图 + - `onRefreshCesiumView(self)`: 刷新 Cesium 视图 + - `onUpdateCesiumURL(self)`: 更新 Cesium URL + - `onAddModelClicked(self)`: 处理添加模型按钮点击 + - `showAddModelDialog(self)`: 显示添加模型对话框 + - `getModelCoordinates(self)`: 获取模型坐标信息 + - `onLoadCesiumTileset(self)`: 加载 Cesium 3D Tiles + - `onToolChanged(self, button)`: 工具切换事件处理 + - `openWebBrowser(self)`: 打开网页浏览器 + - `getSampleWeatherData(self)`: 获取示例天气数据 + - `onCreate3DSampleInfoPanel(self)`: 创建3D示例信息面板 + - `addInfoPanelToTree(self, panel, panel_name)`: 将信息面板添加到场景树 + - `onCreateSystemStatusPanel(self)`: 创建系统状态信息面板 + - `getSystemStatusData(self)`: 获取系统状态数据 + - `onCreateSensorDataPanel(self)`: 创建传感器数据信息面板 + - `getSensorData(self)`: 获取传感器数据 + - `onCreateSceneInfoPanel(self)`: 创建场景信息面板 + - `getSceneInfoData(self)`: 获取场景信息数据 + - `refreshScriptsList(self)`: 刷新脚本列表 + - `updateScriptPanel(self)`: 更新脚本面板状态 + - `updateMountedScriptsList(self, game_object)`: 更新已挂载脚本列表 + - `onCreateScript(self)`: 创建脚本按钮事件 + - `onCreateScriptDialog(self)`: 菜单创建脚本事件 + - `onLoadScript(self)`: 加载脚本按钮事件 + - `onLoadScriptFile(self)`: 加载脚本文件菜单事件 + - `onReloadAllScripts(self)`: 重新加载所有脚本事件 + - `onToggleHotReload(self)`: 切换热更新状态 + - `onOpenScriptsManager(self)`: 打开脚本管理器 + - `onScriptDoubleClick(self, item)`: 脚本列表双击事件 + - `onMountScript(self)`: 挂载脚本事件 + - `onUnmountScript(self)`: 卸载脚本事件 + - `onOpenIconManager(self)`: 打开图标管理器 + - `closeEvent(self, event)`: 处理窗口关闭事件 + - `onCreateFlatTerrain(self)`: 创建平面地形 + - `onCreateHeightmapTerrain(self)`: 从高度图创建地形 + - `onOpenAssemblyDisassemblyConfig(self)`: 打开拆装配置界面 + - `onStartAssemblyInteraction(self)`: 开始拆装交互 + - `onOpenMaintenanceSystem(self)`: 打开维修系统 + - `onEnterVR(self)`: 进入VR模式 + - `onExitVR(self)`: 退出VR模式 + - `onShowVRStatus(self)`: 显示VR状态 + - `onShowVRSettings(self)`: 显示VR设置对话框 + - `createVRSettingsDialog(self)`: 创建VR设置对话框 + - `onVRSettingsOK(self, dialog)`: 确定VR设置 + - `applyVRSettings(self, dialog)`: 应用VR设置 + - `onToggleVRDebug(self)`: 切换VR调试输出 + - `onShowVRPerformance(self)`: 显示VR性能报告 + - `onSetVRDebugMode(self, mode)`: 设置VR调试模式 + - `onToggleVRPerformanceMonitor(self)`: 切换VR性能监控 + - `onToggleVRGpuTiming(self)`: 切换VR GPU时间监控 + - `onToggleVRPipelineMonitor(self)`: 切换VR管线监控 + - `onSetVRPoseStrategy(self, strategy)`: 设置VR姿态策略 + - `onTestVRPipeline(self)`: 测试VR管线监控功能 + - `onShowVRDebugSettings(self)`: 显示VR调试设置对话框 + - `createVRDebugSettingsDialog(self)`: 创建VR调试设置对话框 + - `onToggleVRTestMode(self)`: 切换VR测试模式 + - `onToggleVRTestSubmitTexture(self)`: 切换VR测试模式纹理提交功能 + - `onToggleVRTestWaitPoses(self)`: 切换VR测试模式姿态等待功能 + - `onSetVRTestStep(self, step)`: 设置VR测试步骤 + +#### 函数: setup_main_window +- **功能**: 设置主窗口的便利函数 +- **方法**: + - `setup_main_window(world, path=None)`: 设置主窗口 + +#### 类: AssemblyModeSelectionDialog +- **功能**: 拆装模式选择对话框 +- **方法**: + - `__init__(self, parent=None)`: 初始化对话框 + - `setupUI(self)`: 设置界面 + - `on_mode_changed(self)`: 模式改变时的处理 + - `get_selected_mode(self)`: 获取选中的模式 + +### 8. `ui/maintenance_system.py` + +#### 类: MaintenanceLoginDialog +- **功能**: 维修系统登录对话框 +- **信号**: + - `login_success`: 登录成功信号 +- **方法**: + - `__init__(self, parent=None)`: 初始化登录对话框 + - `setupUI(self)`: 设置用户界面,包括标题、登录表单、提示信息和按钮,应用样式和布局 + - `on_login(self)`: 处理登录,验证账号密码,成功时发射login_success信号 + +#### 类: MaintenanceSubjectDialog +- **功能**: 维修系统科目选择对话框 +- **信号**: + - `subject_selected`: 科目选择信号,传递科目路径和模式参数 +- **方法**: + - `__init__(self, project_path, parent=None)`: 初始化科目选择对话框,设置项目路径和科目路径 + - `setupUI(self)`: 设置用户界面,包括标题、科目列表、科目详情、模式选择和底部按钮,应用样式和布局 + - `load_subjects(self)`: 加载科目列表,扫描Subjects目录中的JSON文件并显示在列表中 + - `on_subject_selected(self, item)`: 处理科目选择,更新科目详情显示和开始按钮状态 + - `format_subject_description(self, subject_data, filename)`: 格式化科目描述,显示科目基本信息、描述、步骤数量、总分和工具列表 + - `on_start(self)`: 开始科目,获取选择的模式并发射subject_selected信号 + +#### 类: MaintenanceSystemManager +- **功能**: 维修系统管理器 +- **方法**: + - `__init__(self, world)`: 初始化维修系统管理器,保存world引用 + - `show_maintenance_system(self, parent_window)`: 显示维修系统,创建登录对话框并连接登录成功信号 + - `show_subject_selection(self, parent_window)`: 显示科目选择界面,获取当前项目路径并创建科目选择对话框 + - `start_maintenance_subject(self, subject_path, mode)`: 开始维修科目,加载科目配置并启动拆装交互系统 + +### 9. `ui/property_panel.py` + +#### 类: PropertyPanelManager +- **功能**: 属性面板管理器,负责显示和编辑场景中各种对象的属性 +- **方法**: + - `__init__(self, world)`: 初始化属性面板管理器 + - `createStatusBadge(self, text, badge_type="green")`: 创建现代化状态徽章 + - `createFixedStatusBadge(self, text, badge_type="green")`: 创建固定宽度的状态徽章 + - `createModernButton(self, text, button_type="default")`: 创建现代化按钮 + - `_collision_button_style(self)`: 返回碰撞检测面板按钮统一样式 + - `createModernGroupBox(self, title, parent_layout)`: 创建现代化的分组框 + - `_getFigmaSpinBoxStyle(self)`: 获取符合Figma设计的SpinBox样式 + - `createPropertyRow(self, label_text, widget, layout, tooltip=None)`: 创建属性行 + - `setPropertyLayout(self, layout)`: 设置属性面板布局引用 + - `clearPropertyPanel(self)`: 清空属性面板 + - `updateNodeVisibilityAfterDrag(self, item)`: 拖拽结束后更新节点的可见性状态 + - `_syncSceneVisibility(self)`: 同步场景可见性 + - `updatePropertyPanel(self, item)`: 更新属性面板显示 + - `_isTerrainNode(self, node, item)`: 检查是否是地形节点 + - `_showTerrainProperties(self, terrain_node, item)`: 显示地形属性面板 + - `_updateTerrainTransformPanel(self, terrain_node)`: 更新地形变化属性面板 + - `_createTerrainEditPanel(self, terrain_info)`: 创建地形编辑控制面板 + - `_onTerrainRadiusChanged(self, value)`: 地形编辑半径改变 + - `_onTerrainStrengthChanged(self, value)`: 地形编辑强度改变 + - `_onTerrainOperationChanged(self, text)`: 地形编辑操作类型改变 + - `_updateTerrainMaterialPanel(self, terrain_node, terrain_info)`: 更新地形材质属性面板 + - `_selectTerrainColor(self, terrain_info)`: 选择地形颜色 + - `_selectTerrainTexture(self, terrain_info)`: 选择地形纹理 + - `_deleteTerrain(self, terrain_info, item)`: 删除地形 + - `_cleanupAllReferences(self)`: 清理所有控件引用 + - `_setUserVisible(self, node, visible)`: 设置用户可见性 + - `_syncEffectiveVisibility(self, start_node)`: 同步有效可见性 + - `_toggleModelVisibility(self, model, state)`: 切换模型可见性状态 + - `refreshModelValues(self, nodePath)`: 刷新模型值显示 + - `_refreshGUIElementValues(self, gui_element)`: 刷新GUI元素值显示 + - `_refreshModelValues(self, nodePath)`: 刷新普通模型值显示 + - `_isPropertyPanelValid(self)`: 检查属性面板是否仍然有效 + - `_safeUpdateSpinBox(self, attr_name, value)`: 安全地更新数值框 + - `_createTransformControls(self, nodePath)`: 创建变换控制控件 + - `_onPositionEditFinished(self, nodePath, axis)`: 位置编辑完成时的处理 + - `_createSafeSpinBox(self, min_val, max_val, read_only=False)`: 创建安全的数值框 + - `_cleanupTransformControls(self)`: 清理变换控件引用 + - `_refreshWorldPos(self, model)`: 刷新世界位置 + - `_showCesiumTilesetProperties(self, nodePath, item)`: 显示 Cesium tileset 属性 + - `_createPositionControl(self, label, nodePath, axis)`: 创建位置控制控件 + - `_createScaleControl(self, nodePath)`: 创建缩放控制控件 + - `_updateTilesetPosition(self, nodePath, axis, value)`: 更新 tileset 位置 + - `_updateTilesetScale(self, nodePath, value)`: 更新 tileset 缩放 + - `_deleteCesiumTileset(self, nodePath, item)`: 删除 Cesium tileset + - `_updateModelPropertyPanel(self, model)`: 更新模型属性面板 + - `_onScaleValueChanged(self, scale_widget, value)`: 缩放值改变 + - `_updateXScale(self, model, value)`: 更新X轴缩放值 + - `_updateYScale(self, model, value)`: 更新Y轴缩放值 + - `_updateZScale(self, model, value)`: 更新Z轴缩放值 + - `updateGUIPropertyPanel(self, gui_element, item)`: 更新GUI元素属性面板 + - `_addInfoPanelProperties(self, info_panel)`: 为信息面板添加属性控制面板 + - `_applyInfoPanel3DTitleProperties(self, info_panel, r, g, b, a, size)`: 应用3D信息面板标题属性 + - `_applyInfoPanel3DContentProperties(self, info_panel, r, g, b, a, size)`: 应用3D信息面板内容属性 + - `_adjustContentWordwrap(self, panel_id, panel_width, font_size)`: 调整信息面板内容的换行设置 + - `_startInfoPanelMonitoring(self, info_panel, panel_id)`: 启动信息面板内容监控 + - `_checkInfoPanelUpdates(self, panel_id)`: 检查信息面板内容更新 + - `_selectInfoPanelBorderColor(self, info_panel, r_spin, g_spin, b_spin, a_spin)`: 选择信息面板边框颜色 + - `updateInfoPanelBackgroundImage(self, info_panel, image_path)`: 更新信息面板背景图片 + - `_applyInfoPanelBackgroundImage(self, panel_node, image_path, panel_data)`: 应用信息面板背景图片 + - `_update3DInfoPanelBackgroundImage(self, panel_id, info_panel, image_path)`: 更新3D信息面板背景图片 + - `_selectInfoPanelBackgroundColor(self, info_panel, r_spin, g_spin, b_spin, a_spin)`: 选择信息面板背景颜色 + - `_applyInfoPanelBackgroundColor(self, info_panel, r, g, b, a)`: 应用信息面板背景颜色 + - `_selectInfoPanelTitleColor(self, info_panel, r_spin, g_spin, b_spin, a_spin)`: 选择信息面板标题颜色 + - `_selectInfoPanelContentColor(self, info_panel, r_spin, g_spin, b_spin, a_spin)`: 选择信息面板内容颜色 + - `_applyInfoPanelTitleProperties(self, info_panel, r, g, b, a, size)`: 应用信息面板标题属性 + - `_applyInfoPanelContentProperties(self, info_panel, r, g, b, a, size)`: 应用信息面板内容属性 + - `_addSphericalVideoProperties(self, spherical_video)`: 为球形视频添加属性控制面板 + - `_toggleSphericalVideoPlayback(self, spherical_video)`: 切换球形视频播放状态 + - `_stopSphericalVideo(self, spherical_video)`: 停止球形视频 + - `_seekSphericalVideo(self, spherical_video, slider_value)`: 跳转到指定时间位置 + - `_updateSphericalVideoRadius(self, spherical_video, new_radius)`: 更新球形视频半径 + - `loadSphericalVideoFile(self, spherical_video, video_path)`: 为球形视频加载新的视频文件 + - `_selectSphericalVideoFile(self, spherical_video)`: 选择球形视频文件 + - `_addVideoScreenProperties(self, video_screen, item)`: 添加视频屏幕属性面板 + - `_add2DVideoScreenProperties(self, video_screen, item)`: 为2D视频屏幕添加属性控制面板 + - `_loadVideoFromURLWithOpenCV(self, video_screen, url)`: 使用OpenCV从URL加载视频流并在2D视频屏幕上显示 + - `play2DVideo(self, video_screen)`: 播放2D视频 + - `pause2DVideo(self, video_screen)`: 暂停2D视频 + - `_stop2DVideo(self, video_screen)`: 停止2D视频 + - `_loadNew2DVideo(self, video_screen, item)`: 为2D视频屏幕加载新视频文件 + - `_loadVideoFromURLWithOpenCV_3D(self, video_screen, url)`: 使用OpenCV从URL加载视频流并在3D视频屏幕上显示 + - `_verifyVideoDisplay(self, video_screen, texture)`: 验证视频显示 + - `_retryLoadVideoFromURLWithOpenCV_3D(self, video_screen, url)`: 重新加载3D视频流 + - `_stop3DVideo(self, video_screen)`: 停止3D视频 + - `_loadNewVideo(self, video_screen, item)`: 加载新视频 + - `editGUI2DPosition(self, gui_element, axis, value)`: 编辑2D GUI元素位置 + - `editGUIScale(self, gui_element, axis, value)`: 编辑GUI元素缩放 + - `_update2DImageWidth(self, gui_element, width)`: 更新2D图片宽度 + - `_update2DImageHeight(self, gui_element, height)`: 更新2D图片高度 + - `_update2DImageScale(self, gui_element, scale)`: 更新2D图片缩放 + - `_update3DImageScale(self, gui_element, axis, scale)`: 更新3D元素缩放 + - `_selectGUIColor(self, gui_element)`: 选择GUI元素的字体颜色 + - `_updateGUITextColor(self, gui_element, color)`: 更新GUI元素的字体颜色 + - `_updateGUIScaleY(self, gui_element, scale_y)`: 更新GUI元素Y轴缩放 + - `_updateGUIScaleZ(self, gui_element, scale_z)`: 更新GUI元素Z轴缩放 + - `update2DImageTexture(self, image_element, texture_path)`: 更新2D图片纹理 + - `_updateScriptPropertyPanel(self, game_object)`: 更新脚本属性面板 + - `_toggleScriptEnabled(self, script_component)`: 切换脚本启用状态 + - `updateLightPropertyPanel(self, model)`: 更新光源属性面板 + - `_updateLightPosition(self, light_object, node_path, axis, value)`: 更新光源位置 + - `_updateLightRotation(self, light_object, node_path, axis, value)`: 更新光源旋转 + - `_updateLightEnergy(self, light_object, value)`: 更新光源强度 + - `_updateLightRadius(self, light_object, value)`: 更新光源半径 + - `_updateLightFOV(self, light_Object, value)`: 更新聚光灯视野角度 + - `_updateLightTemperature(self, light_object, value)`: 更新光源色温 + - `_updateLightInnerRadius(self, light_object, value)`: 更新点光源内半径 + - `_updateLightShaowResolution(self, light_object, value)`: 更新阴影分辨率 + - `_updateLightNearPlane(self, light_object, value)`: 更新近平面距离 + - `_updateLightCastsShadows(self, light_object, casts_shadows)`: 更新光源是否投射阴影 + - `_updateLightScale(self, node_path, axis, value)`: 更新光源节点缩放 + - `_generateUniqueMaterialNames(self, materials, model_name)`: 生成唯一的材质名称 + - `_updateModelMaterialPanel(self, model)`: 模型材质属性 + - `_updateMaterialBaseColor(self, material, component, value)`: 更新材质基础颜色 + - `_updateMaterialTransparency(self, material, alpha_value)`: 更新材质透明度 + - `_updateMaterialRoughness(self, material, value)`: 更新材质粗糙度 + - `_updateMaterialMetallic(self, material, value)`: 更新材质金属性 + - `_updateMaterialIOR(self, material, value)`: 更新材质折射率 + - `_getMaterialStatus(self, material)`: 获取材质状态描述 + - `_getTextureModeString(self, mode)`: 获取纹理模式的字符串表示 + - `_checkAndAdjustMaterialProperty(self, material, property_name, current_value, texture_type)`: 检查并智能调整材质属性值 + - `_getOrCreateMaterialBaseColor(self, material)`: 智能获取或创建材质的基础颜色 + - `_selectDiffuseTexture(self, material_title)`: 漫反射贴图 + - `_selectNormalTexture(self, material)`: 选择法线贴图 + - `_selectRoughnessTexture(self, material)`: 选择粗糙度贴图 + - `_selectMetallicTexture(self, material)`: 选择金属性贴图 + - `_selectIORTexture(self, material)`: 选择IOR贴图 + - `_selectParallaxTexture(self, material)`: 选择视差贴图 + - `_selectEmissionTexture(self, material)`: 选择自发光贴图 + - `_selectAOTexture(self, material)`: 选择环境光遮蔽贴图 + - `_selectAlphaTexture(self, material)`: 选择透明度贴图 + - `_selectDetailTexture(self, material)`: 选择细节贴图 + - `_selectGlossTexture(self, material)`: 选择光泽贴图 + - `_applyDiffuseTexture(self, material_title, texture_path)`: 应用漫反射贴图 + - `_applyNormalTexture(self, material, texture_path)`: 应用法线贴图 + - `_applyRoughnessTexture_FINAL(self, material, texture_path)`: 应用粗糙度贴图 + - `_hasNormalTexture(self, node)`: 检查节点是否有法线贴图 + - `_applySmartPBREffect(self, node, effect_file="effects/default.yaml")`: 智能应用PBR效果 + - `_verifyTextureInShader(self, node, texture_type, expected_sort)`: 验证纹理是否在shader中正确处理 + - `_ensureEnhancedPBREffect(self, node)`: 确保节点使用增强的PBR效果 + - `_createWhiteDiffuseTexture(self, node)`: 创建白色漫反射纹理 + - `_applyMetallicTexture(self, material, texture_path)`: 应用金属性贴图 + - `_applyIORTexture(self, material, texture_path)`: 应用IOR贴图 + - `_applyParallaxTexture(self, material, texture_path)`: 应用视差贴图 + - `_ensureNormalMappingEnabled(self, model)`: 确保模型启用了法线映射功能 + - `_ensurePBREffectEnabled(self, model)`: 确保模型启用了完整的PBR效果 + - `_ensurePBREffectEnabledWithParallax(self, model)`: 确保模型启用了完整的PBR效果,包括视差映射 + - `_ensurePBREffectEnabledWithMetallic(self, model)`: 确保模型启用了支持金属性贴图的PBR效果 + - `_ensurePBREffectEnabledWithDirectMetallic(self, model)`: 确保模型启用了支持金属性贴图直接控制的PBR效果 + - `_onMetallicModeChanged(self, material, mode_index)`: 处理金属性控制模式变化 + - `_ensurePBREffectEnabledWithAdditiveMetallic(self, model)`: 确保模型启用了支持金属性贴图叠加控制的PBR效果 + - `_ensurePBREffectEnabledWithEmission(self, model)`: 确保模型启用了支持自发光贴图的PBR效果 + - `_ensurePBREffectEnabledWithAlpha(self, model)`: 确保模型启用了支持透明度的PBR效果 + - `_ensurePBREffectEnabledWithRoughness(self, model)`: 确保模型启用了支持粗糙度贴图的PBR效果 + - `_ensurePBREffectEnabledStable(self, model)`: 确保模型启用了稳定的PBR效果 + - `_applyEmissionTexture(self, material, texture_path)`: 应用自发光贴图 + - `_applyAOTexture(self, material, texture_path)`: 应用环境光遮蔽贴图 + - `_applyAlphaTexture(self, material, texture_path)`: 应用透明度贴图 + - `_applyDetailTexture(self, material, texture_path)`: 应用细节贴图 + - `_applyGlossTexture(self, material, texture_path)`: 应用光泽贴图 + - `_clearConflictingTextureStages(self, node)`: 清理可能冲突的纹理阶段 + - `_findNodeWithMaterial(self, target_material)`: 查找使用指定材质的节点 + - `_findMaterialAndNodeByTitle(self, material_title)`: 根据材质标题查找对应的材质和节点 + - `_findSpecificGeomNodeWithMaterial(self, model, target_material)`: 查找使用指定材质的具体几何节点 + - `_findSpecificGeomNodeForMaterial(self, target_material)`: 查找使用指定材质的具体几何节点 + - `_findGeomNodeWithMaterial(self, model, target_material)`: 查找使用指定材质的具体几何节点 + - `_displayCurrentTextures(self, material, material_layout, current_row)`: 显示当前材质的贴图信息 + - `_applyToAllMaterials(self, model, property_name, value)`: 将属性应用到模型的所有材质 + - `_addShadingModelPanel(self, material, material_layout, current_row)`: 添加着色模型选择面板 + - `_onShadingModelChanged(self, material, model_index)`: 处理着色模型变化 + - `_updateShadingModel(self, material, model_index)`: 更新着色模型 + - `_addTransparencyPanel(self, material, material_layout, current_row)`: 添加透明度控制面板 + - `_updateTransparency(self, material, opacity_value)`: 更新不透明度值 + - `_updateMaterialAlphaForTransparency(self, material, opacity_slider)`: 为透明度更新材质Alpha + - `_applyTransparentRenderingEffect(self)`: 为当前选中的模型应用透明渲染效果 + - `_addEmissionPanel(self, material, material_layout, current_row)`: 添加自发光控制面板 + - `_updateEmissionStrength(self, material, strength)`: 更新自发光强度 + - `_addMaterialPresetPanel(self, material, material_layout, current_row)`: 添加材质预设面板 + - `_detectCurrentPreset(self, material)`: 检测当前材质最接近的预设 + - `_applyMaterialPreset(self, material, preset_name)`: 应用材质预设 + - `_apply_transparent_effect(self)`: 为当前选中的模型应用透明渲染效果 + - `_refreshMaterialUI(self)`: 刷新材质 UI 显示 + - `_addBatchOperationsPanel(self, model)`: 添加批量操作面板 + - `_batchSetRoughness(self, model)`: 批量设置粗糙度 + - `_applyMetallicTexture_NEW(self, material, texture_path)`: 应用金属性贴图 + - `_hasMetallicTexture(self, node)`: 检查节点是否有金属性贴图 + - `_applyDefaultNormalTexture(self, node)`: 应用RenderPipeline的默认法线贴图 + - `_needsAlphaTesting(self, node)`: 检查节点是否需要透明度测试 + - `_addSunAzimuthPanel(self)`: 添加太阳方位角控制面板 + - `_onSunAzimuthSliderChanged(self, value)`: 滑块值改变时的回调 + - `_onSunAzimuthSpinboxChanged(self, value)`: 数值框值改变时的回调 + - `_onSunAltitudeSliderChanged(self, value)`: 太阳高度角滑块值改变时的回调 + - `_onSunAltitudeSpinboxChanged(self, value)`: 太阳高度角数值框值改变时的回调 + - `_setSunPreset(self, preset_name)`: 设置太阳预设位置 + - `_applySunAzimuth_new(self, azimuth_value)`: 应用太阳方位角 + - `_applySunAltitude(self, altitude_value)`: 应用太阳高度角 + - `_updateDayTimeEditorSetting(self, plugin_name, setting_name, value)`: 直接更新Day Time Editor中的设置节点值 + - `_applySunAzimuth(self, azimuth_degrees)`: 应用太阳方位角到Day Time Editor中的Sun Azimuth节点 + - `_sendSunAzimuthViaFile(self, azimuth_degrees)`: 通过文件通信发送Sun Azimuth值到Day Time Editor + - `_addAnimationPanel(self, origin_model)`: 添加动画面板 + - `_buildSkeletalUI(self, origin_model, actor, layout)`: 构建骨骼动画UI + - `_getModelFormat(self, origin_model)`: 获取模型格式信息 + - `_processAnimationNames(self, origin_model, anim_names)`: 处理和分析动画名称 + - `_isLikelyBoneGroup(self, name)`: 判断动画名称是否更像骨骼组而不是动画序列 + - `_analyzeAnimationQuality(self, actor, anim_names, format_info)`: 分析动画质量和类型 + - `_getActor(self, origin_model)`: 获取Actor + - `_createFBXActor(self, origin_model, filepath)`: 专门为 FBX 文件创建 Actor + - `_convertFBXToActor(self, fbx_path)`: 将 FBX 转换为可用的 Actor + - `_fixFBXAnimations(self, actor, fbx_path)`: 修复 FBX Actor 的动画数据 + - `_deepAnalyzeFBX(self, fbx_path)`: 深度分析 FBX 文件并尝试提取动画 + - `_convertFBXManually(self, origin_model)`: 手动转换 FBX 动画 + - `_systemConvertFBX(self, fbx_path, progress=None)`: 使用系统工具转换 FBX + - `_playAnimation(self, origin_model)`: 播放动画 + - `_pauseAnimation(self, origin_model)`: 暂停动画 + - `_stopAnimation(self, origin_model)`: 停止动画 + - `_loopAnimation(self, origin_model)`: 循环动画 + - `_setAnimationSpeed(self, origin_model, speed)`: 设置动画播放倍速 + - `_dispatchAnimCommand(self, origin_model, cmd)`: 分发动画命令 + - `removeActorForModel(self, model)`: 删除 model 对应的 Actor + - `_addCollisionPanel(self, model)`: 添加碰撞检测面板 + - `_addCollisionParameterControls(self, model, layout, start_row, shape_type)`: 添加碰撞参数调整控件 + - `_createCollisionSpinBox(self, min_val, max_val, decimals=2)`: 创建碰撞参数调整用的SpinBox + - `_addSphereParameters(self, model, layout, start_row)`: 添加球形碰撞参数 + - `_addBoxParameters(self, model, layout, start_row)`: 添加盒型碰撞参数 + - `_addCapsuleParameters(self, model, layout, start_row)`: 添加胶囊体碰撞参数 + - `_addPlaneParameters(self, model, layout, start_row)`: 添加平面碰撞参数 + - `_hasCollision(self, model)`: 检查模型是否已有碰撞体 + - `_isCollisionVisible(self, model)`: 检查碰撞是否可见 + - `_toggleCollisionVisibility(self, model)`: 切换碰撞可见性 + - `_updateCollisionVisibilityButton(self, model)`: 更新碰撞可见性按钮状态 + - `_getCurrentCollisionShape(self, model)`: 获取当前模型的碰撞形状类型 + - `_setComboToShape(self, shape_type)`: 根据形状类型设置下拉框选择 + - `_getSelectedCollisionShape(self)`: 获取选中的碰撞形状类型 + - `_addCollisionAndUpdate(self, model)`: 添加指定形状的碰撞体并更新界面 + - `_removeCollisionAndUpdate(self, model)`: 移除模型的碰撞体并更新界面 + - `_findButtonRow(self, layout)`: 查找按钮应该在的行数 + - `_updateCollisionPanelState(self, model)`: 更新碰撞面板状态 + - `_loadCurrentCollisionParameters(self, model, shape_type)`: 加载当前碰撞参数到界面 + - `_getCollisionShapeCenter(self, solid)`: 从碰撞体形状中获取中心点 + - `_loadSphereParameters(self, solid)`: 加载球形参数 + - `_loadBoxParameters(self, solid)`: 加载盒型参数 + - `_loadCapsuleParameters(self, solid)`: 加载胶囊体参数 + - `_loadPlaneParameters(self, solid)`: 加载平面参数 + - `_updateCollisionPosition(self, model, axis, value)`: 更新碰撞位置偏移 + - `_updateSphereRadius(self, model, radius)`: 更新球形半径 + - `_updateBoxSize(self, model, dimension, value)`: 更新盒型尺寸 + - `_updateCapsuleRadius(self, model, radius)`: 更新胶囊体半径 + - `_updateCapsuleHeight(self, model, height)`: 更新胶囊体高度 + - `_updatePlaneNormal(self, model, axis, value)`: 更新平面法向量 + - `_recreateCollisionShape(self, model, shape_type, **kwargs)`: 重新创建碰撞形状 + - `_clearCollisionParameterControls(self)`: 清理碰撞参数控件 + - `_refreshCollisionPanel(self, model)`: 刷新整个碰撞面板 + - `_addParameterControlsToExistingPanel(self, model, shape_type)`: 向现有面板添加参数控件 + - `_addSphereParametersToExisting(self, model, layout, start_row)`: 向现有面板添加球形参数 + - `_addBoxParametersToExisting(self, model, layout, start_row)`: 向现有面板添加盒型参数 + - `_addCapsuleParametersToExisting(self, model, layout, start_row)`: 向现有面板添加胶囊体参数 + - `_addPlaneParametersToExisting(self, model, layout, start_row)`: 向现有面板添加平面参数 + - `_addVisibilityButtonToExistingPanel(self, model)`: 向现有面板添加可见性按钮 + - `_repositionButtons(self, new_row)`: 重新定位按钮位置 + - `_hideCollisionParameterControls(self)`: 隐藏碰撞参数控件 + +### 10. `ui/simple_maintenance_login.py` + +#### 类: SimpleMaintenanceLoginDialog +- **功能**: 简化的维修系统登录对话框 +- **信号**: + - `login_success`: 登录成功信号 +- **方法**: + - `__init__(self, parent=None)`: 初始化登录对话框 + - `setupUI(self)`: 设置用户界面,包括标题、登录表单、提示信息和按钮,应用样式和布局 + - `handle_login(self)`: 处理登录,验证账号密码,成功时发射login_success信号 + +#### 函数: test_simple_login +- **功能**: 测试简化登录界面 +- **方法**: + - `test_simple_login()`: 测试简化登录界面功能 + +### 11. `ui/widgets.py` + +#### 类: NewProjectDialog +- **功能**: 新建项目对话框 +- **方法**: + - `__init__(self, parent=None)`: 初始化新建项目对话框 + - `createTitleBar(self)`: 创建自定义标题栏 + - `_applyTitleBarIcons(self)`: 为标题栏按钮应用图标 + - `toggleMaximize(self)`: 切换窗口最大化/还原 + - `setWindowTitle(self, title)`: 设置窗口标题 + - `mousePressEvent(self, event)`: 鼠标按下事件 - 用于拖拽窗口 + - `mouseDoubleClickEvent(self, event)`: 双击标题栏切换最大化 + - `mouseMoveEvent(self, event)`: 鼠标移动事件 - 用于拖拽窗口 + - `mouseReleaseEvent(self, event)`: 鼠标释放事件 - 停止拖拽 + - `browsePath(self)`: 浏览选择项目路径 + - `validate(self)`: 验证输入并关闭对话框 + +#### 类: CustomPanda3DWidget +- **功能**: 自定义Panda3D显示部件 +- **方法**: + - `__init__(self, world, parent=None)`: 初始化自定义Panda3D显示部件 + - `getActualSize(self)`: 获取Qt部件的实际渲染尺寸 + - `dragEnterEvent(self, event)`: 处理拖拽进入事件 + - `dragMoveEvent(self, event)`: 处理拖拽移动事件 + - `dropEvent(self, event)`: 处理拖放事件 + - `wheelEvent(self, event)`: 处理滚轮事件 + - `mousePressEvent(self, event)`: 处理 Qt 鼠标按下事件 + - `mouseReleaseEvent(self, event)`: 处理 Qt 鼠标释放事件 + - `mouseMoveEvent(self, event)`: 处理 Qt 鼠标移动事件 + - `cleanup(self)`: 清理Panda3D资源 + +#### 类: CustomFileView +- **功能**: 自定义文件浏览器 +- **方法**: + - `__init__(self, world, parent=None)`: 初始化自定义文件浏览器 + - `setupUI(self)`: 初始化UI设置 + - `setupDragDrop(self)`: 设置拖拽功能 + - `startDrag(self, supportedActions)`: 开始拖拽操作 + - `mouseDoubleClickEvent(self, event)`: 双击标题栏切换最大化 + +#### 类: CustomAssetsTreeWidget +- **功能**: 自定义资源树形控件 +- **方法**: + - `__init__(self, world, parent=None)`: 初始化自定义资源树形控件 + - `showContextMenu(self, position)`: 显示右键菜单 + - `_saveExpandedState(self)`: 保存展开状态 + - `_restoreExpandedState(self, expanded_paths)`: 恢复展开状态 + - `_refreshWithStatePreservation(self)`: 刷新树形视图并保持状态 + - `createNewFolder(self, parent_item)`: 新建文件夹 + - `createNewFile(self, parent_item)`: 新建文件 + - `renameItem(self, item)`: 重命名文件或文件夹 + - `deleteItem(self, item)`: 删除文件或文件夹 + - `copyPath(self, filepath)`: 复制路径到剪贴板 + - `openFile(self, filepath)`: 打开文件 + - `showProperties(self, item)`: 显示属性面板 + - `setupUI(self)`: 初始化UI设置 + - `setupDragDrop(self)`: 设置拖拽功能 + - `getProjectRootPath(self)`: 获取项目根路径下的Resources文件夹,考虑跨平台 + - `load_file_tree(self)`: 加载树形视图 + - `addWatchedDirectory(self, directory)`: 添加监控目录 + - `removeWatchedDirectory(self, directory)`: 移除监控目录 + - `onDirectoryChanged(self, path)`: 目录发生变化时处理 + - `onFileChanged(self, path)`: 目录发生变化时的处理 + - `refreshView(self)`: 刷新视图 + - `load_directory_tree(self, path, parent_item, max_depth=3, current_depth=0)`: 递归加载目录树 + - `create_simple_tree_item(self, name, path, is_folder)`: 创建简单的树形项目 + - `get_file_icon(self, filename)`: 根据文件扩展名获取图标 + - `startDrag(self, supportedActions)`: 开始拖拽操作 + - `dragEnterEvent(self, event)`: 处理拖拽进入事件 + - `dragMoveEvent(self, event)`: 处理拖拽移动事件 + - `dropEvent(self, event)`: 处理拖放事件 + - `_moveFiles(self, source_paths, target_dir)`: 移动文件到目标目录 + - `_isChildOf(self, potential_child, potential_parent)`: 检查 potential_child 是否是 potential_parent 的子级 + +#### 类: CustomConsoleDockWidget +- **功能**: 自定义控制台停靠部件 +- **方法**: + - `__init__(self, world, parent=None)`: 初始化控制台UI + - `setupUI(self)`: 初始化控制台UI + - `updateFPS(self)`: 更新FPS显示 + - `setupConsoleRedirect(self)`: 设置控制台重定向 + - `addMessage(self, message, msg_type="INFO")`: 添加消息到控制台 + - `clearConsole(self)`: 清空控制台 + - `executeCommand(self)`: 执行命令 + - `cleanup(self)`: 清理资源 + +#### 类: ConsoleRedirect +- **功能**: 控制台重定向类 +- **方法**: + - `__init__(self, console_widget, stream_type)`: 初始化控制台重定向 + - `write(self, text)`: 重定向写入 + - `flush(self)`: 刷新缓冲区 + +#### 类: StyledMessageBox +- **功能**: 统一样式的消息框辅助类 +- **变量**: + - `MESSAGEBOX_STYLE`: 消息框样式 + - `INPUTDIALOG_STYLE`: 输入对话框样式 + - `BUTTON_STYLE`: 按钮样式 +- **方法**: + - `information(parent, title, message)`: 显示信息提示框 + - `question(parent, title, message, buttons=QMessageBox.Yes | QMessageBox.No, defaultButton=QMessageBox.No)`: 显示确认对话框 + - `warning(parent, title, message)`: 显示警告对话框 + - `critical(parent, title, message)`: 显示错误对话框 + - `getText(parent, title, label, text="")`: 显示样式统一的文本输入对话框 + +#### 类: UniversalMessageDialog +- **功能**: 通用消息对话框类 - 支持不同图标和按钮配置 +- **枚举**: + - `SUCCESS`: 成功图标 + - `WARNING`: 警告图标 + - `ERROR`: 错误图标 + - `INFO`: 信息图标 +- **方法**: + - `__init__(self, parent, title, message, message_type=INFO, show_cancel=True, confirm_text="确认", cancel_text="取消", icon_size=QSize(20, 20))`: 初始化通用消息对话框 + - `_get_message_icon(self)`: 根据消息类型获取对应图标 + - `_setup_styles(self)`: 设置对话框样式 + - `_create_ui(self, message)`: 构建用户界面 + - `_create_title_bar(self)`: 创建自定义标题栏 + - `_apply_title_bar_icons(self)`: 应用标题栏图标 + - `setWindowTitle(self, title)`: 设置窗口标题 + - `mousePressEvent(self, event)`: 鼠标按下事件 - 用于拖拽窗口 + - `mouseMoveEvent(self, event)`: 鼠标移动事件 - 用于拖拽窗口 + - `mouseReleaseEvent(self, event)`: 鼠标释放事件 - 停止拖拽 + - `show_success(parent, title, message, show_cancel=False, confirm_text="确认")`: 显示成功消息对话框 + - `show_warning(parent, title, message, show_cancel=True, confirm_text="确认", cancel_text="取消")`: 显示警告消息对话框 + - `show_error(parent, title, message, show_cancel=False, confirm_text="确认")`: 显示错误消息对话框 + - `show_info(parent, title, message, show_cancel=True, confirm_text="确认", cancel_text="取消")`: 显示信息消息对话框 + +#### 类: StyledTextInputDialog +- **功能**: 与新建项目样式一致的文本输入对话框 +- **方法**: + - `__init__(self, parent, title, label_text="", placeholder="", default_text="")`: 初始化文本输入对话框 + - `_createTitleBar(self)`: 创建标题栏 + - `_applyTitleBarIcons(self)`: 应用标题栏图标 + - `setWindowTitle(self, title)`: 设置窗口标题 + - `_onAccept(self)`: 确认按钮点击事件 + - `text(self)`: 获取输入文本 + - `mousePressEvent(self, event)`: 鼠标按下事件 + - `mouseMoveEvent(self, event)`: 鼠标移动事件 + - `mouseReleaseEvent(self, event)`: 鼠标释放事件 + +#### 类: CustomTreeWidget +- **功能**: 自定义场景树部件 +- **方法**: + - `__init__(self, world, parent=None)`: 初始化自定义场景树部件 + - `initData(self)`: 初始化变量 + - `setupUI(self)`: 初始化UI设置 + - `setupDragDrop(self)`: 设置拖拽功能 + - `setupContextMenu(self)`: 设置右键菜单 + - `showContextMenu(self, position)`: 显示右键菜单 + - `dropEvent(self, event)`: 处理拖放事件 + - `_ensureUnderSceneRoot(self, item)`: 确保节点在场景根节点下 + - `isValidParentChild(self, dragged_item, target_item)`: 检查是否是有效的父子关系 + - `_validateGUITypeCompatibility(self, dragged_item, target_item)`: 验证GUI元素类型兼容性 + - `_getRootNode(self, item)`: 获取树中节点的根节点项 + - `dragEnterEvent(self, event)`: 处理拖入事件 + - `dragMoveEvent(self, event)`: 处理拖动事件 + - `keyPressEvent(self, event)`: 处理键盘按键事件 + - `_preprocess_light_items_for_deletion(self, selected_items)`: 预处理灯光节点删除 + - `delete_items(self, selected_items)`: 删除选中的item + - `delete_item(self, panda_node)`: 删除指定节点 panda3D + - `clear_tree(self)`: 清空UI树 + - `_apply_font_to_item(self, item)`: 根据节点层级设置字体大小 + - `_apply_font_recursively(self, item)`: 递归应用字体样式 + - `_handle_rows_inserted(self, parent_index, first, last)`: 在插入新节点时自动调整字体 + - `_cleanup_panda_node_resources(self, panda_node)`: 清理与Panda3D节点相关的所有资源 + - `update_item_name(self, text, item)`: 树节点名字 + - `_findSceneRoot(self)`: 查找场景根节点 + - `create_model_items(self, model: NodePath)`: 创建模型项 + - `_add_all_children_unconditionally(self, parent_item: QTreeWidgetItem, node_path: NodePath)`: 无条件地、递归地添加一个节点下的所有子节点 + - `_generateUniqueNodeName(self, base_name, parent_node)`: 生成唯一的节点名称 + - `add_node_to_tree_widget(self, node, parent_item, node_type)`: 将node元素添加到树形控件 + - `update_selection_and_properties(self, node, qt_item)`: 更新选择状态和属性面板 + - `get_target_parents_for_creation(self)`: 获取创建目标的父节点列表 + - `_isValidParentForNewNode(self, item)`: 检查节点是否适合作为新节点的父节点 + - `get_target_parents_for_gui_creation(self)`: 获取GUI创建目标的父节点列表 + - `isValidParentForGUI(self, item)`: 检查节点是否适合作为GUI元素的父节点 + - `is_gui_element(self, node)`: 判断节点是否是GUI元素 + - `calculate_relative_gui_position(self, pos, parent_gui)`: 计算相对于GUI父节点的位置 + - `add_existing_node(self, panda_node, node_type="SCENE_NODE", parent_item=None)`: 将已存在的Panda3D节点添加到Qt树形控件中 + - `_findRenderItem(self)`: 查找render根节点项目 + - `create_item(self, node_type="empty", selected_items=None)`: 创建不同类型的场景节点 + - `_determineParentItems(self, selected_items)`: 确定父节点项目列表 + - `_setupNewNodeDefaults(self, node)`: 设置新节点的默认属性 + - `_createEmptyNode(self, parent_node, parent_item)`: 创建空节点 + - `_createSpotLightNode(self, parent_node, parent_item)`: 创建聚光灯节点 + - `_createPointLightNode(self, parent_node, parent_item)`: 创建点光源节点 \ No newline at end of file diff --git a/源代码架构说明.md b/源代码架构说明.md new file mode 100644 index 00000000..318bfaf0 --- /dev/null +++ b/源代码架构说明.md @@ -0,0 +1,1026 @@ +# 源代码整体架构说明 + +## 1. 项目整体结构 + +项目根目录包含以下主要目录和文件: + +- `core/`: 核心模块,包含世界类、VR系统、选择系统、工具管理器、脚本系统等核心功能。 +- `gui/`: GUI管理模块,负责2D和3D GUI元素的创建与管理。 +- `project/`: 项目管理模块,处理项目文件的加载、保存等操作。 +- `scene/`: 场景管理模块,负责场景中模型的管理。 +- `QPanda3D/`: Panda3D与PyQt5集成库,提供Panda3D渲染窗口的Qt部件封装。 +- `scripts/`: 脚本文件目录,包含各种可挂载到对象的Python脚本。 +- `core/vr/`: VR子系统,包含VR相关的配置、交互、性能、渲染、测试、跟踪和可视化模块。 +- `render_pipeline/` 渲染管线模块 +- `config/`: 配置文件目录,包含VR设置等配置文件。 +- `Resources/`: 资源文件目录,包含模型、纹理等资源。 +- `requirements/`: 依赖管理文件目录。 +- `ui/`: UI组件和主窗口定义。 +- `icons/`: 图标资源文件。 +- `templates/`: 模板文件。 +- `tex/`: 纹理资源文件。 +- `vr_actions/`: VR动作相关文件。 +- `main.py`: 程序主入口文件。 +- `Start_Run.py`: 启动脚本。 + +## 2. 各模块详细说明 + +接下来将详细说明每个模块及其包含的文件。 + +### 2.1 core模块 + +`core/`目录包含了应用程序的核心功能模块,是整个系统的基础。 + +#### 2.1.1 核心文件 + +1. `__init__.py`: Python包初始化文件。 + +2. `world.py`: + - 定义了`CoreWorld`类,是整个3D世界的基础类。 + - 负责基本的场景设置,如相机、光照、坐标轴、地面网格等。 + - 提供资源路径管理和中文字体支持。 + +3. `vr_manager.py`: + - VR管理器主文件,负责VR系统的初始化和管理。 + - 集成了OpenVR/SteamVR支持,处理HMD和控制器的跟踪。 + - 管理VR渲染系统,支持普通渲染和RenderPipeline高级渲染。 + - 包含VR交互系统(抓取、传送、摇杆控制等)。 + +4. `selection.py`: + - 选择系统模块。 + - 实现了3D场景中对象的选择功能。 + - 提供选择历史管理和选择对象的可视化。 + +5. `tool_manager.py`: + - 工具管理器模块。 + - 管理各种编辑工具(选择、移动、旋转、缩放等)。 + - 处理工具状态和工具切换逻辑。 + +6. `script_system.py`: + - 脚本系统模块。 + - 管理游戏对象的脚本挂载和执行。 + - 提供脚本的热重载功能。 + +7. `gui_manager.py`: + - GUI管理器模块。 + - 负责2D和3D GUI元素的创建和管理。 + - 提供GUI编辑模式和属性面板集成。 + +8. `terrain_manager.py`: + - 地形管理器模块。 + - 处理3D地形的创建、编辑和渲染。 + - 支持高度图导入和LOD更新。 + +9. `collision_manager.py`: + - 碰撞管理器模块。 + - 管理场景中的碰撞检测和响应。 + - 提供碰撞历史和统计功能。 + +10. `event_handler.py`: + - 事件处理器模块。 + - 处理用户输入事件和系统事件。 + - 提供事件分发和处理机制。 + +11. `Command_System.py`: + - 命令系统模块。 + - 实现命令模式,支持撤销/重做功能。 + - 管理命令的执行和历史记录。 + +12. `InfoPanelManager.py`: + - 信息面板管理器模块。 + - 管理场景中信息面板的显示和更新。 + - 提供性能监控和调试信息显示。 + +13. `patrol_system.py`: + - 巡检系统模块。 + - 实现自动化巡检路径和逻辑。 + - 支持巡检点设置和巡检过程监控。 + +14. `assembly_interaction.py`: + - 装配交互模块。 + - 处理复杂装配体的交互逻辑。 + - 支持装配和拆卸操作。 + +15. `CustomMouseController.py`: + - 自定义鼠标控制器模块。 + - 提供定制化的鼠标操作控制。 + - 支持不同的鼠标交互模式。 + +16. `maintenance_gui.py`: + - 维护GUI模块。 + - 提供设备维护相关的GUI界面。 + - 支持维护任务管理和状态显示。 + +#### 2.1.2 VR子模块 + +`core/vr/`目录包含了VR系统的各个子模块: + +1. `config/`: VR配置管理模块。 + - `__init__.py`: Python包初始化文件。 + - `vr_config.py`: VR配置管理器模块,负责VR设置的保存、加载和管理,包括渲染模式、分辨率缩放、质量预设等参数的配置和管理。 + - `joystick_config.py`: VR摇杆配置模块,提供摇杆交互的配置选项和预设,包括不同的转向模式和灵敏度设置、传送参数调整等。 + - `shadow_stage.py`: VR专用阴影Stage模块,为VR渲染管线提供阴影支持,采用智能复用策略,可选择复用主Pipeline的ShadowAtlas或创建独立的ShadowAtlas。 + - `vr_settings.json`: VR配置文件,存储VR系统的各种设置参数。 + +2. `interaction/`: VR交互系统模块。 + - `__init__.py`: Python包初始化文件。 + - `actions.py`: VR动作系统模块,基于OpenVR Action系统,提供高级的输入处理和动作映射,包括VR动作清单管理、按钮和轴输入处理、触觉反馈、动作集管理等。 + - `grab.py`: VR抓取交互模块,提供VR手柄与3D场景的交互功能,包括射线投射和碰撞检测、对象选择和高亮、对象抓取和移动、UI交互、距离抓取等。 + - `joystick.py`: VR摇杆交互系统模块,提供类似SteamVR的摇杆交互功能,包括摇杆左右转向(旋转视角)、摇杆向前传送预览(抛物线轨迹)、松开摇杆执行传送、死区处理和平滑控制等。 + - `teleport.py`: VR传送系统模块,提供VR传送功能,包括抛物线轨迹计算和可视化、传送点有效性检测、传送执行、可视化反馈(抛物线、落点标记)等。 + +3. `performance/`: VR性能监控模块。 + - `__init__.py`: Python包初始化文件,导出VRPerformanceMonitor类。 + - `monitoring.py`: VR性能监控子系统,负责VR应用的性能监控、GPU计时、管线统计和性能诊断,包含完整的性能报告、监控核心、GPU计时、管线统计、诊断工具、调试控制、配置、查询和控制方法。 + - `optimization.py`: VR对象池和优化系统,负责VR系统中的对象池管理、垃圾回收控制、分辨率缩放和性能模式控制。 + - `MIGRATION_REPORT.md`: VR性能监控子系统迁移完成报告,详细记录了性能监控功能的迁移过程和验证结果。 + +4. `rendering/`: VR渲染模块。 + - `__init__.py`: Python包初始化文件。 + - `stages.py`: VR专用渲染Stages模块,为VR创建简化但完整的渲染管线,支持GBuffer生成(延迟渲染基础)、光照计算(复用主Pipeline的LightManager)、最终合成(tone mapping + gamma校正),包含VRGBufferStage、VRLightingStage、VRAmbientStage、VRFinalStage和VRPipelineController类。 + +5. `testing/`: VR测试模块。 + - `__init__.py`: Python包初始化文件,导出VRTestMode类。 + - `test_mode.py`: VR测试调试子系统,负责VR测试模式、HUD显示和性能测试功能,包含测试模式控制、纹理管理、显示系统、HUD系统、状态查询和性能测试方法,支持VR内容直接显示在屏幕上、实时性能监控HUD、左眼/右眼/立体三种显示模式、渐进式测试功能和性能测试工具。 + +6. `tracking/`: VR跟踪模块。 + - `__init__.py`: Python包初始化文件。 + - `controllers.py`: VR手柄管理模块,基于panda3d-openvr参考实现,提供完整的VR手柄追踪和交互功能,包括手柄位置和姿态追踪、按钮和触摸板输入处理、手柄可视化和射线显示、震动反馈支持,包含VRController基类和LeftController、RightController子类。 + +7. `visualization/`: VR可视化模块。 + - `__init__.py`: Python包初始化文件。 + - `controllers.py`: VR可视化模块,提供VR手柄和交互元素的高级可视化功能,包括手柄3D模型渲染、交互射线显示、按钮状态可视化、触摸板和扳机反馈,包含VRControllerVisualizer类。 + - `effects.py`: VR Effects管理器模块,为VR场景中的模型自动应用RenderPipeline Effects,包含VREffectsManager类和setup_vr_model_effects便捷函数。 + +#### 2.1.3 资源文件 + +- `RotationHandleFull.fbx`, `RotationHandleQuarter.fbx`, `TranslateArrowHandle.fbx`, `UniformScaleHandle.fbx`: 工具控制器的3D模型文件。 + +### 2.2 gui模块 + +`gui/`目录包含了GUI管理系统,负责2D和3D GUI元素的创建和管理。 + +#### 2.2.1 核心文件 + +1. `__init__.py`: Python包初始化文件,导出`GUIManager`类。 + +2. `gui_manager.py`: + - GUI管理器主文件,定义了`GUIManager`类。 + - 负责各种GUI元素的创建,包括: + - 2D GUI元素:按钮、标签、输入框、2D图像、2D视频屏幕等 + - 3D GUI元素:3D文本、3D图像、视频屏幕、球形视频、虚拟屏幕等 + - 提供GUI编辑模式,支持在独立预览窗口中查看和编辑GUI元素。 + - 支持GUI元素的属性编辑、复制、删除等操作。 + - 集成Cesium地图视图功能,支持在GUI中嵌入地图显示。 + - 提供GUI元素在场景树中的管理与属性面板集成。 + - 支持视频播放控制功能,包括播放、暂停、停止和时间控制。 + - 支持2D和3D图像纹理更新功能。 + +### 2.3 project模块 + +`project/`目录包含了项目管理系统,负责项目的生命周期管理。 + +#### 2.3.1 核心文件 + +1. `__init__.py`: Python包初始化文件,导出`ProjectManager`和`NewProjectDialog`类。 + +2. `project_manager.py`: + - 项目管理器主文件,定义了`ProjectManager`类。 + - 负责项目的完整生命周期管理,包括: + - 创建新项目:提供项目创建向导,生成标准项目结构 + - 打开项目:加载项目配置和场景文件 + - 保存项目:保存场景数据和项目配置 + - 打包项目:将项目打包为可执行文件,支持多平台发布 + - 提供项目配置管理,维护项目元数据(创建时间、修改时间、版本等)。 + - 集成文件浏览器,支持项目文件的可视化管理。 + - 提供窗口标题更新等辅助功能。 + - 支持通过路径直接打开项目功能。 + - 在打包过程中复制Resources、scripts和RenderPipelineFile目录。 + - 保存GUI元素信息到JSON文件供打包后使用。 + +### 2.4 QPanda3D模块 + +`QPanda3D/`目录包含了Panda3D与PyQt5集成的库,实现了在Qt应用程序中嵌入Panda3D渲染窗口的功能。 + +#### 2.4.1 核心文件 + +1. `__init__.py`: Python包初始化文件,导出主要的类。 + +2. `QPanda3DWidget.py`: + - 定义了`QPanda3DWidget`类,这是一个继承自`QWidget`的自定义Qt控件。 + - 负责在Qt界面中显示Panda3D渲染内容。 + - 处理用户输入事件(鼠标、键盘)并将其转换为Panda3D事件。 + - 集成定时器系统,定期更新Panda3D场景和重绘Qt控件。 + - 提供窗口尺寸调整功能,保持渲染内容与窗口尺寸同步。 + - 实现了保持宽高比的图像缩放和居中显示功能。 + - 添加了异常处理机制,静默处理TransformState断言错误和其他异常。 + +3. `Panda3DWorld.py`: + - 定义了`Panda3DWorld`类,继承自`ShowBase`。 + - 负责初始化Panda3D环境,设置离屏渲染模式。 + - 集成RenderPipeline渲染管线,提供高质量的渲染效果。 + - 创建用于Qt显示的纹理输出接口。 + - 提供鼠标控制器集成。 + - 添加了VR性能优化配置,包括单缓冲、禁用VSync等设置。 + - 实现了窗口尺寸调整功能,支持同步Panda3D窗口尺寸到Qt窗口尺寸。 + +4. `QMouseWatcherNode.py`: + - 定义了`QMouseWatcherNode`类,继承自`MouseWatcher`。 + - 实现了通过父级QWidget获取鼠标位置和状态的功能。 + - 为Panda3D提供鼠标输入数据。 + +5. `QPanda3D_Keys_Translation.py`: + - 定义了`QPanda3D_Key_translation`字典。 + - 实现了Qt键盘按键到Panda3D键盘事件的映射。 + +6. `QPanda3D_Buttons_Translation.py`: + - 定义了`QPanda3D_Button_translation`字典。 + - 实现了Qt鼠标按键到Panda3D鼠标事件的映射。 + +7. `QPanda3D_Modifiers_Translation.py`: + - 定义了`QPanda3D_Modifier_translation`字典。 + - 实现了Qt修饰键(如Shift、Ctrl、Alt)到Panda3D修饰键的映射。 + +### 2.5 scene模块 + +`scene/`目录包含了场景管理系统,负责场景中模型、光源、地形等元素的管理。 + +#### 2.5.1 核心文件 + +1. `__init__.py`: Python包初始化文件,导出`SceneManager`类。 + +2. `scene_manager.py`: + - 场景管理器主文件,定义了`SceneManager`类。 + - 负责场景中各种元素的管理,包括: + - 模型导入:支持多种3D模型格式(FBX、GLB等),提供模型转换和优化功能 + - 光源管理:创建和管理聚光灯、点光源等不同类型的光源 + - 场景保存和加载:支持将整个场景保存为BAM文件格式,并能完整加载恢复 + - 碰撞检测:为模型设置碰撞体,支持选择和交互功能 + - Cesium 3D Tiles集成:支持加载和显示地理空间数据 + - GUI元素管理:与GUI系统集成,管理场景中的GUI元素 + - 提供模型处理功能,包括材质应用、缩放标准化、位置调整等。 + - 支持异步模型加载,提升用户体验。 + - 集成脚本系统,支持为场景元素挂载和管理脚本。 + +3. `util.py`: + - 工具模块,提供跨平台路径处理功能。 + - 定义了`CrossPlatformPathHandler`类,用于处理不同操作系统的路径问题。 + - 提供路径标准化、文件搜索、错误处理等辅助功能。 + +### 2.6 scripts模块 + +`scripts/`目录包含了各种可挂载到场景对象的脚本文件,用于实现对象的动态行为。 + +#### 2.6.1 核心概念 + +脚本系统基于组件化设计,每个脚本都是一个继承自`ScriptBase`的Python类。脚本可以被挂载到场景中的任何对象上,为对象添加动态行为。 + +#### 2.6.2 脚本文件说明 + +1. `example_script.py`: + - 示例脚本,演示了脚本的基本结构和生命周期方法。 + - 实现了简单的旋转功能。 + +2. `Rotate_H_Script.py`: + - H轴(偏航)旋转脚本,实现对象绕Y轴的机器人式旋转。 + - 支持设置旋转角度范围、速度、停顿时间等参数。 + - 提供多种预设模式(慢速、快速、平滑)。 + +3. `Rotate_P_Script.py`: + - P轴(俯仰)旋转脚本,实现对象绕X轴的机器人式旋转。 + - 支持设置旋转角度范围、速度、停顿时间等参数。 + - 提供多种预设模式(慢速、快速、平滑)。 + +4. `Rotate_R_Script.py`: + - R轴(滚动)旋转脚本,实现对象绕Z轴的旋转。 + - 简化版旋转脚本,适用于基本的旋转需求。 + +5. `MoverScript.py`: + - 移动脚本,实现对象在指定轴向上的来回移动。 + - 支持设置移动距离、速度和移动轴(X/Y/Z)。 + +6. `ScalerScript.py`: + - 缩放脚本,实现对象的呼吸式缩放效果。 + - 支持设置基础缩放、缩放幅度、缩放速度等参数。 + - 提供统一缩放和非统一缩放选项。 + +7. `ColorChangerScript.py`: + - 颜色变化脚本,实现对象颜色的动态变化。 + - 支持多种颜色模式:彩虹、脉冲、淡入淡出、闪烁。 + - 可调整颜色变化速度和强度。 + +8. `BouncerScript.py`: + - 跳跃脚本,实现对象的上下跳跃效果。 + - 支持多种跳跃类型:正弦波、绝对值正弦波、方波。 + - 可设置跳跃高度和速度。 + +9. `ComboAnimatorScript.py`: + - 组合动画脚本,可以同时控制对象的多个属性(位置、旋转、缩放)。 + - 支持复杂的动画序列和时间控制。 + +10. `FollowerScript.py`: + - 跟随脚本,使对象跟随另一个对象或鼠标位置移动。 + - 支持平滑跟随和延迟跟随效果。 + +11. `TestMover.py`、`TestRotator.py`、`TestScaler.py`: + - 测试脚本,用于验证脚本系统的基本功能。 + +12. `a.py`、`R_P.py`、`R_R.py`、`Rotate_H_Script.py`: + - 其他功能脚本,实现特定的动画或交互效果。 + +### 2.7 RenderPipelineFile模块 + +`RenderPipelineFile/`目录包含了Panda3D的高级渲染管线实现,提供了基于物理的着色、延迟渲染和后处理效果。 + +#### 2.7.1 核心特性 + +- 基于物理的着色(Physically Based Shading) +- 延迟渲染(Deferred Rendering) +- 高级后处理效果和框架 +- 时间ofday系统 +- 插件系统 + +#### 2.7.2 目录结构 + +1. `config/`: 配置文件目录 + - `debugging.yaml`: 调试配置 + - `panda3d-config.prc`: Panda3D配置 + - `pipeline.yaml`: 渲染管线配置 + - `plugins.yaml`: 插件配置 + - `stages.yaml`: 渲染阶段配置 + - `task-scheduler.yaml`: 任务调度配置 + +2. `data/`: 数据资源目录 + - `builtin_models/`: 内置模型资源 + - `skybox/`: 天空盒模型 + - `default_cubemap/`: 默认立方体贴图资源 + - `source/`: 源文件目录 + - `source_2/`: 源文件目录2 + - `cubemap.txo.pz`: 立方体贴图文件 + - `filter.compute.glsl`: 过滤计算着色器 + - `filter.py`: 过滤脚本 + - `empty_textures/`: 空纹理资源 + - `empty_basecolor.png`: 空基础颜色纹理 + - `empty_normal.png`: 空法线纹理 + - `empty_roughness.png`: 空粗糙度纹理 + - `empty_specular.png`: 空镜面反射纹理 + - `README.md`: 说明文档 + - `environment_brdf/`: 环境BRDF资源 + - `res/`: 资源目录 + - `slices/`: 切片目录 + - `slices_coat/`: 涂层切片目录 + - `slices_metal/`: 金属切片目录 + - `generate_reference.py`: 生成参考脚本 + - `run_mitsuba.bat`: Mitsuba运行脚本 + - `film_grain/`: 胶片颗粒资源 + - `generate.py`: 生成脚本 + - `grain.compute.glsl`: 颗粒计算着色器 + - `grain.txo.pz`: 颗粒纹理文件 + - `font/`: 字体资源 + - 包含Roboto字体系列的各种样式和粗细版本 + - `roboto-LICENSE.txt`: 字体许可证 + - `gui/`: GUI资源 + - 包含各种GUI元素的纹理和图标资源 + - `ies_profiles/`: IES光照配置文件 + - 包含多种光照配置文件,如area_light.ies、bollard.ies等 + - `PREVIEWS.jpg`: 预览图片 + - `README.md`: 说明文档 + - `Materials/`: 材质资源 + - `GroundMaterial.yaml`: 地面材质配置 + - `panda3d_patches/`: Panda3D补丁 + - `prev-model-view-matrix-part2.diff`: 模型视图矩阵补丁2 + - `prev-model-view-matrix.diff`: 模型视图矩阵补丁 + - `README.md`: 说明文档 + - `scripts/`: 脚本资源 + - `example_script.py`: 示例脚本 + - `setup/`: 安装设置资源 + - `check_requirements.py`: 检查依赖脚本 + - `generate_txo_files.py`: TXO文件生成脚本 + - `install.flag`: 安装标志文件 + +3. `effects/`: 效果定义目录 + - `basic_instancing.yaml`: 基础实例化效果 + - `debug_metallic.yaml`: 金属度调试效果 + - `debug_roughness.yaml`: 粗糙度调试效果 + - `default.yaml`: 默认效果 + - `material_blend4.yaml`: 四材质混合效果 + - `metallic_only.yaml`: 仅金属度效果 + - `pbr_additive_metallic.yaml`: PBR附加金属度效果 + - `pbr_direct_metallic.yaml`: PBR直接金属度效果 + - `pbr_direct_roughness.yaml`: PBR直接粗糙度效果 + - `pbr_extended.yaml`: 扩展PBR效果 + - `pbr_with_emission.yaml`: 带自发光的PBR效果 + - `pbr_with_metallic.yaml`: 带金属度的PBR效果 + - `pbr_with_normal.yaml`: 带法线贴图的PBR效果 + - `pbr_with_roughness.yaml`: 带粗糙度的PBR效果 + - `pbr_with_textures.yaml`: 带纹理的PBR效果 + - `roughness_only.yaml`: 仅粗糙度效果 + - `simple_texture_test.yaml`: 简单纹理测试效果 + - `simple_transparent.yaml`: 简单透明效果 + - `skybox.yaml`: 天空盒效果 + - `terrain-effect.yaml`: 地形效果 + - `test_metallic_debug.yaml`: 金属度调试测试效果 + - `test_roughness_debug.yaml`: 粗糙度调试测试效果 + +4. `rpcore/`: 核心渲染管线模块 + - `__init__.py`: Python包初始化文件 + - `common_resources.py`: 通用资源管理 + - `effect.py`: 效果管理 + - `globals.py`: 全局变量和设置 + - `gpu_command_queue.py`: GPU命令队列 + - `image.py`: 图像处理 + - `light_manager.py`: 光源管理器 + - `loader.py`: 资源加载器 + - `mount_manager.py`: 挂载管理器 + - `render_pipeline.py`: 渲染管线主类 + - `render_stage.py`: 渲染阶段基类 + - `render_target.py`: 渲染目标管理 + - `rpobject.py`: RP对象基类 + - `stage_manager.py`: 阶段管理器 + + - `gui/`: GUI相关组件 + - `__init__.py`: 初始化文件 + - `buffer_viewer.py`: 缓冲区查看器 + - `checkbox_collection.py`: 复选框集合 + - `checkbox.py`: 复选框组件 + - `debugger.py`: 调试器 + - `draggable_window.py`: 可拖拽窗口 + - `error_message_display.py`: 错误信息显示 + - `exposure_widget.py`: 曝光控件 + - `fps_chart.py`: FPS图表 + - `labeled_checkbox.py`: 带标签的复选框 + - `loading_screen.py`: 加载屏幕 + - `pipe_viewer.py`: 管道查看器 + - `pixel_inspector.py`: 像素检查器 + - `README.md`: 说明文档 + - `render_mode_selector.py`: 渲染模式选择器 + - `slider.py`: 滑块控件 + - `sprite.py`: 精灵组件 + - `text_node.py`: 文本节点 + - `text.py`: 文本组件 + - `texture_preview.py`: 纹理预览器 + + - `native/`: 原生C++模块接口 + - `__init__.py`: 初始化文件 + - `source/`: C++源代码目录 + - `config_rsnative.cpp/h/N`: 原生配置模块 + - `gpu_command_list.cpp/h`: GPU命令列表 + - `gpu_command.cpp/h/I`: GPU命令 + - `ies_dataset.cpp/h`: IES数据集 + - `internal_light_manager.cpp/h/I`: 内部光源管理器 + - `pointer_slot_storage.h`: 指针槽存储 + - `pssm_camera_rig.cpp/h/I`: PSSM相机支架 + - `pssm_helper.cpp/h`: PSSM辅助函数 + - `README.md`: 说明文档 + - `rp_light.cpp/h/I`: RP光源基类 + - `rp_point_light.cpp/h/I`: RP点光源 + - `rp_spot_light.cpp/h/I`: RP聚光灯 + - `shadow_atlas.cpp/h/I`: 阴影图集 + - `shadow_manager.cpp/h/I`: 阴影管理器 + - `shadow_source.cpp/h/I`: 阴影源 + - `tag_state_manager.cpp/h/I`: 标签状态管理器 + - `.gitignore`: Git忽略文件 + - `config.ini`: 配置文件 + - `update_module_builder.py`: 模块构建器更新脚本 + - `use_cxx.flag`: C++使用标志文件 + + - `pluginbase/`: 插件基础类 + - `__init__.py`: 初始化文件 + - `base_plugin.py`: 插件基类 + - `day_manager.py`: 日间管理器 + - `day_setting_types.py`: 日间设置类型 + - `manager.py`: 管理器 + - `setting_types.py`: 设置类型 + + - `pynative/`: Python原生接口 + - `__init__.py`: 初始化文件 + - `gpu_command_list.py`: GPU命令列表Python接口 + - `gpu_command.py`: GPU命令Python接口 + - `ies_dataset.py`: IES数据集Python接口 + - `internal_light_manager.py`: 内部光源管理器Python接口 + - `pointer_slot_storage.py`: 指针槽存储Python接口 + - `pssm_camera_rig.py`: PSSM相机支架Python接口 + - `README.md`: 说明文档 + - `rp_light.py`: RP光源Python接口 + - `rp_point_light.py`: RP点光源Python接口 + - `rp_spot_light.py`: RP聚光灯Python接口 + - `shadow_atlas.py`: 阴影图集Python接口 + - `shadow_manager.py`: 阴影管理器Python接口 + - `shadow_source.py`: 阴影源Python接口 + - `tag_state_manager.py`: 标签状态管理器Python接口 + + - `shader/`: 着色器管理 + - `ibl/`: 基于图像的光照着色器 + - `cubemap_diffuse_filter.frag.glsl`: 立方体贴图漫反射过滤片段着色器 + - `cubemap_diffuse.frag.glsl`: 立方体贴图漫反射片段着色器 + - `cubemap_specular_filter_first.frag.glsl`: 立方体贴图镜面反射过滤第一阶段片段着色器 + - `cubemap_specular_filter.frag.glsl`: 立方体贴图镜面反射过滤片段着色器 + - `cubemap_specular_prefilter_first.frag.glsl`: 立方体贴图镜面反射预过滤第一阶段片段着色器 + - `cubemap_specular_prefilter.frag.glsl`: 立方体贴图镜面反射预过滤片段着色器 + - `includes/`: 包含文件 + - `brdf.inc.glsl`: BRDF函数包含文件 + - `color_spaces.inc.glsl`: 颜色空间包含文件 + - `common_functions.inc.glsl`: 通用函数包含文件 + - `envprobes.inc.glsl`: 环境探针包含文件 + - `forward_shading.inc.glsl`: 前向渲染包含文件 + - `gaussian_weights.inc.glsl`: 高斯权重包含文件 + - `gbuffer.inc.glsl`: G缓冲包含文件 + - `halton_sequences.inc.glsl`: Halton序列包含文件 + - `ies_lighting.inc.glsl`: IES光照包含文件 + - `importance_sampling.inc.glsl`: 重要性采样包含文件 + - `light_classification.inc.glsl`: 光源分类包含文件 + - `light_culling.inc.glsl`: 光源剔除包含文件 + - `light_data.inc.glsl`: 光源数据包含文件 + - `light_data.struct.glsl`: 光源数据结构包含文件 + - `lighting_pipeline.inc.glsl`: 光照管线包含文件 + - `lights.inc.glsl`: 光源包含文件 + - `material.inc.glsl`: 材质包含文件 + - `noise.inc.glsl`: 噪声包含文件 + - `nonviewspace_shading_pipeline.inc.glsl`: 非视图空间着色管线包含文件 + - `normal_mapping.inc.glsl`: 法线映射包含文件 + - `normal_packing.inc.glsl`: 法线打包包含文件 + - `poisson_disk.inc.glsl`: 泊松圆盘包含文件 + - `sampling_sequences.inc.glsl`: 采样序列包含文件 + - `shadows.inc.glsl`: 阴影包含文件 + - `skin_shading.inc.glsl`: 皮肤着色包含文件 + - `source_data.struct.glsl`: 源数据结构包含文件 + - `temporal_resolve.inc.glsl`: 时间解析包含文件 + - `tonemapping.inc.glsl`: 色调映射包含文件 + - `transforms.inc.glsl`: 变换包含文件 + - `upsampling.inc.glsl`: 上采样包含文件 + - `vertex_output.struct.glsl`: 顶点输出结构包含文件 + - `templates/`: 模板文件 + - `envmap.frag.glsl`: 环境贴图片段着色器模板 + - `forward.frag.glsl`: 前向渲染片段着色器模板 + - `gbuffer.frag.glsl`: G缓冲片段着色器模板 + - `shadow.frag.glsl`: 阴影片段着色器模板 + - `vertex.vert.glsl`: 顶点着色器模板 + - `voxelize.frag.glsl`: 体素化片段着色器模板 + - `ambient_stage.frag.glsl`: 环境阶段片段着色器 + - `apply_lights.frag.glsl`: 应用光照片段着色器 + - `bilateral_blur.frag.glsl`: 双边模糊片段着色器 + - `bilateral_halfres_blur.frag.glsl`: 半分辨率双边模糊片段着色器 + - `bilateral_upscale.frag.glsl`: 双边上采样片段着色器 + - `collect_used_cells.frag.glsl`: 收集使用单元片段着色器 + - `combine_velocity.frag.glsl`: 合并速度片段着色器 + - `cull_lights.frag.glsl`: 剔除光源片段着色器 + - `default_gui_shader.vert.glsl`: 默认GUI顶点着色器 + - `default_post_process_instanced.vert.glsl`: 默认后期处理实例化顶点着色器 + - `default_post_process.vert.glsl`: 默认后期处理顶点着色器 + - `downscale_depth.frag.glsl`: 深度下采样片段着色器 + - `final_present_stage.frag.glsl`: 最终呈现阶段片段着色器 + - `final_stage.frag.glsl`: 最终阶段片段着色器 + - `flag_used_cells.frag.glsl`: 标记使用单元片段着色器 + - `fps_chart_update.compute.glsl`: FPS图表更新计算着色器 + - `fps_chart.compute.glsl`: FPS图表计算着色器 + - `group_lights.frag.glsl`: 分组光源片段着色器 + - `pixel_inspector.frag.glsl`: 像素检查器片段着色器 + - `process_command_queue.frag.glsl`: 处理命令队列片段着色器 + - `render_pipeline_base.inc.glsl`: 渲染管线基础包含文件 + - `tiled_culling.vert.glsl`: 平铺剔除顶点着色器 + - `upscale_stage.frag.glsl`: 上采样阶段片段着色器 + - `view_frustum_cull.frag.glsl`: 视锥剔除片段着色器 + - `visualize_exposure.compute.glsl`: 可视化曝光计算着色器 + + - `stages/`: 渲染阶段实现 + - `__init__.py`: 初始化文件 + - `ambient_stage.py`: 环境阶段 + - `apply_lights_stage.py`: 应用光源阶段 + - `collect_used_cells_stage.py`: 收集使用单元阶段 + - `combine_velocity_stage.py`: 合并速度阶段 + - `cull_lights_stage.py`: 剔除光源阶段 + - `downscale_z_stage.py`: Z缓冲下采样阶段 + - `final_stage.py`: 最终阶段 + - `flag_used_cells_stage.py`: 标记使用单元阶段 + - `gbuffer_stage.py`: G缓冲阶段 + - `shadow_stage.py`: 阴影阶段 + - `update_previous_pipes_stage.py`: 更新前一管道阶段 + - `upscale_stage.py`: 上采样阶段 + + - `util/`: 工具函数 + - `__init__.py`: 初始化文件 + - `cubemap_filter.py`: 立方体贴图过滤器 + - `display_shader_builder.py`: 显示着色器构建器 + - `generic.py`: 通用工具函数 + - `ies_profile_loader.py`: IES配置文件加载器 + - `movement_controller.py`: 移动控制器 + - `network_communication.py`: 网络通信 + - `post_process_region.py`: 后期处理区域 + - `shader_input_blocks.py`: 着色器输入块 + - `smooth_connected_curve.py`: 平滑连接曲线 + - `submodule_downloader.py`: 子模块下载器 + - `task_scheduler.py`: 任务调度器 + +5. `rpplugins/`: 插件目录 + - `__init__.py`: 初始化文件 + - `ao/`: 环境光遮蔽插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `ao_stage.py`: AO阶段 + - `config.yaml`: 配置文件 + - `plugin.py`: 插件主文件 + - `bloom/`: 泛光效果插件 + - `__init__.py`: 初始化文件 + - `resources/`: 资源目录 + - `shader/`: 着色器目录 + - `bloom_stage.py`: 泛光阶段 + - `config.yaml`: 配置文件 + - `plugin.py`: 插件主文件 + - `clouds/`: 云渲染插件 + - `__init__.py`: 初始化文件 + - `resources/`: 资源目录 + - `shader/`: 着色器目录 + - `apply_clouds_stage.py`: 应用云阶段 + - `cloud_voxel_stage.py`: 云体素阶段 + - `config.yaml`: 配置文件 + - `plugin.py`: 插件主文件 + - `color_correction/`: 颜色校正插件 + - `__init__.py`: 初始化文件 + - `resources/`: 资源目录 + - `shader/`: 着色器目录 + - `auto_exposure_stage.py`: 自动曝光阶段 + - `color_correction_stage.py`: 颜色校正阶段 + - `config.yaml`: 配置文件 + - `manual_exposure_stage.py`: 手动曝光阶段 + - `plugin.py`: 插件主文件 + - `sharpen_stage.py`: 锐化阶段 + - `tonemapping_stage.py`: 色调映射阶段 + - `dof/`: 景深效果插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `dof_stage.py`: 景深阶段 + - `plugin.py`: 插件主文件 + - `env_probes/`: 环境探针插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `apply_envprobes_stage.py`: 应用环境探针阶段 + - `config.yaml`: 配置文件 + - `cull_probes_stage.py`: 剔除探针阶段 + - `environment_capture_stage.py`: 环境捕捉阶段 + - `environment_probe.py`: 环境探针类 + - `plugin.py`: 插件主文件 + - `probe_manager.py`: 探针管理器 + - `forward_shading/`: 前向渲染插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `forward_stage.py`: 前向渲染阶段 + - `plugin.py`: 插件主文件 + - `fxaa/`: FXAA抗锯齿插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `fxaa_stage.py`: FXAA阶段 + - `plugin.py`: 插件主文件 + - `motion_blur/`: 运动模糊插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `motion_blur_stage.py`: 运动模糊阶段 + - `plugin.py`: 插件主文件 + - `plugin_prefab/`: 插件预制件 + - `__init__.py`: 初始化文件 + - `resources/`: 资源目录 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `demo_stage.py`: 演示阶段 + - `plugin.py`: 插件主文件 + - `pssm/`: 平行分割阴影贴图插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `plugin.py`: 插件主文件 + - `pssm_dist_shadow_stage.py`: PSSM距离阴影阶段 + - `pssm_scene_shadow_stage.py`: PSSM场景阴影阶段 + - `pssm_shadow_stage.py`: PSSM阴影阶段 + - `pssm_stage.py`: PSSM阶段 + - `scattering/`: 散射效果插件 + - `__init__.py`: 初始化文件 + - `resources/`: 资源目录 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `godray_stage.py`: 光线阶段 + - `plugin.py`: 插件主文件 + - `scattering_envmap_stage.py`: 散射环境贴图阶段 + - `scattering_methods.py`: 散射方法 + - `scattering_stage.py`: 散射阶段 + - `skin_shading/`: 皮肤着色插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `plugin.py`: 插件主文件 + - `skin_shading_stage.py`: 皮肤着色阶段 + - `sky_ao/`: 天空AO插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `ao_stage.py`: AO阶段 + - `capture_stage.py`: 捕捉阶段 + - `config.yaml`: 配置文件 + - `plugin.py`: 插件主文件 + - `smaa/`: SMAA抗锯齿插件 + - `__init__.py`: 初始化文件 + - `resources/`: 资源目录 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `jitters.py`: 抖动工具 + - `LICENSE.txt`: 许可证文件 + - `plugin.py`: 插件主文件 + - `smaa_stage.py`: SMAA阶段 + - `ssr/`: 屏幕空间反射插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `plugin.py`: 插件主文件 + - `ssr_stage.py`: SSR阶段 + - `volumetrics/`: 体积渲染插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `plugin.py`: 插件主文件 + - `volumetrics_stage.py`: 体积渲染阶段 + - `vxgi/`: VXGI全局光照插件 + - `__init__.py`: 初始化文件 + - `shader/`: 着色器目录 + - `config.yaml`: 配置文件 + - `plugin.py`: 插件主文件 + - `voxelization_stage.py`: 体素化阶段 + - `vxgi_stage.py`: VXGI阶段 + +6. `toolkit/`: 工具集 + - `bake_gi/`: GI烘焙工具 + - `resources/`: 资源目录 + - `bake.py`: 烘焙脚本 + - `display.py`: 显示脚本 + - `day_time_editor/`: 日间时间编辑器 + - `ui/`: UI目录 + - `curve_widget.py`: 曲线控件 + - `main.py`: 主程序 + - `import_sun_data/`: 导入太阳数据工具 + - `import_data.py`: 导入数据脚本 + - `README.md`: 说明文档 + - `material_editor/`: 材质编辑器 + - `ui/`: UI目录 + - `main.py`: 主程序 + - `pathtracing_reference/`: 路径追踪参考 + - `config/`: 配置目录 + - `res/`: 资源目录 + - `batch_compare.py`: 批量比较脚本 + - `generate_difference.py`: 生成差异脚本 + - `get_brightness.py`: 获取亮度脚本 + - `README.md`: 说明文档 + - `run_mitsuba.bat`: Mitsuba运行脚本 + - `run_renderpipeline.py`: 运行渲染管线脚本 + - `plugin_configurator/`: 插件配置器 + - `ui/`: UI目录 + - `main.py`: 主程序 + - `poisson_disk_generator/`: 泊松圆盘生成器 + - `source/`: 源代码目录 + - `.gitignore`: Git忽略文件 + - `config.ini`: 配置文件 + - `generate_poisson_disk.py`: 生成泊松圆盘脚本 + - `update_module_builder.py`: 更新模块构建器脚本 + - `render_service/`: 渲染服务 + - `config/`: 配置目录 + - `resources/`: 资源目录 + - `example_usage.py`: 使用示例 + - `README.md`: 说明文档 + - `service.py`: 服务脚本 + - `rp_distributor/`: RP分发器 + - `launch.templ.bat`: 启动模板脚本 + - `main.py`: 主程序 + - `README.md`: 说明文档 + +7. `rplibs/`: 第三方库 + - `colorama/`: 终端颜色库 + - `progressbar/`: 进度条库 + - `yaml/`: YAML解析库 + - `__init__.py`: 初始化文件 + - `pyqt_imports.py`: PyQt导入工具 + - `six-source.txt`: Six库源信息 + - `six.py`: Six库兼容工具 + +#### 2.7.3 根目录文件 + + 1. `__init__.py`: Python包初始化文件 + 2. `.flake8`: Flake8配置文件,用于代码风格检查 + 3. `.gitignore`: Git忽略文件,指定不纳入版本控制的文件和目录 + 4. `.pylintrc`: Pylint配置文件,用于代码质量检查 + 5. `.travis.yml`: Travis CI配置文件,用于持续集成 + 6. `Default_NRM_2K.png`: 默认法线贴图,2K分辨率 + 7. `Default_Rough.png`: 默认粗糙度贴图 + 8. `LICENSE.txt`: 许可证文件,采用MIT许可证 + 9. `README.md`: 项目说明文档,包含项目介绍、特性列表和使用说明 + 10. `setup.py`: 安装和配置脚本,负责编译原生模块、生成必要的资源文件和配置渲染管线环境 + 11. `start_daytime_editor.py`: 启动日间编辑器脚本,用于运行时间ofday编辑器 + 12. `start_plugin_configurator.py`: 启动插件配置器脚本,用于运行插件配置工具 + +### 2.8 ui模块 + +`ui/`目录包含了用户界面组件和主窗口定义。 + +#### 2.8.1 核心文件 + +1. `__init__.py`: Python包初始化文件。 + +2. `assembly_disassembly_config_simple.py`: + - 简化版装配拆卸配置界面模块,提供装配拆卸功能的简单配置界面。 + +3. `assembly_disassembly_config.py`: + - 装配拆卸配置界面模块,提供复杂的装配拆卸配置功能。 + +4. `icon_manager_gui.py`: + - 图标管理GUI模块,负责管理界面中的图标资源。 + +5. `icon_manager.py`: + - 图标管理器模块,提供图标资源的加载和管理功能。 + +6. `interface_manager.py`: + - 界面管理器模块,负责管理整个应用程序的界面组件。 + - 处理窗口布局、控件管理和用户交互。 + +7. `main_window.py`: + - 主窗口模块,定义了应用程序的主窗口结构和布局。 + - 负责创建和管理主界面的各种组件。 + +8. `maintenance_system.py`: + - 维护系统模块,提供设备维护相关的界面功能。 + +9. `property_panel.py`: + - 属性面板模块,负责对象属性的显示和编辑。 + - 提供对象属性的可视化编辑界面。 + +10. `simple_maintenance_login.py`: + - 简化版维护登录界面模块,提供维护功能的登录界面。 + +11. `widgets.py`: + - 自定义控件模块,包含各种自定义的UI控件。 + - 提供Panda3D控件和文件视图等特殊控件。 + +### 2.9 templates模块 + +`templates/`目录包含项目模板文件。 + +#### 2.9.1 核心文件 + +1. `main_template.py`: + - 主程序模板文件,提供了一个基础的Panda3D应用程序框架。 + - 包含场景加载、GUI元素处理、动画播放、脚本管理等功能的模板实现。 + - 提供了相机控制、鼠标点击处理、帧率显示等基础功能。 + +### 2.10 主程序文件 + +#### 2.10.1 核心文件 + +1. `main.py`: + - 程序主入口文件,定义了`MyWorld`类,继承自`CoreWorld`。 + - 集成了所有核心系统:选择系统、事件处理、工具管理、脚本管理、GUI管理、场景管理、项目管理、地形管理、属性面板、界面管理、VR管理、碰撞管理等。 + - 提供了兼容性属性和功能代理方法,将各种操作委托给相应的管理器。 + - 实现了键盘事件处理、巡检系统控制、模型导入等核心功能。 + - 包含了与UI模块的集成,通过`setup_main_window`函数创建主窗口。 + +2. `Start_Run.py`: + - 程序启动脚本,负责初始化Python路径和依赖。 + - 自动添加项目根目录、RenderPipeline、RenderPipelineFile和icons目录到Python路径。 + - 处理命令行参数并启动主程序。 + - 提供了项目路径参数的处理功能。 + + +## 3 非代码文件 +### 3.1 config模块 + + `config/`目录包含项目的配置文件,主要用于存储系统设置和参数。 + +#### 3.1.1 核心文件 + + 1. `vr_settings.json`: + - VR系统配置文件,定义了VR渲染模式和质量参数。 + - 包含渲染模式设置(render_pipeline)、分辨率缩放、管线分辨率缩放、质量预设等参数。 + - 包含Pipeline VR配置,如阴影、环境光遮蔽(AO)、泛光(Bloom)、运动模糊等效果的启用状态和质量设置。 + +### 3.2 Resources模块 + + `Resources/`目录包含了项目使用的各种资源文件。 + +#### 3.2.1 目录结构 + + 1. `animations/`: + - 动画资源目录,当前为空。 + + 2. `c/`: + - 测试/临时资源目录,包含一些测试文件和子目录。 + + 3. `icons/`: + - 图标资源目录,包含各种纹理图标: + - `heightmap.png`: 高度图纹理 + - `test_metallic_stripes.png`: 金属度测试纹理 + - `test_roughness_checkerboard.png`: 粗糙度棋盘纹理 + - `test_roughness_circle.png`: 粗糙度圆形纹理 + - `test_roughness_gradient.png`: 粗糙度渐变纹理 + + 4. `materials/`: + - 材质资源目录,当前为空。 + + 5. `models/`: + - 3D模型资源目录,包含示例模型文件: + - `DancingTwerk.glb`: 跳舞动画模型 + - `Haqijingzhu.glb`: 花旗镜柱模型 + - `JQB_auto_converted.glb`: 自动转换的JQB模型 + - `Women_2.glb`: 女性角色模型 + + 6. `textures/`: + - 纹理资源目录,当前为空。 + + 7. `a`: + - 根目录下的测试文件。 + +### 3.3 requirements模块 + + `requirements/`目录包含项目的依赖管理文件,用于环境配置和部署。 + +#### 3.3.1 核心文件 + + 1. `requirements.txt`: + - 项目的完整依赖列表文件,包含所有必要的Python包及其版本。 + - 包括Panda3D、PyQt5、PySide6、Pillow、pyassimp等核心依赖。 + - 还包含系统级包如apturl、bcrypt、dbus-python等。 + + 2. `clean-requirements.txt`: + - 精简的依赖列表文件,仅包含项目核心依赖。 + - 包括Panda3D、PyQt5、PySide6、Pillow、python-dotenv、pyassimp等。 + + 3. `environment.yml`: + - Conda环境配置文件,定义了项目环境的依赖。 + - 指定了Python版本为3.10,并包含了pip依赖项。 + + 4. `conda-requirements.txt`: + - Conda显式依赖文件,用于创建完全相同的环境。 + - 包含了系统级依赖如libgcc、openssl、ncurses等。 + + 5. `DEPLOYMENT_README.md`: + - 项目部署指南文档,提供详细的部署说明。 + - 包含使用Conda和virtualenv两种部署方法。 + - 提供了项目依赖说明和跨平台注意事项。 + - 包含常见问题解答。 + + +### 3.4 icons模块 + + `icons/`目录包含应用程序使用的各种图标资源文件。 + +#### 3.4.1 图标文件 + + 1. `close_icon.png`: 关闭按钮图标 + 2. `delete_fail_icon.png`: 删除失败图标 + 3. `down_arrows.png`: 向下箭头图标 + 4. `left_arrows.png`: 向左箭头图标 + 5. `logo.png`: 应用程序Logo图标 + 6. `minimize_icon.png`: 最小化按钮图标 + 7. `move_tool.png`: 移动工具图标 + 8. `property_select_image.png`: 属性选择图像 + 9. `right_arrows.png`: 向右箭头图标 + 10. `rotate_tool.png`: 旋转工具图标 + 11. `scale_tool.png`: 缩放工具图标 + 12. `select_tool.png`: 选择工具图标 + 13. `solid_down_arrows.png`: 实心向下箭头图标 + 14. `solid_right_arrows.png`: 实心向右箭头图标 + 15. `success_icon.png`: 成功图标 + 16. `up_arrows.png`: 向上箭头图标 + 17. `warning_icon.png`: 警告图标 + 18. `windowing_icon.png`: 窗口化图标 + +### 3.5 tex模块 + + `tex/`目录包含基础纹理资源文件。 + +#### 3.5.1 纹理文件 + + 1. `empty_basecolor.png`: 空白基础颜色纹理 + 2. `empty_normal.png`: 空白法线纹理 + 3. `empty_roughness.png`: 空白粗糙度纹理 + 4. `empty_specular.png`: 空白镜面反射纹理 + + 这些纹理通常用作默认或占位纹理,在材质系统中作为基础资源。 + +### 3.6 vr_actions模块 + + `vr_actions/`目录包含VR动作系统配置文件。 + +#### 3.6.1 核心文件 + + 1. `actions.json`: + - VR动作定义文件,定义了VR系统中所有可用的动作。 + - 包括姿态、触发器、握把、菜单、系统按钮、触摸板、操纵杆等动作。 + - 定义了动作集和默认绑定关系,支持多语言本地化。 + + 2. `bindings_index.json`: + - Valve Index控制器绑定配置文件。 + - 定义了Index控制器的按钮、操纵杆、触摸板等输入的映射关系。 + + 3. `bindings_oculus.json`: + - Oculus Touch控制器绑定配置文件。 + - 定义了Oculus Touch控制器的按钮、扳机、操纵杆等输入的映射关系。 + + 4. `bindings_vive.json`: + - HTC Vive控制器绑定配置文件。 + - 定义了Vive控制器的按钮、触控板等输入的映射关系。