This commit is contained in:
Rowland 2026-01-26 15:25:33 +08:00
parent 058cfe454d
commit cbbbf065ac
2 changed files with 490 additions and 372 deletions

View File

@ -1855,13 +1855,71 @@ class SelectionSystem:
return False
def stopGizmoDrag(self):
"""停止坐标轴拖拽"""
"""停止坐标轴拖拽并创建撤销命令"""
print(f"停止坐标轴拖拽 - 轴: {self.dragGizmoAxis}")
# 移除拖拽更新任务
if hasattr(self.world, 'taskMgr') and self.world.taskMgr:
self.world.taskMgr.remove("gizmoDragUpdate")
# 创建撤销命令
if hasattr(self.world,'command_manager') and self.world.command_manager and self.gizmoTarget:
try:
# 检查是否是移动操作
if (hasattr(self,'gizmoTargetStartPos') and self.gizmoTargetStartPos):
current_pos = self.gizmoTarget.getPos()
if (abs(current_pos.x-self.gizmoTargetStartPos.x)>0.001 or
abs(current_pos.y-self.gizmoTargetStartPos.y)>0.001 or
abs(current_pos.z-self.gizmoTargetStartPos.z)>0.001):
from core.Command_System import MoveNodeCommand, MoveLightCommand
light_object = self.gizmoTarget.getPythonTag("rp_light_object")
if light_object:
command = MoveLightCommand(self.gizmoTarget,self.gizmoTargetStartPos,current_pos,light_object)
else:
command = MoveNodeCommand(self.gizmoTarget,self.gizmoTargetStartPos,current_pos)
self.world.command_manager.execute_command(command)
print(f"创建移动命令: {self.gizmoTargetStartPos} -> {current_pos}")
# 检查是否是缩放操作
if (hasattr(self, 'gizmoTargetStartScale') and self.gizmoTargetStartScale):
current_scale = self.gizmoTarget.getScale()
if (abs(current_scale.x - self.gizmoTargetStartScale.x) > 0.001 or
abs(current_scale.y - self.gizmoTargetStartScale.y) > 0.001 or
abs(current_scale.z - self.gizmoTargetStartScale.z) > 0.001):
from core.Command_System import ScaleNodeCommand
command = ScaleNodeCommand(self.gizmoTarget, self.gizmoTargetStartScale, current_scale)
self.world.command_manager.execute_command(command)
print(f"创建缩放命令: {self.gizmoTargetStartScale} -> {current_scale}")
# 检查是否是旋转操作
if (hasattr(self, 'gizmoTargetStartHpr') and self.gizmoTargetStartHpr):
current_hpr = self.gizmoTarget.getHpr()
if (abs(current_hpr.x - self.gizmoTargetStartHpr.x) > 0.001 or
abs(current_hpr.y - self.gizmoTargetStartHpr.y) > 0.001 or
abs(current_hpr.z - self.gizmoTargetStartHpr.z) > 0.001):
from core.Command_System import RotateNodeCommand
command = RotateNodeCommand(self.gizmoTarget, self.gizmoTargetStartHpr, current_hpr)
self.world.command_manager.execute_command(command)
print(f"创建旋转命令: {self.gizmoTargetStartHpr} -> {current_hpr}")
except Exception as e:
print(f"创建撤销命令时出错: {e}")
# 恢复所有轴的颜色
for axis_name in ["x", "y", "z"]:
self.setGizmoAxisColor(axis_name, self.gizmo_colors[axis_name])
# 重置拖拽状态
self.isDraggingGizmo = False
self.dragGizmoAxis = None
self.dragStartMousePos = None
# 清理拖拽状态,下次拖拽开始时重新设置
self.gizmoTargetStartPos = None
self.gizmoTargetStartScale = None
self.gizmoTargetStartHpr = None
self.gizmoStartPos = None
def _dragUpdateTask(self, task):
"""拖拽更新任务 - 持续更新拖拽状态"""
try:
@ -1889,55 +1947,6 @@ class SelectionSystem:
except Exception as e:
print(f"拖拽更新任务错误: {e}")
return task.done
if hasattr(self.world,'command_manager') and self.world.command_manager and self.gizmoTarget:
current_pos = self.gizmoTarget.getPos()
if (hasattr(self,'gizmoTargetStartPos') and self.gizmoTargetStartPos and
(abs(current_pos.x-self.gizmoTargetStartPos.x)>0.001 or
abs(current_pos.y-self.gizmoTargetStartPos.y)>0.001 or
abs(current_pos.z-self.gizmoTargetStartPos.z)>0.001)):
from core.Command_System import MoveNodeCommand
from core.Command_System import MoveLightCommand
light_object = self.gizmoTarget.getPythonTag("rp_light_object")
if light_object:
command = MoveLightCommand(self.gizmoTarget,self.gizmoTargetStartPos,current_pos,light_object)
else:
command = MoveNodeCommand(self.gizmoTarget,self.gizmoTargetStartPos,current_pos)
self.world.command_manager.execute_command(command)
# 如果是缩放操作且缩放发生了变化,则创建缩放命令
elif (hasattr(self, 'gizmoTargetStartScale') and hasattr(self, 'gizmoTargetStartScale') and
self.gizmoTargetStartScale):
current_scale = self.gizmoTarget.getScale()
if (abs(current_scale.x - self.gizmoTargetStartScale.x) > 0.001 or
abs(current_scale.y - self.gizmoTargetStartScale.y) > 0.001 or
abs(current_scale.z - self.gizmoTargetStartScale.z) > 0.001):
from core.Command_System import ScaleNodeCommand
command = ScaleNodeCommand(self.gizmoTarget, self.gizmoTargetStartScale, current_scale)
self.world.command_manager.execute_command(command)
# 如果是旋转操作且旋转发生了变化,则创建旋转命令
elif (hasattr(self, 'gizmoTargetStartHpr') and hasattr(self, 'gizmoTargetStartHpr') and
self.gizmoTargetStartHpr):
current_hpr = self.gizmoTarget.getHpr()
if (abs(current_hpr.x - self.gizmoTargetStartHpr.x) > 0.001 or
abs(current_hpr.y - self.gizmoTargetStartHpr.y) > 0.001 or
abs(current_hpr.z - self.gizmoTargetStartHpr.z) > 0.001):
from core.Command_System import RotateNodeCommand
command = RotateNodeCommand(self.gizmoTarget, self.gizmoTargetStartHpr, current_hpr)
self.world.command_manager.execute_command(command)
# 恢复所有轴的颜色
for axis_name in ["x", "y", "z"]:
self.setGizmoAxisColor(axis_name, self.gizmo_colors[axis_name])
self.isDraggingGizmo = False
self.dragGizmoAxis = None
self.dragStartMousePos = None
# 清理拖拽状态,下次拖拽开始时重新设置
self.gizmoTargetStartPos = None
self.gizmoStartPos = None
if hasattr(self, 'gizmoTargetStartScale'):
delattr(self, 'gizmoTargetStartScale')
if hasattr(self, 'gizmoTargetStartHpr'):

