import warnings from core.Command_System import CommandManager from core.InfoPanelManager import InfoPanelManager from core.patrol_system import PatrolSystem from demo.video_integration import VideoManager warnings.filterwarnings("ignore", category=DeprecationWarning) import sys import builtins from PyQt5.QtWidgets import (QApplication, QMainWindow, QMenuBar, QMenu, QAction, QDockWidget, QTreeWidget, QListWidget, QWidget, QVBoxLayout, QTreeWidgetItem, QLabel, QLineEdit, QFormLayout, QDoubleSpinBox, QScrollArea, QTreeView, QInputDialog, QFileDialog, QMessageBox, QDialog, QGroupBox, QHBoxLayout, QPushButton, QDialogButtonBox) from PyQt5.QtCore import Qt, QDir, QUrl from PyQt5.QtGui import QDrag, QPainter, QPixmap from PyQt5.QtWidgets import QFileSystemModel from QMeta3D.QMeta3DWidget import QMeta3DWidget from panda3d.core import loadPrcFileData loadPrcFileData("", "assertions 0") from core.world import CoreWorld from core.selection import SelectionSystem from core.event_handler import EventHandler from core.tool_manager import ToolManager from core.script_system import ScriptManager from core.patrol_system import PatrolSystem from core.Command_System import CommandManager from gui.gui_manager import GUIManager from core.terrain_manager import TerrainManager from scene.scene_manager import SceneManager from project.project_manager import ProjectManager from ui.widgets import CustomMeta3DWidget, CustomFileView, CustomTreeWidget from ui.property_panel import PropertyPanelManager from ui.interface_manager import InterfaceManager from panda3d.core import (CardMaker, Vec4, Vec3, ColorAttrib, MaterialAttrib, GeomNode, NodePath, Material, CollisionTraverser, CollisionHandlerQueue, CollisionNode, CollisionRay, Plane, Point3, Point2, BitMask32, CollisionSphere, CollisionPlane, ModelPool, Filename, ModelRoot, AmbientLight, DirectionalLight, TextureAttrib, DriveInterface, WindowProperties) from panda3d.egg import EggData, EggVertexPool, EggPolygon from direct.task import Task from direct.task.TaskManagerGlobal import taskMgr from direct.showbase.ShowBase import ShowBase from direct.showbase.DirectObject import DirectObject from direct.showbase.ShowBaseGlobal import globalClock, aspect2d import os import json import datetime from direct.actor.Actor import Actor from PyQt5.sip import wrapinstance #from RenderPipelineFile.toolkit.material_editor.main import MaterialEditor class MyWorld(CoreWorld): def __init__(self): super().__init__() # 初始化选择和变换系统 self.selection = SelectionSystem(self) # 绑定F键用于聚焦选中节点 self.accept("f", self.onFocusKeyPressed) self.accept("F", self.onFocusKeyPressed) # 大写F #初始化巡检系统 self.patrol_system = PatrolSystem(self) self.accept("p",self.onPatrolKeyPressed) self.accept("P",self.onPatrolKeyPressed) # 初始化事件处理系统 self.event_handler = EventHandler(self) # 初始化工具管理系统 self.tool_manager = ToolManager(self) # 初始化脚本管理系统 self.script_manager = ScriptManager(self) # 初始化GUI管理系统 self.gui_manager = GUIManager(self) # 初始化视频管理 self.video_manager = VideoManager(self) # 初始化场景管理系统 self.scene_manager = SceneManager(self) # 初始化项目管理系统 self.project_manager = ProjectManager(self) # 初始化属性面板管理系统 self.property_panel = PropertyPanelManager(self) # 初始化界面管理系统 self.interface_manager = InterfaceManager(self) # 启动脚本系统 self.script_manager.start_system() #self.material_editor = None self.terrain_manager = TerrainManager(self) self.terrain_edit_radius = 3.0 self.terrain_edit_strength=0.3 self.terrain_edit_operation = "add" self.info_panel_manager = InfoPanelManager(self) self.command_manager = CommandManager() # 初始化碰撞管理器 from core.collision_manager import CollisionManager self.collision_manager = CollisionManager(self) # 初始化VR管理器 try: from core.vr import VRManager self.vr_manager = VRManager(self) print("✓ VR管理器初始化完成") except Exception as e: print(f"⚠ VR管理器初始化失败: {e}") self.vr_manager = None # 调试选项 self.debug_collision = True # 是否显示碰撞体 # 默认启用模型间碰撞检测(可选) self.enableModelCollisionDetection(enable=True, frequency=0.1, threshold=0.5) try: self.property_panel = PropertyPanelManager(self) print("✓ 属性面板管理器初始化完成") except Exception as e: print(f"⚠ 属性面板管理器初始化失败: {e}") import traceback traceback.print_exc() self.property_panel = None print("✓ MyWorld 初始化完成") print("✅ 碰撞管理器已初始化") # ==================== 兼容性属性 ==================== # 保留models属性以兼容现有代码 @property def models(self): """模型列表的兼容性属性""" return self.scene_manager.models @models.setter def models(self, value): """模型列表的兼容性设置器""" self.scene_manager.models = value # 保留gui_elements属性以兼容现有代码 @property def gui_elements(self): """GUI元素列表的兼容性属性""" return self.gui_manager.gui_elements @gui_elements.setter def gui_elements(self, value): """GUI元素列表的兼容性设置器""" self.gui_manager.gui_elements = value # 保留gui_elements属性以兼容现有代码 @property def Spotlight(self): """GUI元素列表的兼容性属性""" return self.scene_manager.Spotlight @Spotlight.setter def Spotlight(self, value): """GUI元素列表的兼容性设置器""" self.scene_manager.Spotlight = value @property def Pointlight(self): return self.scene_manager.Pointlight @Pointlight.setter def Pointlight(self,value): self.scene_manager.Pointlight = value # 保留guiEditMode属性以兼容现有代码 @property def guiEditMode(self): """GUI编辑模式的兼容性属性""" return self.gui_manager.guiEditMode @guiEditMode.setter def guiEditMode(self, value): """GUI编辑模式的兼容性设置器""" self.gui_manager.guiEditMode = value # 保留currentTool属性以兼容现有代码 @property def currentTool(self): """当前工具的兼容性属性""" return self.tool_manager.currentTool @currentTool.setter def currentTool(self, value): """当前工具的兼容性设置器""" self.tool_manager.currentTool = value # 保留treeWidget属性以兼容现有代码 @property def treeWidget(self): """树形控件的兼容性属性""" return self.interface_manager.treeWidget @treeWidget.setter def treeWidget(self, value): """树形控件的兼容性设置器""" self.interface_manager.treeWidget = value #保留terrains属性以兼容现有代码 @property def terrains(self): """地形列表的兼容性属性""" return self.terrain_manager.terrains @terrains.setter def terrains(self,value): """地形列表的兼容性设置器""" self.terrain_manager.terrains = value # ==================== GUI管理功能代理 ==================== # GUI元素创建方法 - 代理到gui_manager def createGUIButton(self, pos=(0, 0, 0), text="按钮", size=0.1): """创建2D GUI按钮""" return self.gui_manager.createGUIButton(pos, text, size) def createGUILabel(self, pos=(0, 0, 0), text="标签", size=0.08): """创建2D GUI标签""" return self.gui_manager.createGUILabel(pos, text, size) def createGUIEntry(self, pos=(0, 0, 0), placeholder="输入文本...", size=0.08): """创建2D GUI文本输入框""" return self.gui_manager.createGUIEntry(pos, placeholder, size) def createGUI3DText(self, pos=(0, 0, 0), text="3D文本", size=1): """创建3D空间文本""" return self.gui_manager.createGUI3DText(pos, text, size) def createGUI3DImage(self,pos=(0,0,0),text="3D图片",size=(1,1,1)): """创建3D图片""" return self.gui_manager.createGUI3DImage(pos,text,size) def createGUI2DImage(self, pos=(0, 0, 0), image_path=None, size=2): """创建2D GUI图片""" return self.gui_manager.createGUI2DImage(pos, image_path, size) def createVideoScreen(self,pos=(0,0,0),size=1,video_path=None): """创建视频屏幕""" return self.gui_manager.createVideoScreen(pos,size,video_path) def create2DVideoScreen(self,pos=(0,0,0),size=0.2,video_path=None): """创建2D视频屏幕""" return self.gui_manager.createGUI2DVideoScreen(pos,size,video_path) def createSphericalVideo(self,pos=(0,0,0),radius=5.0,video_path=None): """创建360度视频""" return self.gui_manager.createSphericalVideo(pos,radius,video_path) def playSphericalVideo(self,spherical_video_node): return self.gui_manager.playSphericalVideo(spherical_video_node) def pauseSphericalVideo(self,spherical_video_node): return self.gui_manager.pauseSphericalVideo(spherical_video_node) def setSphericalVideoTime(self,spherical_video_node,time_seconds): return self.gui_manager.setSphericalVideoTime(spherical_video_node,time_seconds) def createSpotLight(self,pos=(0,0,5)): """创建聚光灯""" return self.scene_manager.createSpotLight(pos) def createPointLight(self,pos=(0,0,5)): """创建点光源""" return self.scene_manager.createPointLight(pos) def createGUIVirtualScreen(self, pos=(0, 0, 0), size=(2, 1), text="虚拟屏幕"): """创建3D虚拟屏幕""" return self.gui_manager.createGUIVirtualScreen(pos, size, text) def createGUISlider(self, pos=(0, 0, 0), text="滑块", scale=0.3): """创建2D GUI滑块""" return self.gui_manager.createGUISlider(pos, text, scale) # GUI元素管理方法 - 代理到gui_manager def deleteGUIElement(self, gui_element): """删除GUI元素""" return self.gui_manager.deleteGUIElement(gui_element) def editGUIElement(self, gui_element, property_name, value): """编辑GUI元素属性""" return self.gui_manager.editGUIElement(gui_element, property_name, value) def duplicateGUIElement(self, gui_element): """复制GUI元素""" return self.gui_manager.duplicateGUIElement(gui_element) def editGUIElementDialog(self, gui_element): """显示GUI元素编辑对话框""" return self.gui_manager.editGUIElementDialog(gui_element) # GUI事件处理方法 - 代理到gui_manager def onGUIButtonClick(self, button_id): """GUI按钮点击事件处理""" return self.gui_manager.onGUIButtonClick(button_id) def onGUIEntrySubmit(self, text, entry_id): """GUI输入框提交事件处理""" return self.gui_manager.onGUIEntrySubmit(text, entry_id) # GUI编辑模式方法 - 代理到gui_manager def toggleGUIEditMode(self): """切换GUI编辑模式""" return self.gui_manager.toggleGUIEditMode() def enterGUIEditMode(self): """进入GUI编辑模式""" return self.gui_manager.enterGUIEditMode() def exitGUIEditMode(self): """退出GUI编辑模式""" return self.gui_manager.exitGUIEditMode() def createGUIEditPanel(self): """创建GUI编辑面板""" return self.gui_manager.createGUIEditPanel() def openGUIPreviewWindow(self): """打开独立的GUI预览窗口""" return self.gui_manager.openGUIPreviewWindow() def closeGUIPreviewWindow(self): """关闭GUI预览窗口""" return self.gui_manager.closeGUIPreviewWindow() # GUI工具和选择方法 - 代理到gui_manager def setGUICreateTool(self, tool_type): """设置GUI创建工具""" return self.gui_manager.setGUICreateTool(tool_type) def deleteSelectedGUI(self): """删除选中的GUI元素""" return self.gui_manager.deleteSelectedGUI() def copySelectedGUI(self): """复制选中的GUI元素""" return self.gui_manager.copySelectedGUI() def handleGUIEditClick(self, hitPos): """处理GUI编辑模式下的点击""" return self.gui_manager.handleGUIEditClick(hitPos) def createGUIAtPosition(self, world_pos, gui_type): """在指定位置创建GUI元素""" return self.gui_manager.createGUIAtPosition(world_pos, gui_type) def findClickedGUI(self, hitNode): """查找被点击的GUI元素""" return self.gui_manager.findClickedGUI(hitNode) def selectGUIInTree(self, gui_element): """在树形控件中选中GUI元素""" return self.gui_manager.selectGUIInTree(gui_element) def updateGUISelection(self, gui_element): """更新GUI元素选择状态""" return self.gui_manager.updateGUISelection(gui_element) # GUI属性面板方法 - 代理到gui_manager def selectGUIColor(self, gui_element): """选择GUI元素颜色""" return self.gui_manager.selectGUIColor(gui_element) def editGUI2DPosition(self, gui_element, axis, value): """编辑2D GUI元素位置""" return self.gui_manager.editGUI2DPosition(gui_element, axis, value) # ==================== 事件处理代理 ==================== def onTreeItemClicked(self, item, column): """处理树形控件项目点击事件 - 代理到interface_manager""" return self.interface_manager.onTreeItemClicked(item, column) def setTreeWidget(self, treeWidget): """设置树形控件引用 - 代理到interface_manager""" return self.interface_manager.setTreeWidget(treeWidget) def mousePressEventLeft(self, evt): """处理鼠标左键按下事件 - 代理到event_handler""" return self.event_handler.mousePressEventLeft(evt) def mouseReleaseEventLeft(self, evt): """处理鼠标左键释放事件 - 代理到event_handler""" return self.event_handler.mouseReleaseEventLeft(evt) def wheelForward(self, data=None): """处理滚轮向前滚动(前进) - 代理到event_handler""" return self.event_handler.wheelForward(data) def wheelBackward(self, data=None): """处理滚轮向后滚动(后退) - 代理到event_handler""" return self.event_handler.wheelBackward(data) def mousePressEventMiddle(self, evt): """处理鼠标中键按下事件 - 代理到event_handler""" return self.event_handler.mousePressEventMiddle(evt) def mouseReleaseEventMiddle(self, evt): """处理鼠标中键释放事件 - 代理到event_handler""" return self.event_handler.mouseReleaseEventMiddle(evt) def mouseMoveEvent(self, evt): """处理鼠标移动事件 - 代理到event_handler""" return self.event_handler.mouseMoveEvent(evt) # ==================== 射线显示控制 ==================== def toggleRayDisplay(self): """切换射线显示状态 - 代理到event_handler""" return self.event_handler.toggleRayDisplay() def setRayDisplay(self, show=True): """设置射线显示状态 - 代理到event_handler""" self.event_handler.showRay = show if not show: self.event_handler.clearRay() return show def getRayDisplay(self): """获取射线显示状态 - 代理到event_handler""" return self.event_handler.showRay def setRayLifetime(self, seconds): """设置射线显示时长(秒) - 代理到event_handler""" self.event_handler.rayLifetime = seconds print(f"射线显示时长设置为: {seconds}秒") def getRayLifetime(self): """获取射线显示时长 - 代理到event_handler""" return self.event_handler.rayLifetime # ==================== 属性面板代理 ==================== def setPropertyLayout(self, layout): """设置属性面板布局引用 - 代理到property_panel""" return self.property_panel.setPropertyLayout(layout) def clearPropertyPanel(self): """清空属性面板 - 代理到property_panel""" return self.property_panel.clearPropertyPanel() def updatePropertyPanel(self, item): """更新属性面板显示 - 代理到property_panel""" return self.property_panel.updatePropertyPanel(item) def updateGUIPropertyPanel(self, gui_element): """更新GUI元素属性面板 - 代理到property_panel""" return self.property_panel.updateGUIPropertyPanel(gui_element) def removeActorForModel(self,model): return self.property_panel.removeActorForModel( model) def updateNodeVisibilityAfterDrag(self,item): return self.property_panel.updateNodeVisibilityAfterDrag(item) # ==================== 工具管理代理 ==================== def setCurrentTool(self, tool): """设置当前工具 - 代理到tool_manager""" return self.tool_manager.setCurrentTool(tool) # ==================== 场景管理功能代理 ==================== # 模型导入和处理方法 - 代理到scene_manager def importModel(self, filepath): """导入模型到场景""" # 自动转换FBX等格式为GLB以获得更好的动画支持(不再弹窗询问) # 如果你不想自动转换,可以将 auto_convert 改为 False auto_convert = False print(f"[模型导入] 文件: {filepath}, 自动转换GLB: {auto_convert}") return self.scene_manager.importModel(filepath, auto_convert_to_glb=auto_convert) def importModelAsync(self, filepath): """异步导入模型""" return self.scene_manager.importModelAsync(filepath) # 材质和几何体处理方法 - 代理到scene_manager def processMaterials(self, model): """处理模型材质""" return self.scene_manager.processMaterials(model) def processModelGeometry(self, model): """处理模型几何体""" return self.scene_manager.processModelGeometry(model) # 碰撞系统方法 - 代理到scene_manager def setupCollision(self, model): """为模型设置碰撞检测""" return self.scene_manager.setupCollision(model) # 场景树管理方法 - 代理到scene_manager def updateSceneTree(self): """更新场景树显示""" return self.scene_manager.updateSceneTree() # 场景保存和加载方法 - 代理到scene_manager def saveScene(self, filename): """保存场景到BAM文件""" return self.scene_manager.saveScene(filename) def loadScene(self, filename): """从BAM文件加载场景""" return self.scene_manager.loadScene(filename) # 模型管理方法 - 代理到scene_manager def deleteModel(self, model): """删除模型""" return self.scene_manager.deleteModel(model) def clearAllModels(self): """清除所有模型""" return self.scene_manager.clearAllModels() def getModels(self): """获取模型列表""" return self.scene_manager.getModels() def getModelCount(self): """获取模型数量""" return self.scene_manager.getModelCount() def findModelByName(self, name): """根据名称查找模型""" return self.scene_manager.findModelByName(name) # ==================== 脚本系统功能代理 ==================== # 脚本系统控制方法 - 代理到script_manager def startScriptSystem(self): """启动脚本系统""" return self.script_manager.start_system() def stopScriptSystem(self): """停止脚本系统""" return self.script_manager.stop_system() def enableHotReload(self, enabled=True): """启用/禁用热重载""" self.script_manager.hot_reload_enabled = enabled if enabled: self.script_manager.start_hot_reload() else: self.script_manager.stop_hot_reload() # 脚本创建和加载方法 - 代理到script_manager def createScript(self, script_name, template="basic"): """创建新脚本文件""" return self.script_manager.create_script_file(script_name, template) def loadScript(self, script_path): """从文件加载脚本""" return self.script_manager.load_script_from_file(script_path) def loadAllScripts(self, directory=None): """从目录加载所有脚本""" return self.script_manager.load_all_scripts_from_directory(directory) def reloadScript(self, script_name): """重新加载脚本""" return self.script_manager.reload_script(script_name) # 脚本挂载和管理方法 - 代理到script_manager def addScript(self, game_object, script_name): """为游戏对象添加脚本""" return self.script_manager.add_script_to_object(game_object, script_name) def removeScript(self, game_object, script_name): """从游戏对象移除脚本""" return self.script_manager.remove_script_from_object(game_object, script_name) def getScripts(self, game_object): """获取对象上的所有脚本""" return self.script_manager.get_scripts_on_object(game_object) def getScript(self, game_object, script_name): """获取对象上的特定脚本""" return self.script_manager.get_script_on_object(game_object, script_name) # 脚本信息查询方法 - 代理到script_manager def getAvailableScripts(self): """获取所有可用的脚本名称""" return self.script_manager.get_available_scripts() def getScriptInfo(self, script_name): """获取脚本信息""" return self.script_manager.get_script_info(script_name) def listAllScripts(self): """列出所有脚本信息""" return self.script_manager.list_all_scripts() def loadCesiumTileset(self,tileset_url,position=(0,0,0)): return self.scene_manager.load_cesium_tileset(tileset_url,position) def addCesiumTileset(self,name,url,position=(0,0,0)): if hasattr(self,'gui_manager') and self.gui_manager: return self.gui_manager.addCesiumTilesetToScene(name,url,position) else: return self.scene_manager.load_cesium_tileset(url,position) # ==================== 地形管理功能代理 ==================== # 地形创建方法 - 代理到terrain_manager def createTerrainFromHeightMap(self, heightmap_path, scale=(1, 1, 1)): """从高度图创建地形""" return self.terrain_manager.createTerrainFromHeightMap(heightmap_path, scale) def createFlatTerrain(self, size=(0.3, 0.3), resolution=256): """创建平面地形""" return self.terrain_manager.createFlatTerrain(size, resolution) def updateTerrain(self): """更新所有地形的LOD""" return self.terrain_manager.updateTerrain() def getTerrainHeight(self, terrain_info, x, y): """获取地形上指定点的高度""" return self.terrain_manager.getTerrainHeight(terrain_info, x, y) def setTerrainEditParameters(self,radius=None,strength=None,operation=None): if radius is not None: self.terrain_edit_radius = float(radius) if strength is not None: self.terrain_edit_strenght = float(strength) if operation is not None: self.terrain_edit_operation = operation print(f"地形编辑参数已更新: 半径={self.terrain_edit_radius}, 强度={self.terrain_edit_strength}, 操作={self.terrain_edit_operation}") def getTerrainEditParameters(self): """获取当前地形编辑参数""" return { 'radius': self.terrain_edit_radius, 'strength': self.terrain_edit_strength, 'operation': self.terrain_edit_operation } def modifyTerrainHeight(self, terrain_info, x, y, radius, strength, operation="add"): """修改地形高度的便捷方法""" if hasattr(self, 'terrain_manager'): return self.terrain_manager.modifyTerrainHeight(terrain_info, x, y, radius, strength, operation) return False # 添加碰撞管理相关的代理方法 def enableModelCollisionDetection(self, enable=True, frequency=0.1, threshold=0.5): """启用模型间碰撞检测""" return self.collision_manager.enableModelCollisionDetection(enable, frequency, threshold) def detectModelCollisions(self, specific_models=None, log_results=True): """检测模型间碰撞""" return self.collision_manager.detectModelCollisions(specific_models, log_results) def getCollisionHistory(self, limit=None): """获取碰撞历史""" return self.collision_manager.getCollisionHistory(limit) def getCollisionStatistics(self): """获取碰撞统计""" return self.collision_manager.getCollisionStatistics() def setupKeyboardEvents(self): """设置键盘事件""" try: # 绑定 F 键用于聚焦选中节点 self.accept("f", self.onFocusKeyPressed) self.accept("F", self.onFocusKeyPressed) # 大写F print("✓ 键盘事件绑定完成") except Exception as e: print(f"设置键盘事件失败: {e}") def onFocusKeyPressed(self): """处理 F 键按下事件""" try: #print("检测到 F 键按下") # 检查是否有选中的节点 if hasattr(self, 'selection') and self.selection.selectedNode: #print(f"当前选中节点: {self.selection.selectedNode.getName()}") # 调用选择系统的聚焦功能(可以选择带动画或不带动画的版本) # self.selection.focusCameraOnSelectedNode() # 无动画版本 self.selection.focusCameraOnSelectedNodeAdvanced() # 带动画版本 else: print("当前没有选中任何节点") except Exception as e: print(f"处理 F 键事件失败: {e}") def onPatrolKeyPressed(self): """处理 P 键按下事件 - 控制巡检系统""" try: print("检测到 P 键按下") if not self.patrol_system.is_patrolling: # 如果巡检系统没有点,创建默认巡检路线 if not self.patrol_system.patrol_points: self.createDefaultPatrolRoute() # 开始巡检 if self.patrol_system.start_patrol(): print("✓ 巡检已开始") else: print("✗ 巡检启动失败") else: # 停止巡检 if self.patrol_system.stop_patrol(): print("✓ 巡检已停止") else: print("✗ 巡检停止失败") except Exception as e: print(f"处理 P 键事件失败: {e}") def createDefaultPatrolRoute(self): """创建默认巡检路线(使用自动朝向)""" try: # 清空现有巡检点 self.patrol_system.clear_patrol_points() # 添加巡检点,使用None表示朝向下一个点 self.patrol_system.add_patrol_point((0, -10, 2), (0,0,0), 1.5) self.patrol_system.add_patrol_point((10, -10, 2), (0,0,0), 1.5) self.patrol_system.add_patrol_point((10, 5, 2), (0,0,0), 1.5) self.patrol_system.add_patrol_point((10, 0, 5), (0,0,0), 1.5) # 最后一个点可以指定特定的朝向,或者也设为None继续循环 self.patrol_system.add_patrol_point((0, -10, 2), None, 2.5) print("✓ 默认自动朝向巡检路线已创建") self.patrol_system.list_patrol_points() except Exception as e: print(f"创建默认自动朝向巡检路线失败: {e}") def _serializeNode(self, node): """序列化节点数据""" try: return self.world.scene_manager.serializeNode(node) except Exception as e: print(f"序列化节点失败: {e}") return None def _deserializeNode(self, node_data, parent_node): """反序列化节点数据""" try: return self.world.scene_manager.deserializeNode(node_data, parent_node) except Exception as e: print(f"反序列化节点失败: {e}") return None # ==================== 项目管理功能代理 ==================== # 以下函数代理到project_manager模块的对应功能 def updateWindowTitle(window, project_name=None): """更新窗口标题 - 代理到project_manager""" from project.project_manager import updateWindowTitle as pm_updateWindowTitle return pm_updateWindowTitle(window, project_name) def createNewProject(parent_window): """创建新项目 - 代理到project_manager""" world = parent_window.centralWidget().world return world.project_manager.createNewProject(parent_window) def saveProject(appw): """保存项目 - 代理到project_manager""" world = appw.centralWidget().world return world.project_manager.saveProject(appw) def openProject(appw): """打开项目 - 代理到project_manager""" world = appw.centralWidget().world return world.project_manager.openProject(appw) def openProjectForPath(project_path, appw): """打开项目 - 代理到project_manager""" world = appw.centralWidget().world return world.project_manager.openProjectForPath(project_path, appw) def buildPackage(appw): """打包项目 - 代理到project_manager""" world = appw.centralWidget().world return world.project_manager.buildPackage(appw) def run(args = None): print(f'Path is {args}') print("引擎已启动(使用Panda3D原生窗口)") # 创建世界实例并运行 world = MyWorld() world.run() if __name__ == "__main__": run()