forked from Rowland/EG
760 lines
27 KiB
Python
760 lines
27 KiB
Python
import warnings
|
||
|
||
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 QPanda3D.QPanda3DWidget import QPanda3DWidget
|
||
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.vr_manager import VRManager
|
||
from core.vr_input_handler import VRInputHandler
|
||
from core.alvr_streamer import ALVRStreamer
|
||
from gui.gui_manager import GUIManager
|
||
from scene.scene_manager import SceneManager
|
||
from project.project_manager import ProjectManager
|
||
from ui.widgets import CustomPanda3DWidget, 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
|
||
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)
|
||
|
||
# 初始化事件处理系统
|
||
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)
|
||
|
||
# 初始化VR系统
|
||
self.vr_manager = VRManager(self)
|
||
self.vr_input_handler = VRInputHandler(self, self.vr_manager)
|
||
self.alvr_streamer = ALVRStreamer(self, self.vr_manager)
|
||
|
||
# 启动脚本系统
|
||
self.script_manager.start_system()
|
||
|
||
#self.material_editor = None
|
||
|
||
# 初始化碰撞管理器
|
||
from core.collision_manager import CollisionManager
|
||
self.collision_manager = CollisionManager(self)
|
||
|
||
# 调试选项
|
||
self.debug_collision = True # 是否显示碰撞体
|
||
|
||
# 默认启用模型间碰撞检测(可选)
|
||
self.enableModelCollisionDetection(enable=True, frequency=0.1, threshold=0.5)
|
||
|
||
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
|
||
|
||
# ==================== 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=0.5):
|
||
"""创建3D空间文本"""
|
||
return self.gui_manager.createGUI3DText(pos, text, size)
|
||
|
||
def createSpotLight(self,pos=(-20,0,5)):
|
||
"""创建聚光灯"""
|
||
return self.scene_manager.createSpotLight(pos)
|
||
|
||
def createPointLight(self,pos=(20,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
|
||
if filepath.lower().endswith('.fbx'):
|
||
try:
|
||
from PyQt5.QtWidgets import QMessageBox
|
||
reply = QMessageBox.question(
|
||
None,
|
||
'格式转换选择',
|
||
'FBX文件检测到!\n\n是否要尝试转换为GLB格式以获得更好的动画支持?\n\n点击"是":尝试转换为GLB格式(需要安装转换工具)\n点击"否":直接使用原始FBX格式导入',
|
||
QMessageBox.Yes | QMessageBox.No,
|
||
QMessageBox.Yes
|
||
)
|
||
auto_convert = (reply == QMessageBox.Yes)
|
||
except ImportError:
|
||
# 如果没有PyQt5,默认不转换
|
||
print("检测到FBX文件,由于GUI不可用,将直接使用原始格式导入")
|
||
auto_convert = False
|
||
else:
|
||
# 非FBX文件,保持原有逻辑
|
||
auto_convert = True
|
||
|
||
return self.scene_manager.importModel(filepath, auto_convert_to_glb=auto_convert)
|
||
|
||
def importModelAsync(self, filepath):
|
||
"""异步导入模型"""
|
||
return self.scene_manager.importModelAsync(filepath)
|
||
|
||
def loadAnimatedModel(self, model_path, anims=None):
|
||
"""加载带动画的模型"""
|
||
return self.scene_manager.loadAnimatedModel(model_path, anims)
|
||
|
||
# 材质和几何体处理方法 - 代理到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()
|
||
# ==================== VR系统功能代理 ====================
|
||
|
||
# VR系统控制方法 - 代理到vr_manager
|
||
def initializeVR(self):
|
||
"""初始化VR系统"""
|
||
return self.vr_manager.initialize_vr()
|
||
|
||
def shutdownVR(self):
|
||
"""关闭VR系统"""
|
||
return self.vr_manager.shutdown_vr()
|
||
|
||
def isVREnabled(self):
|
||
"""检查VR是否启用"""
|
||
return self.vr_manager.is_vr_enabled()
|
||
|
||
def getVRInfo(self):
|
||
"""获取VR系统信息"""
|
||
return self.vr_manager.get_vr_info()
|
||
|
||
# VR输入处理方法 - 代理到vr_input_handler
|
||
def startVRInput(self):
|
||
"""启动VR输入处理"""
|
||
return self.vr_input_handler.start_input_handling()
|
||
|
||
def stopVRInput(self):
|
||
"""停止VR输入处理"""
|
||
return self.vr_input_handler.stop_input_handling()
|
||
|
||
def showControllerRays(self, show=True):
|
||
"""显示/隐藏控制器射线"""
|
||
return self.vr_input_handler.show_controller_rays(show)
|
||
|
||
def getControllerState(self, controller_id):
|
||
"""获取控制器状态"""
|
||
return self.vr_input_handler.get_controller_state(controller_id)
|
||
|
||
def getAllControllers(self):
|
||
"""获取所有控制器"""
|
||
return self.vr_input_handler.get_all_controllers()
|
||
|
||
def setVRGestureEnabled(self, enabled):
|
||
"""设置VR手势识别启用状态"""
|
||
return self.vr_input_handler.set_gesture_enabled(enabled)
|
||
|
||
def setVRInteractionEnabled(self, enabled):
|
||
"""设置VR交互启用状态"""
|
||
return self.vr_input_handler.set_interaction_enabled(enabled)
|
||
|
||
# ALVR串流方法 - 代理到alvr_streamer
|
||
def initializeALVR(self):
|
||
"""初始化ALVR串流"""
|
||
return self.alvr_streamer.initialize()
|
||
|
||
def startALVRStreaming(self):
|
||
"""开始ALVR串流"""
|
||
return self.alvr_streamer.start_streaming()
|
||
|
||
def stopALVRStreaming(self):
|
||
"""停止ALVR串流"""
|
||
return self.alvr_streamer.stop_streaming()
|
||
|
||
def getALVRStreamingStatus(self):
|
||
"""获取ALVR串流状态"""
|
||
return self.alvr_streamer.get_streaming_status()
|
||
|
||
def setALVRStreamQuality(self, width, height, fps, bitrate):
|
||
"""设置ALVR串流质量"""
|
||
return self.alvr_streamer.set_stream_quality(width, height, fps, bitrate)
|
||
|
||
def sendHapticFeedback(self, controller_id, duration, intensity):
|
||
"""发送触觉反馈"""
|
||
return self.alvr_streamer.send_haptic_feedback(controller_id, duration, intensity)
|
||
|
||
def shutdownALVR(self):
|
||
"""关闭ALVR串流"""
|
||
return self.alvr_streamer.shutdown()
|
||
|
||
def isALVRConnected(self):
|
||
"""检查ALVR是否连接"""
|
||
return self.alvr_streamer.is_connected()
|
||
|
||
def isALVRStreaming(self):
|
||
"""检查ALVR是否在串流"""
|
||
return self.alvr_streamer.is_streaming()
|
||
|
||
# 便捷方法
|
||
def enableVRMode(self):
|
||
"""启用VR模式(一键启动)"""
|
||
print("启用VR模式...")
|
||
|
||
# 1. 初始化VR系统
|
||
if not self.initializeVR():
|
||
print("VR系统初始化失败")
|
||
return False
|
||
|
||
# 2. 启动VR输入处理
|
||
if not self.startVRInput():
|
||
print("VR输入处理启动失败")
|
||
return False
|
||
|
||
# 3. 初始化ALVR串流
|
||
if self.initializeALVR():
|
||
print("✓ ALVR串流已启用")
|
||
# 自动开始串流
|
||
self.startALVRStreaming()
|
||
else:
|
||
print("⚠ ALVR串流启用失败,但VR系统仍可用")
|
||
|
||
print("✓ VR模式已启用")
|
||
return True
|
||
|
||
def disableVRMode(self):
|
||
"""禁用VR模式(一键关闭)"""
|
||
print("禁用VR模式...")
|
||
|
||
# 1. 停止ALVR串流
|
||
self.stopALVRStreaming()
|
||
self.shutdownALVR()
|
||
|
||
# 2. 停止VR输入处理
|
||
self.stopVRInput()
|
||
|
||
# 3. 关闭VR系统
|
||
self.shutdownVR()
|
||
|
||
print("✓ VR模式已禁用")
|
||
|
||
def getVRStatus(self):
|
||
"""获取VR系统总体状态"""
|
||
return {
|
||
"vr_enabled": self.isVREnabled(),
|
||
"vr_info": self.getVRInfo(),
|
||
"controllers": self.getAllControllers(),
|
||
"alvr_connected": self.isALVRConnected(),
|
||
"alvr_streaming": self.isALVRStreaming(),
|
||
"streaming_status": self.getALVRStreamingStatus() if self.isALVRConnected() else None
|
||
}
|
||
|
||
# 添加碰撞管理相关的代理方法
|
||
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()
|
||
|
||
|
||
# ==================== 项目管理功能代理 ====================
|
||
# 以下函数代理到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 buildPackage(appw):
|
||
"""打包项目 - 代理到project_manager"""
|
||
world = appw.centralWidget().world
|
||
return world.project_manager.buildPackage(appw)
|
||
|
||
|
||
# def open_material_editor(self):
|
||
# """打开材质编辑器作为子窗口"""
|
||
# if not self.material_editor:
|
||
# self.material_editor = MaterialEditor()
|
||
# # 设置为子窗口
|
||
# self.material_editor.setParent(self)
|
||
# self.material_editor.setWindowFlags(Qt.Window)
|
||
#
|
||
# self.material_editor.show()
|
||
#
|
||
|
||
if __name__ == "__main__":
|
||
world = MyWorld()
|
||
|
||
# 使用新的UI模块创建主窗口
|
||
from ui.main_window import setup_main_window
|
||
|
||
app, main_window = setup_main_window(world)
|
||
|
||
# 启动应用程序
|
||
sys.exit(app.exec_()) |