201
demo.py
View File

@ -181,6 +181,11 @@ class MyWorld(CoreWorld):
print(f"⚠ VR管理器初始化失败: {e}")
self.vr_manager = None
# VR调试相关变量
self.vr_debug_enabled = False
self.vr_detailed_mode = True
self.vr_performance_monitor = False
# 调试选项
self.debug_collision = True # 是否显示碰撞体
@ -395,11 +400,11 @@ class MyWorld(CoreWorld):
self.accept('f4', self._on_f4_pressed)
# 编辑功能快捷键
self.accept('z', self._on_z_pressed)
self.accept('y', self._on_y_pressed)
self.accept('x', self._on_x_pressed)
self.accept('c', self._on_c_pressed)
self.accept('v', self._on_v_pressed)
self.accept('control-z', self._on_undo)
self.accept('control-y', self._on_redo)
self.accept('control-x', self._on_cut)
self.accept('control-c', self._on_copy)
self.accept('control-v', self._on_paste)
self.accept('delete', self._on_delete_pressed)
# 滚轮事件
@ -831,6 +836,11 @@ class MyWorld(CoreWorld):
# 创建菜单
with imgui_ctx.begin_menu("创建") as create_menu:
if create_menu:
if imgui.menu_item("导入模型", "", False, True)[1]:
self._on_import_model()
imgui.separator()
if imgui.menu_item("空对象", "", False, True)[1]:
self._on_create_empty_object()
@ -928,11 +938,64 @@ class MyWorld(CoreWorld):
# 工具菜单
with imgui_ctx.begin_menu("工具") as tools_menu:
if tools_menu:
if imgui.menu_item("导入模型", "", False, True)[1]:
self._on_import_model()
imgui.menu_item("地形编辑器", "", False, True)
imgui.menu_item("材质编辑器", "", False, True)
imgui.menu_item("脚本编辑器", "", False, True)
# 工具切换选项
if imgui.menu_item("选择工具", "", False, True)[1]:
self.tool_manager.setCurrentTool("选择")
if imgui.menu_item("移动工具", "", False, True)[1]:
self.tool_manager.setCurrentTool("移动")
if imgui.menu_item("旋转工具", "", False, True)[1]:
self.tool_manager.setCurrentTool("旋转")
if imgui.menu_item("缩放工具", "", False, True)[1]:
self.tool_manager.setCurrentTool("缩放")
imgui.separator()
# 编辑工具
if imgui.menu_item("光照编辑", "", False, True)[1]:
self.tool_manager.setCurrentTool("光照编辑")
if imgui.menu_item("图形编辑", "", False, True)[1]:
self.tool_manager.setCurrentTool("图形编辑")
imgui.separator()
# VR子菜单
with imgui_ctx.begin_menu("VR") as vr_menu:
if vr_menu:
if imgui.menu_item("进入VR模式", "", False, True)[1]:
self._toggle_vr_mode()
if imgui.menu_item("退出VR模式", "", False, True)[1]:
self._exit_vr_mode()
imgui.separator()
if imgui.menu_item("VR状态", "", False, True)[1]:
self._show_vr_status()
if imgui.menu_item("VR设置", "", False, True)[1]:
self._show_vr_settings()
imgui.separator()
# VR调试子菜单
with imgui_ctx.begin_menu("VR调试") as vr_debug_menu:
if vr_debug_menu:
_, self.vr_debug_enabled = imgui.menu_item("启用调试输出", "", self.vr_debug_enabled, True)
if imgui.menu_item("立即显示性能报告", "", False, True)[1]:
self._show_vr_performance_report()
imgui.separator()
# 输出模式
with imgui_ctx.begin_menu("输出模式") as output_menu:
if output_menu:
if imgui.menu_item("简短模式", "", not self.vr_detailed_mode, True)[1]:
self.vr_detailed_mode = False
if imgui.menu_item("详细模式", "", self.vr_detailed_mode, True)[1]:
self.vr_detailed_mode = True
imgui.separator()
_, self.vr_performance_monitor = imgui.menu_item("启用性能监控", "", self.vr_performance_monitor, True)
# 窗口菜单 - 已隐藏
# with imgui_ctx.begin_menu("窗口") as window_menu:
@ -4978,30 +5041,7 @@ class MyWorld(CoreWorld):
if self.alt_pressed:
self._on_exit()
def _on_z_pressed(self):
"""Z键按下 - 检查Ctrl+Z组合键撤销"""
if self.ctrl_pressed:
self._on_undo()
def _on_y_pressed(self):
"""Y键按下 - 检查Ctrl+Y组合键重做"""
if self.ctrl_pressed:
self._on_redo()
def _on_x_pressed(self):
"""X键按下 - 检查Ctrl+X组合键剪切"""
if self.ctrl_pressed:
self._on_cut()
def _on_c_pressed(self):
"""C键按下 - 检查Ctrl+C组合键复制"""
if self.ctrl_pressed:
self._on_copy()
def _on_v_pressed(self):
"""V键按下 - 检查Ctrl+V组合键粘贴"""
if self.ctrl_pressed:
self._on_paste()
# 移除了单独的按键处理方法,现在直接使用组合键事件
def _on_delete_pressed(self):
"""Delete键按下 - 删除选中节点"""
@ -5309,12 +5349,37 @@ class MyWorld(CoreWorld):
self.add_error_message(f"删除操作失败: {e}")
def _delete_node(self, node):
"""删除节点的通用方法"""
"""删除节点的通用方法 - 使用命令系统"""
try:
if not node or node.isEmpty():
return False
node_name = node.getName() or "未命名节点"
parent = node.getParent()
# 创建删除命令
if hasattr(self, 'command_manager') and self.command_manager:
from core.Command_System import DeleteNodeCommand
command = DeleteNodeCommand(node, parent, self)
self.command_manager.execute_command(command)
print(f"[命令系统] 创建删除命令: {node_name}")
else:
# 备用方案:直接删除并执行清理
print(f"[删除] 命令管理器不可用,直接删除节点: {node_name}")
self._perform_node_cleanup(node)
node.removeNode()
print(f"[删除] 成功删除节点: {node_name}")
return True
except Exception as e:
print(f"[删除] 删除节点失败: {e}")
return False
def _perform_node_cleanup(self, node):
"""执行节点清理逻辑"""
try:
node_name = node.getName() or "未命名节点"
# 从场景管理器的模型列表中移除(如果是模型)
if hasattr(self, 'scene_manager') and self.scene_manager:
@ -5356,15 +5421,8 @@ class MyWorld(CoreWorld):
finally:
del self._actor_cache[node]
# 从父节点中移除
node.removeNode()
print(f"[删除] 成功删除节点: {node_name}")
return True
except Exception as e:
print(f"[删除] 删除节点失败: {e}")
return False
print(f"[清理] 节点清理失败: {e}")
# ==================== 对话框绘制函数 ====================
@ -7302,8 +7360,8 @@ class MyWorld(CoreWorld):
imgui.end_popup()
def _delete_node(self, node):
"""删除节点"""
def _delete_node_simple(self, node):
"""删除节点 - 简化版本"""
if not node or node.isEmpty():
return
@ -7321,6 +7379,9 @@ class MyWorld(CoreWorld):
if gui_element in self.gui_manager.gui_elements:
self.gui_manager.gui_elements.remove(gui_element)
# 使用主删除方法
self._delete_node(node)
# 获取节点名称(在删除之前)
node_name = node.getName() if not node.isEmpty() else '未命名节点'
@ -7958,7 +8019,55 @@ class MyWorld(CoreWorld):
"""GUI按钮点击事件处理"""
print("GUI按钮被点击了")
def _get_chinese_font(self):
def _toggle_vr_mode(self):
"""切换VR模式"""
if self.vr_manager:
if self.vr_manager.is_enabled():
self._exit_vr_mode()
else:
self.vr_manager.enable()
self.add_info_message("已进入VR模式")
else:
self.add_error_message("VR管理器未初始化")
def _exit_vr_mode(self):
"""退出VR模式"""
if self.vr_manager:
self.vr_manager.disable()
self.add_info_message("已退出VR模式")
def _show_vr_status(self):
"""显示VR状态"""
if self.vr_manager:
status = "已启用" if self.vr_manager.is_enabled() else "未启用"
self.add_info_message(f"VR状态: {status}")
# 显示设备信息
if self.vr_manager.is_enabled():
devices = self.vr_manager.get_connected_devices()
if devices:
self.add_info_message(f"连接的设备: {', '.join(devices)}")
else:
self.add_info_message("未检测到VR设备")
else:
self.add_error_message("VR管理器未初始化")
def _show_vr_settings(self):
"""显示VR设置"""
if self.vr_manager:
self.add_info_message("VR设置对话框待实现")
else:
self.add_error_message("VR管理器未初始化")
def _show_vr_performance_report(self):
"""显示VR性能报告"""
if self.vr_manager and self.vr_manager.is_enabled():
report = self.vr_manager.get_performance_report()
self.add_info_message(f"VR性能报告: {report}")
else:
self.add_info_message("VR未启用或管理器未初始化")
def _get_chinese_font(self):
"""获取中文字体"""
try:
from panda3d.core import TextNode