From 11ad2d57429605b4889a969426bd1d65101ed504 Mon Sep 17 00:00:00 2001 From: ayuan9957 <107920784+ayuan9957@users.noreply.github.com> Date: Sun, 15 Mar 2026 17:23:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E7=90=86qt=E5=92=8C=E6=97=A7=E7=89=88?= =?UTF-8?q?gizmo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Command_System.py | 44 ++------ core/editor_context.py | 10 +- core/event_handler.py | 141 +---------------------- core/selection.py | 172 +++++++---------------------- core/terrain_manager.py | 40 +------ main.py | 6 - scene/scene_manager_model_mixin.py | 33 +----- ui/panels/runtime_actions.py | 8 +- ui/panels/script_panels.py | 2 +- 9 files changed, 70 insertions(+), 386 deletions(-) diff --git a/core/Command_System.py b/core/Command_System.py index ddc31d99..c5b800ff 100644 --- a/core/Command_System.py +++ b/core/Command_System.py @@ -787,20 +787,18 @@ class AttachNodeCommand(Command): self.execute() -class ReparentNodeCommand(Command): - """ - 重新设置节点父子关系命令 - 增强版(同时处理Panda3D和Qt树) - """ +class ReparentNodeCommand(Command): + """ + 重新设置节点父子关系命令。 + """ - def __init__(self, node: NodePath, old_parent: NodePath, new_parent: NodePath, - old_parent_item=None, new_parent_item=None, is_2d_gui=False, world=None): - self.node = node - self.old_parent = old_parent - self.new_parent = new_parent - self.old_parent_item = old_parent_item # Qt树中的旧父节点项 - self.new_parent_item = new_parent_item # Qt树中的新父节点项 - self.is_2d_gui = is_2d_gui - self.world = world + def __init__(self, node: NodePath, old_parent: NodePath, new_parent: NodePath, + is_2d_gui=False, world=None): + self.node = node + self.old_parent = old_parent + self.new_parent = new_parent + self.is_2d_gui = is_2d_gui + self.world = world # 保存节点在操作前的世界坐标和局部坐标,以便在撤销/重做时保持位置不变 self.world_pos = node.getPos(self.world.render if self.world else node.getParent()) @@ -811,26 +809,6 @@ class ReparentNodeCommand(Command): self.local_hpr = node.getHpr() self.local_scale = node.getScale() - def _updateQtTree(self, node_item, new_parent_item): - """更新Qt树控件中的节点位置""" - if not node_item or not new_parent_item: - return - - # 从当前父节点中移除 - current_parent = node_item.parent() - if current_parent: - current_parent.removeChild(node_item) - else: - # 如果是顶级项目 - tree_widget = node_item.treeWidget() - if tree_widget: - index = tree_widget.indexOfTopLevelItem(node_item) - if index >= 0: - tree_widget.takeTopLevelItem(index) - - # 添加到新父节点 - new_parent_item.addChild(node_item) - def execute(self): """ 执行重新父化操作 diff --git a/core/editor_context.py b/core/editor_context.py index 58466884..e79bb8bd 100644 --- a/core/editor_context.py +++ b/core/editor_context.py @@ -1,4 +1,4 @@ -"""Editor context adapter for legacy bridge access.""" +"""Editor context adapter for the ImGui editor runtime.""" class EditorContext: @@ -7,14 +7,8 @@ class EditorContext: def __init__(self, world): self.world = world - def get_interface_manager(self): - return getattr(self.world, "interface_manager", None) - def get_tree_widget(self): - interface_manager = self.get_interface_manager() - if not interface_manager: - return None - return getattr(interface_manager, "treeWidget", None) + return None def get_gui_manager(self): return getattr(self.world, "gui_manager", None) diff --git a/core/event_handler.py b/core/event_handler.py index b3abb5ad..f75b7ca4 100644 --- a/core/event_handler.py +++ b/core/event_handler.py @@ -22,12 +22,8 @@ class EventHandler: self._editor_context = get_editor_context(self.world) return self._editor_context - def _get_interface_manager(self): - """获取兼容层中的场景树管理器(若存在)。""" - return self._get_editor_context().get_interface_manager() - def _get_tree_widget(self): - """安全获取场景树控件。""" + """Qt tree has been removed in the ImGui editor.""" return self._get_editor_context().get_tree_widget() def _get_gui_manager(self): @@ -35,29 +31,7 @@ class EventHandler: return self._get_editor_context().get_gui_manager() def _sync_tree_selection(self, selected_model): - """将当前选中模型同步到场景树。""" - interface_manager = self._get_interface_manager() - tree_widget = self._get_tree_widget() - if not interface_manager or not tree_widget: - return False - - root = tree_widget.invisibleRootItem() - found_item = None - - for i in range(root.childCount()): - scene_item = root.child(i) - if scene_item.text(0) != "场景": - continue - found_item = interface_manager.findTreeItem(selected_model, scene_item) - if found_item: - try: - tree_widget.itemClicked.disconnect() - except TypeError: - pass - tree_widget.setCurrentItem(found_item) - tree_widget.itemClicked.connect(interface_manager.onTreeItemClicked) - return True - break + """Scene tree selection is rendered directly from editor state in ImGui.""" return False def showClickRay(self, nearPoint, farPoint, hitPos=None): @@ -236,73 +210,10 @@ class EventHandler: pickerNP.removeNode() return - # 优先检查是否点击了坐标轴 - #print(f"检查坐标轴点击: 坐标轴存在={bool(self.world.selection.gizmo)}") - if self.world.selection.hasLegacyGizmoInput(): - #print("准备检查坐标轴点击...") - try: - highlighted_axis = self.world.selection.gizmoHighlightAxis - if highlighted_axis: - print(f"✓ 检测到高亮轴: {highlighted_axis},直接开始拖拽") - # 直接使用高亮轴开始拖拽 - self.world.selection.startGizmoDrag(highlighted_axis, x, y) - pickerNP.removeNode() - return - - # 如果没有高亮轴,再尝试检测点击 - gizmoAxis = self.world.selection.checkGizmoClick(x, y) - if gizmoAxis: - print(f"✓ 检测到坐标轴点击: {gizmoAxis}") - # 开始坐标轴拖拽 - self.world.selection.startGizmoDrag(gizmoAxis, x, y) - pickerNP.removeNode() - return - else: - print("× 没有点击到坐标轴") - - # gizmoAxis = self.world.selection.checkGizmoClick(x, y) - # if gizmoAxis: - # #print(f"✓ 检测到坐标轴点击: {gizmoAxis}") - # # 开始坐标轴拖拽 - # self.world.selection.startGizmoDrag(gizmoAxis, x, y) - # pickerNP.removeNode() - # return - # else: - # print("× 没有点击到坐标轴") - except Exception as e: - print(f"❌ 坐标轴点击检测出现异常: {str(e)}") - import traceback - traceback.print_exc() - print("继续处理模型选择...") - - #print("继续处理碰撞结果...") - if hitPos and hitNode: #print(f"✓ 检测到碰撞,开始处理点击事件") - #print(f"GUI编辑模式: {self.world.guiEditMode}") #print(f"当前工具: {self.world.currentTool}") - # 处理GUI编辑模式 - if self.world.guiEditMode: - gui_manager = self._get_gui_manager() - if not gui_manager: - print("GUI编辑模式已开启,但 gui_manager 不可用") - pickerNP.removeNode() - return - #print("处理GUI编辑模式点击") - # 检查是否点击了GUI元素 - clickedGUI = gui_manager.findClickedGUI(hitNode) - if clickedGUI: - # 选中GUI元素 - self.world.selection.updateSelection(clickedGUI) - gui_manager.selectGUIInTree(clickedGUI) - print(f"选中GUI元素: {clickedGUI.getTag('gui_text')}") - elif hasattr(self.world, 'currentGUITool') and self.world.currentGUITool: - # 在点击位置创建新GUI元素 - gui_manager.createGUIAtPosition(hitPos, self.world.currentGUITool) - pickerNP.removeNode() - return - # 根据当前工具处理点击事件 if self.world.currentTool in ("选择", "移动", "旋转", "缩放"): print("✓ 使用选择工具处理点击") @@ -317,22 +228,7 @@ class EventHandler: print(f"当前工具不是'选择',无法处理: {self.world.currentTool}") else: print("没有检测到碰撞") - - # 如果不在GUI编辑模式,清除选择 - if not self.world.guiEditMode: - self.world.selection.updateSelection(None) - - # 在GUI编辑模式下,即使没有碰撞也可以在空白区域创建GUI - if (self.world.guiEditMode and - hasattr(self.world, 'currentGUITool') and - self.world.currentGUITool): - # 使用默认的地面高度创建GUI - default_height = 0.0 - world_pos = Point3(mx * 10, 0, my * 10) # 简单的屏幕到世界坐标转换 - world_pos.setZ(default_height) - gui_manager = self._get_gui_manager() - if gui_manager: - gui_manager.createGUIAtPosition(world_pos, self.world.currentGUITool) + self.world.selection.updateSelection(None) # 确保总是清理碰撞检测节点 try: @@ -552,10 +448,7 @@ class EventHandler: def mouseReleaseEventLeft(self, evt): """处理鼠标左键释放事件""" - # 处理坐标轴拖拽结束 - if self.world.selection.isLegacyGizmoDragActive(): - self.world.selection.stopGizmoDrag() - return + return def wheelForward(self, data=None): """处理滚轮向前滚动(前进)""" @@ -597,30 +490,6 @@ class EventHandler: """处理鼠标移动事件""" if not evt: return - - # 处理坐标轴拖拽 - if self.world.selection.isLegacyGizmoDragActive(): - x = evt.get('x', 0) - y = evt.get('y', 0) - - # 获取准确的窗口尺寸 - winWidth, winHeight = self.world.getWindowSize() - - # 将屏幕坐标转换为世界坐标 - mx = 2.0 * x / float(winWidth) - 1.0 - my = 1.0 - 2.0 * y / float(winHeight) - - # 更新坐标轴拖拽 - self.world.selection.updateGizmoDrag(x, y) - return - - # 更新坐标轴高亮(鼠标悬停效果) - if self.world.selection.hasLegacyGizmoInput() and not self.world.selection.isLegacyGizmoDragActive(): - x = evt.get('x', 0) - y = evt.get('y', 0) - # 减少高亮调试输出,只在需要时输出 - # 已静默处理,避免控制台刷屏 - self.world.selection.updateGizmoHighlight(x, y) - + # 调用CoreWorld的父类方法处理基础的相机旋转 super(type(self.world), self.world).mouseMoveEvent(evt) diff --git a/core/selection.py b/core/selection.py index 3587b3bd..d2fd78b4 100644 --- a/core/selection.py +++ b/core/selection.py @@ -177,26 +177,11 @@ class SelectionSystem: return self.gizmoTarget == nodePath def _has_legacy_gizmo_input(self): - """Return whether legacy gizmo hit-testing/dragging is active.""" - if self._has_new_transform_gizmo(): - return False - if not self.gizmo or not self.gizmoTarget: - return False - try: - return not self.gizmo.isEmpty() and not self.gizmoTarget.isEmpty() - except Exception: - return False - - def hasLegacyGizmoInput(self): - """Compatibility helper for event routing.""" - return self._has_legacy_gizmo_input() - - def isLegacyGizmoDragActive(self): - """Return whether the legacy gizmo drag loop should keep consuming mouse input.""" - return self.isDraggingGizmo and self._has_legacy_gizmo_input() + """Legacy gizmo path is retired.""" + return False def _get_effective_selected_node(self): - """Resolve the current editor selection across legacy and SSBO selection sources.""" + """Resolve the current editor selection across scene and SSBO sources.""" ssbo_editor = getattr(self.world, "ssbo_editor", None) if ssbo_editor and hasattr(ssbo_editor, "has_active_selection"): try: @@ -511,91 +496,19 @@ class SelectionSystem: # ==================== 坐标轴(Gizmo)系统 ==================== def createGizmo(self, nodePath): - """为选中的节点创建坐标轴工具 - 保留箭头版本""" - if self._has_new_transform_gizmo(): - self.gizmo = None - self.gizmoTarget = nodePath - if not nodePath: - return - self.sync_transform_gizmo_mode() - try: - self.world.newTransform.attach(nodePath) - except Exception as e: - print(f"attach TransformGizmo failed: {e}") + """Attach the unified TransformGizmo to the selected node.""" + self.gizmo = None + self.gizmoTarget = nodePath + if not nodePath or not self._has_new_transform_gizmo(): return + self.sync_transform_gizmo_mode() try: - #print(f" 开始创建坐标轴,目标节点: {nodePath.getName()}") - - # 如果已有坐标轴,先移除 - if self.gizmo: - self.gizmo.removeNode() - self.gizmo = None - taskMgr.remove("updateGizmo") - - if not nodePath: - return - - # 创建坐标轴主节点 - self.gizmo = self.world.render.attachNewNode("gizmo") - self.gizmoTarget = nodePath - - # 添加标识标签,便于识别 - self.gizmo.setTag("is_gizmo", "1") - if hasattr(nodePath, 'getName'): - self.gizmo.setTag("gizmo_target", nodePath.getName()) - - # 为各轴添加标签 - if hasattr(self, 'gizmoXAxis') and self.gizmoXAxis: - self.gizmoXAxis.setTag("is_gizmo", "1") - self.gizmoXAxis.setTag("gizmo_axis", "x") - if hasattr(self, 'gizmoYAxis') and self.gizmoYAxis: - self.gizmoYAxis.setTag("is_gizmo", "1") - self.gizmoYAxis.setTag("gizmo_axis", "y") - if hasattr(self, 'gizmoZAxis') and self.gizmoZAxis: - self.gizmoZAxis.setTag("is_gizmo", "1") - self.gizmoZAxis.setTag("gizmo_axis", "z") - - # 设置位置和朝向 - minPoint = Point3() - maxPoint = Point3() - if nodePath.calcTightBounds(minPoint, maxPoint, self.world.render): - center = Point3((minPoint.x + maxPoint.x) * 0.5, - (minPoint.y + maxPoint.y) * 0.5, - (minPoint.z + maxPoint.z) * 0.5) - self.gizmo.setPos(center) - - parent_node = nodePath.getParent() - if parent_node and parent_node != self.world.render: - self.gizmo.setHpr(parent_node.getHpr()) - else: - self.gizmo.setHpr(0, 0, 0) - - # 只调用一次几何体创建 - self.createGizmoGeometry() - - #只调用一次颜色设置 - self.setGizmoAxisColor("x", self.gizmo_colors["x"]) - self.setGizmoAxisColor("y", self.gizmo_colors["y"]) - self.setGizmoAxisColor("z", self.gizmo_colors["z"]) - - self._updateGizmoScreenSize() - - self._setupGizmoRendering() - - self.setupGizmoCollision() - - # 现在才显示坐标轴 - self.gizmo.show() - - # 只启动一次更新任务 - taskMgr.add(self.updateGizmoTask, "updateGizmo") - - #print(f" ✓ 为节点 {nodePath.getName()} 创建了坐标轴") - + self.world.newTransform.attach(nodePath) except Exception as e: - print(f"创建坐标轴失败: {str(e)}") + print(f"attach TransformGizmo failed: {e}") def createGizmoGeometry(self): """创建坐标轴的几何体""" + return from panda3d.core import Material try: if not self.gizmo: @@ -734,6 +647,7 @@ class SelectionSystem: print(f"创建坐标轴几何体失败: {str(e)}") def _setupGizmoRendering(self): + return try: axis_nodes = [self.gizmoXAxis,self.gizmoYAxis,self.gizmoZAxis] axis_Rotnodes = [self.gizmoRotXAxis, self.gizmoRotYAxis, self.gizmoRotZAxis] @@ -824,6 +738,7 @@ class SelectionSystem: def updateGizmoTask(self, task): """坐标轴更新任务 - 包含固定大小功能""" + return task.done try: # 限制更新频率 if not hasattr(self, '_last_gizmo_update'): @@ -1007,26 +922,9 @@ class SelectionSystem: self.world.newTransform.detach() except Exception as e: print(f"detach TransformGizmo failed: {e}") - self.gizmo = None - self.gizmoTarget = None - self.gizmoXAxis = None - self.gizmoYAxis = None - self.gizmoZAxis = None - self.isDraggingGizmo = False - self.dragGizmoAxis = None - self.dragStartMousePos = None - self.gizmoTargetStartPos = None - self.gizmoStartPos = None - self._resetCursor() - return - - if self.gizmo: - self.gizmo.removeNode() - self.gizmo = None - - taskMgr.remove("updateGizmo") self.gizmoTarget = None + self.gizmo = None self.gizmoXAxis = None self.gizmoYAxis = None self.gizmoZAxis = None @@ -1041,6 +939,7 @@ class SelectionSystem: # """设置坐标轴颜色 - RenderPipeline 兼容版本""" def setGizmoRotAxisColor(self, axis, color): """使用材质设置坐标轴颜色 - RenderPipeline兼容版本""" + return try: from panda3d.core import Material, Vec4,ColorWriteAttrib,DepthWriteAttrib,DepthTestAttrib,TransparencyAttrib @@ -1135,6 +1034,7 @@ class SelectionSystem: def setGizmoAxisColor(self, axis, color): """使用材质设置坐标轴颜色 - RenderPipeline兼容版本""" + return try: from panda3d.core import Material, Vec4,ColorWriteAttrib,DepthWriteAttrib,DepthTestAttrib,TransparencyAttrib @@ -1308,6 +1208,7 @@ class SelectionSystem: def checkGizmoClick(self, mouseX, mouseY): """使用屏幕空间检测是否点击了坐标轴""" + return None if not self._has_legacy_gizmo_input(): return None @@ -1402,6 +1303,7 @@ class SelectionSystem: def checkGizmoClickFallback(self, mouseX, mouseY): """备用检测方法:使用固定的屏幕区域""" + return None # 获取准确的窗口尺寸 win_width, win_height = self.world.getWindowSize() @@ -1585,6 +1487,9 @@ class SelectionSystem: def updateGizmoHighlight(self, mouseX, mouseY): """更新坐标轴高亮状态""" + self.gizmoHighlightAxis = None + self._resetCursor() + return if not self._has_legacy_gizmo_input() or self.isDraggingGizmo: self._resetCursor() return @@ -1644,6 +1549,7 @@ class SelectionSystem: def startGizmoDrag(self, axis, mouseX, mouseY): """开始坐标轴拖拽""" + return try: if not self._has_legacy_gizmo_input(): return @@ -1968,6 +1874,7 @@ class SelectionSystem: def updateGizmoDrag(self, mouseX, mouseY): """更新坐标轴拖拽 - 使用正确的坐标系变换,支持旋转后的子节点拖拽""" + return try: if not self._validate_gizmo_drag_state(): return @@ -2018,6 +1925,16 @@ class SelectionSystem: def stopGizmoDrag(self): """停止坐标轴拖拽并创建撤销命令""" + self.isDraggingGizmo = False + self.dragGizmoAxis = None + self.dragStartMousePos = None + self.gizmoTargetStartPos = None + self.gizmoTargetStartScale = None + self.gizmoTargetStartHpr = None + self.gizmoStartPos = None + self.gizmoHighlightAxis = None + self._resetCursor() + return if not self.isDraggingGizmo: return @@ -2119,6 +2036,7 @@ class SelectionSystem: def _dragUpdateTask(self, task): """拖拽更新任务 - 持续更新拖拽状态""" + return task.done try: if not self.isDraggingGizmo: return task.done @@ -2232,24 +2150,6 @@ class SelectionSystem: import traceback traceback.print_exc() - def _reparentTreeItem(self, item, new_parent_item): - """将树项重新父化到新的父项下""" - if not item or not new_parent_item: - return - - # 从当前父项中移除 - current_parent = item.parent() - if current_parent: - current_parent.removeChild(item) - else: - # 如果是顶级项 - index = self.indexOfTopLevelItem(item) - if index >= 0: - self.takeTopLevelItem(index) - - # 添加到新父项 - new_parent_item.addChild(item) - # def _updateSelectionVisuals(self, nodePath): # """更新选择的视觉效果(选择框和坐标轴)""" # try: @@ -2344,6 +2244,7 @@ class SelectionSystem: self._updateSelectionOutline(None) def setupGizmoCollision(self): + return if not self.gizmo or not self.gizmoXAxis or not self.gizmoYAxis or not self.gizmoZAxis: return @@ -2362,6 +2263,7 @@ class SelectionSystem: self.createAxisCollision("z", self.gizmoZAxis) def createAxisCollision(self, axis_name, axis_node): + return # 为单个轴创建碰撞体 try: handle_node = axis_node.find(f"{axis_name}_handle") @@ -2422,6 +2324,7 @@ class SelectionSystem: traceback.print_exc() def detectGizmoAxisWithCollision(self, mouseX, mouseY): + return None # 使用碰撞体检测鼠标是否悬停在坐标轴上 if not self.gizmo: return None @@ -2489,6 +2392,7 @@ class SelectionSystem: return None def debugGizmoCollision(self): + return print("===碰撞体调试信息===") for axis_name in ["x","y","z"]: axis_node = getattr(self,f"gizmo{axis_name.upper()}Axis") diff --git a/core/terrain_manager.py b/core/terrain_manager.py index 254ce53b..e12ba100 100644 --- a/core/terrain_manager.py +++ b/core/terrain_manager.py @@ -144,16 +144,7 @@ class TerrainManager: parent_name = parent_item.text(0) if parent_item else "root" print(f"✅ 为 {parent_name} 创建高度图地形: {terrain_name}") - # 在Qt树形控件中添加对应节点 - qt_item = None - if tree_widget and parent_item: - qt_item = tree_widget.add_node_to_tree_widget(terrain_node, parent_item, "TERRAIN_NODE") - - if qt_item: - created_terrains.append((terrain_node, qt_item)) - else: - created_terrains.append((terrain_node, None)) - print("⚠️ Qt树节点添加跳过或失败,但Panda3D对象已创建") + created_terrains.append((terrain_node, None)) # 添加到场景管理器(ImGui环境使用) if hasattr(self.world, 'scene_manager') and self.world.scene_manager: @@ -176,13 +167,8 @@ class TerrainManager: print("❌ 没有成功创建任何高度图地形") return None - # 选中最后创建的光源 - if created_terrains: - last_light_np, last_qt_item = created_terrains[-1] - if last_qt_item: - tree_widget.setCurrentItem(last_qt_item) - # 更新选择和属性面板 - tree_widget.update_selection_and_properties(last_light_np, last_qt_item) + if created_terrains: + pass print(f"🎉 总共创建了 {len(created_terrains)} 个高度图地形") @@ -294,16 +280,7 @@ class TerrainManager: parent_name = parent_item.text(0) if parent_item else "root" print(f"✅ 为 {parent_name} 创建平面地形: {terrain_name}") - # 在Qt树形控件中添加对应节点 - qt_item = None - if tree_widget and parent_item: - qt_item = tree_widget.add_node_to_tree_widget(terrain_node, parent_item, "TERRAIN_NODE") - - if qt_item: - created_terrains.append((terrain_node, qt_item)) - else: - created_terrains.append((terrain_node, None)) - print("⚠️ Qt树节点添加跳过或失败,但Panda3D对象已创建") + created_terrains.append((terrain_node, None)) # 添加到场景管理器(ImGui环境使用) if hasattr(self.world, 'scene_manager') and self.world.scene_manager: @@ -326,13 +303,8 @@ class TerrainManager: print("❌ 没有成功创建任何平面地形") return None - # 选中最后创建的光源 - if created_terrains: - last_light_np, last_qt_item = created_terrains[-1] - if last_qt_item: - tree_widget.setCurrentItem(last_qt_item) - # 更新选择和属性面板 - tree_widget.update_selection_and_properties(last_light_np, last_qt_item) + if created_terrains: + pass print(f"🎉 总共创建了 {len(created_terrains)} 个平面地形") diff --git a/main.py b/main.py index 8eef26e7..f5c38661 100644 --- a/main.py +++ b/main.py @@ -138,12 +138,7 @@ class MyWorld(PanelDelegates, CoreWorld): self.taskMgr.doMethodLater(0.05, self._sync_window_metrics_task, "window-metrics-sync") print(f"✓ 窗口初始化完成: {self.win.getXSize()} x {self.win.getYSize()}") - # Legacy compatibility fields used by scene/project modules. self.gui_elements = [] - self.gui_manager = None - self.interface_manager = None - self.guiEditMode = False - self.currentGUITool = None # 初始化选择和变换系统 self.selection = SelectionSystem(self) @@ -193,7 +188,6 @@ class MyWorld(PanelDelegates, CoreWorld): self.project_manager = ProjectManager(self) # print(f"[DEBUG] 项目管理系统初始化完成") - # Legacy manager removed in ImGui migration; keep attribute for compatibility. self.info_panel_manager = None self.command_manager = CommandManager() diff --git a/scene/scene_manager_model_mixin.py b/scene/scene_manager_model_mixin.py index 70ba4808..59baf7c4 100644 --- a/scene/scene_manager_model_mixin.py +++ b/scene/scene_manager_model_mixin.py @@ -17,7 +17,6 @@ from panda3d.core import ( from panda3d.egg import EggData, EggVertexPool from RenderPipelineFile.rpplugins.smaa.jitters import halton_seq from scene import util -from scene.tree_roles import TREE_USER_ROLE from core.editor_context import get_editor_context class SceneManagerModelMixin: @@ -164,30 +163,7 @@ class SceneManagerModelMixin: # 添加到模型列表 self.models.append(model) - # 更新场景树 - # 获取树形控件并添加到Qt树中 - tree_widget = self._get_tree_widget() - if tree_widget: - # 找到根节点项 - root_item = None - for i in range(tree_widget.topLevelItemCount()): - item = tree_widget.topLevelItem(i) - if item.text(0) == "render" or item.data(0, TREE_USER_ROLE) == self.world.render: - root_item = item - break - - if root_item: - qt_item = tree_widget.add_node_to_tree_widget(model, root_item, "IMPORTED_MODEL_NODE") - if qt_item: - #tree_widget.setCurrentItem(qt_item) - # 更新选择和属性面板 - #tree_widget.update_selection_and_properties(model, qt_item) - print("✅ Qt树节点添加成功") - else: - print("⚠️ Qt树节点添加失败,但Panda3D对象已创建") - else: - print("⚠️ 未找到根节点项,无法添加到Qt树") - #self.updateSceneTree() + # ImGui scene tree is rendered directly from scene state. print(f"=== 模型导入成功: {model_name} ===\n") return model @@ -847,11 +823,8 @@ class SceneManagerModelMixin: print(f"刷新碰撞框失败: {e}") def updateSceneTree(self): - """更新场景树显示 - 代理到interface_manager""" - interface_manager = get_editor_context(self.world).get_interface_manager() - if interface_manager and hasattr(interface_manager, "updateSceneTree"): - return interface_manager.updateSceneTree() - print("界面管理器未初始化,无法更新场景树") + """ImGui scene tree renders directly from scene state; no explicit refresh hook needed.""" + return True def _get_script_file_path(self, script_class, script_name): """ diff --git a/ui/panels/runtime_actions.py b/ui/panels/runtime_actions.py index 0459a0df..5fa9e434 100644 --- a/ui/panels/runtime_actions.py +++ b/ui/panels/runtime_actions.py @@ -49,7 +49,7 @@ class RuntimeActions: return None def _create_simple_gui_button(self, pos=(0, 0, 0), text="按钮", size=0.1): - """创建简单的GUI按钮,不依赖QT树形控件""" + """创建简单的GUI按钮。""" try: from direct.gui.DirectGui import DirectButton @@ -178,7 +178,7 @@ class RuntimeActions: return None def _create_simple_gui_label(self, pos=(0, 0, 0), text="标签", size=0.08): - """创建简单的GUI标签,不依赖QT树形控件""" + """创建简单的GUI标签。""" try: from direct.gui.DirectGui import DirectLabel @@ -225,7 +225,7 @@ class RuntimeActions: return None def _create_simple_gui_entry(self, pos=(0, 0, 0), placeholder="输入文本...", size=0.08): - """创建简单的GUI输入框,不依赖QT树形控件""" + """创建简单的GUI输入框。""" try: from direct.gui.DirectGui import DirectEntry @@ -274,7 +274,7 @@ class RuntimeActions: return None def _create_simple_gui_image(self, pos=(0, 0, 0), image_path=None, size=2): - """创建简单的GUI图片,不依赖QT树形控件""" + """创建简单的GUI图片。""" try: from direct.gui.DirectGui import DirectFrame from panda3d.core import Filename diff --git a/ui/panels/script_panels.py b/ui/panels/script_panels.py index 433b4667..68710ad1 100644 --- a/ui/panels/script_panels.py +++ b/ui/panels/script_panels.py @@ -104,7 +104,7 @@ class ScriptPanels: def _draw_script_panel(self): - """绘制脚本管理面板(与Qt版本功能一致)""" + """绘制脚本管理面板。""" # 使用面板类型的窗口标志,支持docking flags = self.style_manager.get_window_flags("panel")