From e20d2a21911580df1ed0175a8bb7f13e98290b79 Mon Sep 17 00:00:00 2001 From: Rowland <975945824@qq.com> Date: Mon, 20 Oct 2025 17:01:45 +0800 Subject: [PATCH] =?UTF-8?q?vr=E6=8B=86=E5=88=86s3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IFLOW.md | 179 ++++++++ STAGE1_COMPLETION_REPORT.md | 358 ---------------- STAGE2_COMPLETION_REPORT.md | 349 ---------------- core/vr/performance/optimization.py | 346 ++++++++++++++++ core/vr_manager.py | 614 ++++++++++++---------------- test_test_mode_integration.py | 200 --------- 6 files changed, 780 insertions(+), 1266 deletions(-) create mode 100644 IFLOW.md delete mode 100644 STAGE1_COMPLETION_REPORT.md delete mode 100644 STAGE2_COMPLETION_REPORT.md create mode 100644 core/vr/performance/optimization.py delete mode 100644 test_test_mode_integration.py diff --git a/IFLOW.md b/IFLOW.md new file mode 100644 index 00000000..8716200d --- /dev/null +++ b/IFLOW.md @@ -0,0 +1,179 @@ +# iFlow 上下文文档 + +## 项目概述 + +这是一个基于 Panda3D 和 PyQt5 的 3D 虚拟现实 (VR) 应用程序框架。该项目旨在提供一个功能齐全、模块化的 3D 环境,支持 VR 设备(如 HTC Vive, Oculus Rift)的集成,包含场景管理、模型导入、GUI 系统、脚本系统、地形系统、碰撞检测以及完整的 VR 交互功能。 + +核心架构围绕 `MyWorld` 类构建,该类继承自 `CoreWorld`,并集成了各种管理器模块,如选择系统、工具管理器、脚本管理器、GUI 管理器、场景管理器、项目管理器、地形管理器、碰撞管理器和 VR 管理器。 + +## 核心技术栈 + +- **核心引擎**: Panda3D +- **图形渲染**: 可选择普通渲染或 RenderPipeline 高级渲染管线 +- **VR 支持**: OpenVR/SteamVR +- **用户界面**: PyQt5 +- **3D 模型格式**: 支持 glTF, FBX (需转换), BAM 等 +- **脚本语言**: Python (内嵌脚本系统) +- **物理/碰撞**: Panda3D 内置碰撞系统 + +## 项目结构 + +``` +. +├── core/ # 核心模块 +│ ├── world.py # CoreWorld 基础世界类 +│ ├── vr/ # VR 子模块 (完整模块化结构) +│ │ ├── __init__.py +│ │ ├── config/ # VR 配置管理 +│ │ ├── interaction/ # VR 交互系统 (动作、抓取、摇杆、传送) +│ │ ├── performance/ # VR 性能监控 +│ │ ├── rendering/ # VR 渲染相关 (RenderPipeline 集成) +│ │ ├── testing/ # VR 测试模式 +│ │ ├── tracking/ # VR 设备跟踪 +│ │ └── visualization/ # VR 可视化 (控制器模型) +│ ├── vr_manager.py # VR 管理器主文件 (待拆分) +│ ├── selection.py # 选择系统 +│ ├── tool_manager.py # 工具管理器 +│ ├── script_system.py # 脚本系统 +│ ├── gui_manager.py # GUI 管理器 +│ ├── terrain_manager.py # 地形管理器 +│ ├── collision_manager.py # 碰撞管理器 +│ ├── event_handler.py # 事件处理器 +│ ├── patrol_system.py # 巡检系统 +│ ├── Command_System.py # 命令系统 +│ └── InfoPanelManager.py # 信息面板管理器 +├── demo/ # 示例和测试文件 +├── gui/ # GUI 相关模块 +├── project/ # 项目管理模块 +├── scene/ # 场景管理模块 (部分代码在 core/) +├── scripts/ # 脚本文件目录 +├── ui/ # UI 组件和主窗口 +├── QPanda3D/ # Panda3D 与 PyQt 集成库 +├── Resources/ # 资源文件 (模型、纹理等) +├── config/ # 配置文件 +│ └── vr_settings.json # VR 配置文件 +├── main.py # 程序入口点 +└── Start_Run.py # 启动脚本 +``` + +## 核心功能模块 + +### 1. World (core/world.py, main.py) + +- `CoreWorld`: 基础 3D 世界设置,包括相机、光照、地面、资源路径。 +- `MyWorld`: 扩展的主世界类,整合所有管理器和功能模块。 + - **初始化**: 设置资源路径、相机、光照、地面,加载中文字体。 + - **兼容性**: 提供旧版属性访问接口。 + - **功能代理**: 将大量功能委托给专门的管理器。 + +### 2. VR 系统 (core/vr/) + +这是一个高度模块化的 VR 子系统,核心是 `VRManager` (core/vr_manager.py)。 + +- **VRManager**: + - **初始化与状态管理**: 检查 VR 可用性、初始化 OpenVR、管理启用/禁用状态。 + - **渲染系统**: + - 支持普通渲染和 RenderPipeline 高级渲染两种模式。 + - 创建和管理左右眼的渲染缓冲区和相机。 + - 实现高效的纹理提交到 OpenVR Compositor。 + - 支持动态分辨率缩放和质量预设。 + - **跟踪系统**: + - 通过 OpenVR 获取 HMD 和控制器的姿态。 + - 使用锚点层级系统 (`tracking_space`, `hmd_anchor` 等) 管理设备位置。 + - 坐标系转换 (OpenVR 到 Panda3D)。 + - **控制器**: + - `LeftController`, `RightController`: 管理具体的手柄输入和可视化。 + - 支持动作系统 (VRActionManager) 或直接输入读取。 + - **交互系统**: + - **VRInteractionManager**: 对象抓取和交互。 + - **VRTeleportSystem**: 传送功能。 + - **VRJoystickManager**: 摇杆移动控制。 + - **性能优化**: + - 对象池 (Mat4) 减少 GC 压力。 + - 纹理 ID 缓存避免重复 prepare。 + - 智能 GPU 同步策略。 + - 性能模式自动切换。 + - **配置管理**: + - `VRConfigManager`: 从 `config/vr_settings.json` 加载/保存配置。 + - **测试与调试**: + - `VRTestMode`: 提供不同的测试显示模式和功能开关。 + - `VRPerformanceMonitor`: 性能监控和报告。 + +### 3. GUI 系统 (core/gui_manager.py, gui/) + +- **GUIManager**: 管理 2D 和 3D GUI 元素的创建、编辑、删除。 +- **功能**: + - 创建按钮、标签、输入框、2D/3D 图像、视频屏幕等。 + - GUI 编辑模式,支持拖拽创建和属性编辑。 + - 与场景树和属性面板集成。 + - 独立的 GUI 预览窗口。 + +### 4. 场景与模型管理 (core/scene_manager.py) + +- **SceneManager**: 管理 3D 场景中的所有模型。 +- **功能**: + - 模型导入 (支持 glTF, FBX 转换)。 + - 材质和几何体处理。 + - 碰撞体设置。 + - 场景保存/加载 (BAM 格式)。 + - 场景树更新。 + +### 5. 脚本系统 (core/script_system.py) + +- **ScriptManager**: 嵌入式 Python 脚本系统。 +- **功能**: + - 脚本文件的创建、加载、重载。 + - 为游戏对象挂载/卸载脚本。 + - 热重载支持。 + - 脚本信息查询。 + +### 6. 地形系统 (core/terrain_manager.py) + +- **TerrainManager**: 管理 3D 地形。 +- **功能**: + - 从高度图或创建平面地形。 + - 地形 LOD 更新。 + - 地形高度查询和编辑。 + +### 7. 碰撞系统 (core/collision_manager.py) + +- **CollisionManager**: 处理场景中的碰撞检测。 +- **功能**: + - 模型间碰撞检测。 + - 碰撞历史和统计。 + +### 8. 工具与选择系统 (core/tool_manager.py, core/selection.py) + +- **ToolManager**: 管理当前使用的工具 (选择、移动、旋转、缩放)。 +- **SelectionSystem**: 处理对象选择逻辑和相机聚焦。 + +## 构建与运行 + +### 入口点 + +- `main.py`: 主程序入口,创建 `MyWorld` 实例并启动 PyQt5 主窗口。 +- `Start_Run.py`: 可能的启动脚本。 + +### 运行方式 + +1. 确保已安装所有依赖项(Panda3D, PyQt5, OpenVR 等)。 +2. 运行 `python main.py` 启动应用程序。 +3. 如果连接了 VR 设备并安装了 SteamVR,可以在应用内启用 VR 模式。 + +### 依赖项 + +项目未提供 `requirements.txt` 文件,但根据代码分析,主要依赖包括: + +- `panda3d` +- `PyQt5` +- `openvr` (用于 VR 功能) +- `numpy` (在 VR 模块中使用) + +## 开发约定 + +- **模块化设计**: 功能被分解到不同的管理器类中,`MyWorld` 主要起到集成和代理的作用。 +- **VR 子模块化**: VR 功能被组织在 `core/vr/` 目录下,具有清晰的子模块划分。 +- **配置驱动**: VR 设置通过 `config/vr_settings.json` 文件进行管理。 +- **性能意识**: VR 模块包含大量性能优化措施,如对象池、缓存、智能同步等。 +- **向后兼容**: `MyWorld` 通过属性代理保持与旧代码的兼容性。 +- **测试模式**: VR 系统包含专门的测试模式,便于调试和验证不同功能。 diff --git a/STAGE1_COMPLETION_REPORT.md b/STAGE1_COMPLETION_REPORT.md deleted file mode 100644 index 5e584660..00000000 --- a/STAGE1_COMPLETION_REPORT.md +++ /dev/null @@ -1,358 +0,0 @@ -# VR Manager 模块化拆分 - 阶段1完成报告 - -## 📋 任务概述 - -**阶段**: 阶段1 - 拆分性能监控系统 -**开始时间**: 2025-10-14 -**完成时间**: 2025-10-14 -**状态**: ✅ 已完成 - ---- - -## 🎯 完成的工作 - -### 1. 创建的文件 - -| 文件路径 | 行数 | 说明 | -|---------|------|------| -| `core/vr/performance/monitoring.py` | 1,168 | VR性能监控核心模块 | -| `core/vr/performance/__init__.py` | 已更新 | 模块导出接口 | -| `core/vr/performance/MIGRATION_REPORT.md` | - | 迁移文档 | -| `core/vr_manager.py.backup.stage1` | 4,736 | 原始文件备份 | -| `test_performance_integration.py` | - | 集成测试脚本 | - -### 2. 修改的文件 - -| 文件路径 | 变化 | 说明 | -|---------|------|------| -| `core/vr_manager.py` | 4,736 → 3,829行 (-907行) | 删除性能监控代码,添加委托方法 | - ---- - -## 📊 代码统计 - -### 代码行数变化 -- **原始 vr_manager.py**: 4,736行 ❌ (超标 5.3倍) -- **重构后 vr_manager.py**: 3,829行 ⚠️ (超标 4.25倍) -- **新增 monitoring.py**: 1,168行 ✅ (符合900行标准) -- **净减少**: 907行 (-19.1%) - -### 迁移的内容 -- **迁移的方法**: 35个 -- **迁移的属性**: 34个 -- **委托方法**: 34个(保持API兼容) - ---- - -## 🔧 技术实现 - -### 1. VRPerformanceMonitor类结构 - -```python -class VRPerformanceMonitor: - """VR性能监控系统 - - 功能模块: - - 性能报告 (3个方法) - - 性能监控核心 (4个方法) - - GPU计时 (3个方法) - - 渲染管线统计 (4个方法) - - 诊断工具 (3个方法) - - 调试控制 (5个方法) - - 配置方法 (4个方法) - - 查询方法 (4个方法) - - 控制方法 (4个方法) - """ -``` - -### 2. 集成方式 - -**在VRManager中**: -```python -# 初始化性能监控系统 -self.performance_monitor = VRPerformanceMonitor(self) - -# 委托方法示例 -def enable_performance_monitoring(self): - if self.performance_monitor: - return self.performance_monitor.enable_performance_monitoring() -``` - -### 3. 设计原则 - -- ✅ **组合优先于继承**: 通过组合模式集成子系统 -- ✅ **单一职责**: 性能监控功能独立管理 -- ✅ **向后兼容**: 100%保持现有API -- ✅ **松耦合**: 最小化模块间依赖 - ---- - -## ✅ 验证测试 - -### 1. 编译检查 -```bash -python3 -m py_compile core/vr/performance/monitoring.py ✅ -python3 -m py_compile core/vr_manager.py ✅ -``` - -### 2. 导入测试 -```bash -from core.vr.performance import VRPerformanceMonitor ✅ -``` - -### 3. 集成测试 (7项测试) -- ✅ 模块导入正常 -- ✅ 类结构完整 (13个关键方法验证) -- ✅ 初始化成功 -- ✅ 基本方法正常 -- ✅ 计时方法正常 -- ✅ 配置方法正常 -- ✅ 重置和禁用正常 - -**测试结果**: 全部通过 ✅ - ---- - -## 📦 迁移的功能模块 - -### 1. 性能报告 (3个方法) -- `_print_performance_report` - 详细性能报告 -- `_print_performance_recommendations` - 优化建议 -- `_print_brief_performance_report` - 简短摘要 - -### 2. 性能监控核心 (4个方法) -- `_init_performance_monitoring` - 初始化监控库 -- `_update_performance_metrics` - 更新性能指标 -- `_update_gpu_metrics` - 更新GPU指标 -- `_track_frame_time` - 帧时间追踪 - -### 3. GPU计时 (3个方法) -- `_get_gpu_frame_timing` - 获取GPU渲染时间 -- `enable_gpu_timing_monitoring` - 启用GPU监控 -- `disable_gpu_timing_monitoring` - 禁用GPU监控 - -### 4. 渲染管线统计 (4个方法) -- `_start_timing` - 开始计时 -- `_end_timing` - 结束计时 -- `_get_pipeline_stats` - 获取管线统计 -- `test_pipeline_monitoring` - 测试监控功能 - -### 5. 诊断工具 (3个方法) -- `_print_render_callback_diagnostics` - 渲染回调诊断 -- `_check_rendering_optimizations` - 优化状态检查 -- `_diagnose_opengl_state` - OpenGL状态诊断 - -### 6. 调试控制 (5个方法) -- `enable_debug_output`, `disable_debug_output` -- `set_debug_mode`, `toggle_debug_output` -- `get_debug_status` - -### 7. 配置方法 (4个方法) -- `set_performance_check_interval` -- `set_frame_time_history_size` -- `set_performance_report_interval` -- `set_prediction_time` - -### 8. 查询方法 (4个方法) -- `get_performance_stats` - 详细统计 -- `get_current_performance_summary` - 性能摘要 -- `get_performance_monitoring_config` - 监控配置 -- `print_performance_monitoring_status` - 监控状态 - -### 9. 控制方法 (4个方法) -- `enable_performance_monitoring`, `disable_performance_monitoring` -- `force_performance_report`, `reset_performance_counters` - ---- - -## 🎯 目标达成情况 - -| 目标 | 计划 | 实际 | 状态 | -|-----|------|------|------| -| 迁移方法数 | 35个 | 35个 | ✅ | -| 迁移属性数 | ~30个 | 34个 | ✅ | -| 新文件行数 | ~900行 | 1,168行 | ⚠️ 超出29% | -| vr_manager.py减少 | 预期减少 | -907行 (-19.1%) | ✅ | -| API兼容性 | 100% | 100% | ✅ | -| 测试通过率 | 100% | 100% | ✅ | - -**说明**: monitoring.py略超900行目标,但仍是合理的模块大小,功能完整且职责清晰。 - ---- - -## 📂 目录结构 - -``` -EG/ -├── core/ -│ ├── vr_manager.py (3,829行) ⬇️ -19% -│ └── vr/ -│ └── performance/ -│ ├── __init__.py ✨ -│ ├── monitoring.py (1,168行) ✨ -│ └── MIGRATION_REPORT.md ✨ -├── test_performance_integration.py ✨ -├── STAGE1_COMPLETION_REPORT.md ✨ -└── VR_Manager 模块化拆分计划.md -``` - ---- - -## 🔄 Git状态 - -### 待提交的文件 -``` -修改: - core/vr/performance/__init__.py - core/vr_manager.py - -新增: - core/vr/performance/monitoring.py - core/vr/performance/MIGRATION_REPORT.md - test_performance_integration.py - STAGE1_COMPLETION_REPORT.md - -备份: - core/vr_manager.py.backup.stage1 -``` - -### 建议的提交信息 -``` -feat(vr): 模块化拆分阶段1 - 性能监控系统 - -- 创建独立的VRPerformanceMonitor类 (1,168行) -- 迁移35个性能监控方法和34个属性 -- 添加34个委托方法保持API兼容性 -- vr_manager.py从4,736行减少到3,829行 (-19%) -- 所有测试通过,100% API兼容 - -相关文档: -- core/vr/performance/MIGRATION_REPORT.md -- STAGE1_COMPLETION_REPORT.md -``` - ---- - -## 🐛 修复的Bug - -在集成过程中发现并修复了以下关键问题: - -### Bug 1: AttributeError - 渲染计数属性缺失 -**错误信息**: -``` -'VRManager' object has no attribute 'left_render_count' -'VRManager' object has no attribute 'right_render_count' -``` - -**原因**: 属性迁移到VRPerformanceMonitor后,VRManager中的渲染回调仍通过`self.left_render_count`访问。 - -**解决方案**: 在VRManager中添加16组@property代理(32个属性总计),透明转发到performance_monitor: -```python -@property -def left_render_count(self): - if self.performance_monitor: - return self.performance_monitor.left_render_count - return 0 - -@left_render_count.setter -def left_render_count(self, value): - if self.performance_monitor: - self.performance_monitor.left_render_count = value -``` - -**影响范围**: vr_manager.py增加约192行代理属性代码(3648-3886行) - -### Bug 2: UnboundLocalError - 变量作用域问题 -**错误信息**: -``` -local variable 'target_frame_time' referenced before assignment -File "monitoring.py", line 318, in _print_performance_report -``` - -**原因**: -1. `target_frame_time`在第249行条件块内定义,但在第318行条件块外使用 -2. `pipeline_stats`仅在`enable_pipeline_monitoring=True`时定义,但在327-360行无条件使用 - -**解决方案**: -1. 第231行添加默认值: `target_frame_time = 13.9 # 默认目标帧时间(72Hz)` -2. 第327-360行包裹在条件检查中: `if self.enable_pipeline_monitoring:` - -**修复位置**: monitoring.py 第231行, 第327-360行 - -### 验证结果 -- ✅ 属性代理测试: 9/9 通过 (test_property_proxy.py) -- ✅ 集成测试: 7项全部通过 (test_performance_integration.py) -- ✅ 所有修复经过充分测试验证 - ---- - -## 🚀 后续工作 - -### 下一步: 阶段2 - 拆分测试调试系统 - -根据计划,阶段2将拆分测试调试系统 (~800行): - -**待迁移的功能**: -- 测试模式管理 (17个方法) -- 纹理管理 -- 显示系统 -- HUD系统 -- 性能测试 - -**预期文件**: `core/vr/testing/test_mode.py` - -**预期收益**: vr_manager.py再减少约700-800行 - ---- - -## ✨ 关键改进 - -1. **模块化**: 性能监控完全独立,便于维护和测试 -2. **代码质量**: vr_manager.py减少907行,更易阅读 -3. **可测试性**: 独立模块可单独测试 -4. **API稳定性**: 100%向后兼容,无需修改现有调用代码 -5. **文档完善**: 提供迁移文档和测试脚本 - ---- - -## 📝 经验总结 - -### 成功因素 -- ✅ 渐进式迁移,先分析后实施 -- ✅ 完整的备份策略 -- ✅ 委托模式保证API兼容性 -- ✅ 充分的测试验证 -- ✅ 清晰的文档记录 - -### 注意事项 -- ⚠️ 新模块略超900行,但功能完整 -- ⚠️ vr_manager.py仍然较大,需要继续拆分 -- ⚠️ 某些属性需要通过vr_manager访问 - -### 优化建议 -- 考虑进一步细分monitoring.py (如独立GPU计时模块) -- 继续执行阶段2-6的拆分计划 -- 最终目标: vr_manager.py < 900行 - ---- - -## ✅ 阶段1完成确认 - -- [x] 创建备份 -- [x] 创建目录结构 -- [x] 分析和提取代码 -- [x] 创建VRPerformanceMonitor类 -- [x] 集成到VRManager -- [x] 添加委托方法 -- [x] 编译检查通过 -- [x] 导入测试通过 -- [x] 集成测试通过 -- [x] 文档完善 - -**阶段1状态**: ✅ **圆满完成** - ---- - -**生成时间**: 2025-10-14 -**负责人**: Claude (Ultrathink模式) -**下一阶段**: 阶段2 - 测试调试系统拆分 diff --git a/STAGE2_COMPLETION_REPORT.md b/STAGE2_COMPLETION_REPORT.md deleted file mode 100644 index fc3943e4..00000000 --- a/STAGE2_COMPLETION_REPORT.md +++ /dev/null @@ -1,349 +0,0 @@ -# VR Manager 模块化拆分 - 阶段2完成报告 - -## 📋 任务概述 - -**阶段**: 阶段2 - 拆分测试调试系统 -**开始时间**: 2025-10-14 -**完成时间**: 2025-10-14 -**状态**: ✅ 已完成 - ---- - -## 🎯 完成的工作 - -### 1. 创建的文件 - -| 文件路径 | 行数 | 说明 | -|---------|------|------| -| `core/vr/testing/test_mode.py` | 621 | VR测试模式核心模块 | -| `core/vr/testing/__init__.py` | 已更新 | 模块导出接口 | -| `core/vr_manager.py.backup.stage2` | 3,829 | 阶段2开始前备份 | -| `test_test_mode_integration.py` | - | 集成测试脚本 | - -### 2. 修改的文件 - -| 文件路径 | 变化 | 说明 | -|---------|------|------| -| `core/vr/manager.py` | 3,829 → 3,630行 (-199行, 含新增代码) | 删除测试模式代码,添加委托方法和核心方法 | - -**注**: 实际删除634行测试代码,新增177行(108行委托+69行_batch_submit_textures),净减少457行 - ---- - -## 📊 代码统计 - -### 代码行数变化 -- **阶段1后 vr_manager.py**: 3,829行 ⚠️ (超标 4.25倍) -- **阶段2后 vr_manager.py**: 3,630行 ⚠️ (超标 4.03倍) -- **新增 test_mode.py**: 621行 ✅ (远低于800行目标,节省22.4%) -- **净减少**: 199行 (-5.2%) -- **累计减少** (阶段1+2): 1,106行 (-23.4%) - -### 迁移的内容 -- **迁移的方法**: 16个 (原计划17个,_batch_submit_textures保留在VRManager) -- **迁移的属性**: 15个 -- **委托方法**: 7个(保持API兼容) -- **属性代理**: 5个(保持API兼容) -- **保留的核心方法**: 1个 (_batch_submit_textures) - ---- - -## 🔧 技术实现 - -### 1. VRTestMode类结构 - -```python -class VRTestMode: - """VR测试模式系统 - - 功能模块: - - 测试模式控制 (3个方法) - - 纹理管理 (3个方法) - - 显示系统 (5个方法) - - HUD系统 (3个方法) - - 状态查询 (3个方法) - """ -``` - -### 2. 集成方式 - -**在VRManager中**: -```python -# 初始化测试调试系统 -self.test_mode = VRTestMode(self) - -# 委托方法示例 -def enable_vr_test_mode(self, display_mode='stereo'): - if self.test_mode: - return self.test_mode.enable_vr_test_mode(display_mode) -``` - -### 3. 属性代理 - -```python -@property -def vr_test_mode(self): - if self.test_mode: - return self.test_mode.vr_test_mode - return False - -@vr_test_mode.setter -def vr_test_mode(self, value): - if self.test_mode: - self.test_mode.vr_test_mode = value -``` - -### 4. 设计原则 - -- ✅ **组合优先于继承**: 通过组合模式集成子系统 -- ✅ **单一职责**: 测试调试功能独立管理 -- ✅ **向后兼容**: 100%保持现有API -- ✅ **松耦合**: 最小化模块间依赖 - ---- - -## ✅ 验证测试 - -### 1. 编译检查 -```bash -python3 -m py_compile core/vr/testing/test_mode.py ✅ -python3 -m py_compile core/vr_manager.py ✅ -``` - -### 2. 导入测试 -```bash -from core.vr.testing import VRTestMode ✅ -from core.vr_manager import VRManager ✅ -``` - -### 3. 集成测试 (7项测试) -- ✅ 模块导入正常 -- ✅ 类结构完整 (12个关键方法验证) -- ✅ 初始化成功 -- ✅ 状态查询方法正常 -- ✅ 配置方法正常 -- ✅ VRManager委托正常 -- ✅ HUD更新逻辑正常 - -**测试结果**: 全部通过 ✅ - ---- - -## 📦 迁移的功能模块 - -### 1. 测试模式控制 (3个方法) -- `enable_vr_test_mode` - 启用测试模式 -- `disable_vr_test_mode` - 禁用测试模式 -- `switch_test_display_mode` - 切换显示模式 - -### 2. 纹理管理 (2个方法) -- `_ensure_test_mode_textures` - 确保测试纹理 -- `_create_cached_ovr_textures` - 创建缓存的OVR纹理 -- **注**: `_batch_submit_textures`保留在VRManager作为核心渲染功能 - -### 3. 显示系统 (5个方法) -- `_initialize_test_display` - 初始化测试显示 -- `_update_test_display` - 更新测试显示 -- `_create_stereo_display` - 创建立体显示 -- `_cleanup_test_display` - 清理测试显示 - -### 4. HUD系统 (3个方法) -- `_initialize_test_performance_hud` - 初始化HUD -- `_update_test_performance_hud` - 更新HUD -- `_cleanup_test_performance_hud` - 清理HUD - -### 5. 状态查询 (3个方法) -- `get_test_mode_status` - 获取测试模式状态 -- `get_test_mode_features` - 获取测试模式特性 -- `set_test_mode_features` - 设置测试模式特性 - -### 6. 性能测试 (1个方法) -- `run_vr_performance_test` - 运行性能测试 - ---- - -## 🎯 目标达成情况 - -| 目标 | 计划 | 实际 | 状态 | -|-----|------|------|------| -| 迁移方法数 | 17个 | 16个 | ✅ (_batch_submit_textures保留) | -| 迁移属性数 | ~15个 | 15个 | ✅ | -| 新文件行数 | ~800行 | 621行 | ✅ 节省22.4% | -| vr_manager.py减少 | 预期减少 | -199行 (-5.2%) | ✅ | -| API兼容性 | 100% | 100% | ✅ | -| 测试通过率 | 100% | 100% | ✅ | - -**说明**: -- test_mode.py为621行,远低于800行目标,代码精简高效 -- vr_manager.py净减少199行(_batch_submit_textures保留导致减少量较少) - ---- - -## 📂 目录结构 - -``` -EG/ -├── core/ -│ ├── vr_manager.py (3,555行) ⬇️ -13.7% -│ └── vr/ -│ ├── performance/ -│ │ ├── __init__.py -│ │ └── monitoring.py (1,168行) ✨ -│ └── testing/ -│ ├── __init__.py ✨ -│ └── test_mode.py (688行) ✨ -├── test_test_mode_integration.py ✨ -├── STAGE2_COMPLETION_REPORT.md ✨ -└── VR_Manager 模块化拆分计划.md -``` - ---- - -## 🐛 修复的Bug - -在集成过程中发现并修复了以下问题: - -### Bug 1: _setup_vr_render_buffers() 方法不存在 - -**错误**: `_ensure_test_mode_textures()` 调用了不存在的方法 `_setup_vr_render_buffers()` - -**解决方案**: 替换为正确的方法调用: -```python -if hasattr(self.vr_manager.world, 'render_pipeline') and self.vr_manager.world.render_pipeline: - success = self.vr_manager._create_vr_buffers_with_pipeline() -else: - success = self.vr_manager._create_vr_buffers() -``` - -**修复位置**: test_mode.py 第209-212行 - -### Bug 2: _batch_submit_textures() 方法丢失 (运行时错误) - -**错误信息**: -``` -'VRManager' object has no attribute '_batch_submit_textures' -``` - -**根本原因**: -- `_batch_submit_textures`是VR渲染的核心方法,不仅用于测试模式 -- 错误地将它迁移到了VRTestMode类中 -- 导致正常VR渲染流程无法调用该方法 - -**解决方案**: -1. 将`_batch_submit_textures`方法重新添加到VRManager (vr_manager.py 3453-3521行) -2. 从VRTestMode中删除该方法,添加说明注释 -3. 修复渲染回调中的测试模式方法调用: - - `self._update_test_display()` → `self.test_mode._update_test_display()` - - `self._update_test_performance_hud()` → `self.test_mode._update_test_performance_hud()` - -**修复位置**: -- vr_manager.py 第1405行, 1475行, 3453-3521行 -- test_mode.py 第277-279行 - -**影响**: 这是关键修复,确保正常VR渲染和测试模式都能正常工作 - ---- - -## 🔄 Git状态 - -### 待提交的文件 -``` -修改: - core/vr_manager.py - core/vr/testing/__init__.py - -新增: - core/vr/testing/test_mode.py - test_test_mode_integration.py - STAGE2_COMPLETION_REPORT.md - -备份: - core/vr_manager.py.backup.stage2 -``` - -### 建议的提交信息 -``` -feat(vr): 模块化拆分阶段2 - 测试调试系统 - -- 创建独立的VRTestMode类 (688行) -- 迁移17个测试模式方法和15个属性 -- 添加7个委托方法和5个属性代理保持API兼容性 -- 修复_setup_vr_render_buffers()方法不存在的bug -- vr_manager.py从3,829行减少到3,555行 (-13.7%) -- 所有测试通过,100% API兼容 - -相关文档: -- STAGE2_COMPLETION_REPORT.md -``` - ---- - -## 🚀 后续工作 - -### 下一步: 阶段3 - 拆分对象池和优化系统 - -根据计划,阶段3将拆分对象池和优化系统 (~300行): - -**待迁移的功能**: -- 对象池管理 (19个方法) -- GC控制 -- 分辨率管理 -- 性能模式 - -**预期文件**: `core/vr/performance/optimization.py` - -**预期收益**: vr_manager.py再减少约250-300行 - ---- - -## ✨ 关键改进 - -1. **模块化**: 测试调试功能完全独立,便于维护和测试 -2. **代码质量**: vr_manager.py减少526行,更易阅读 -3. **可测试性**: 独立模块可单独测试 -4. **API稳定性**: 100%向后兼容,无需修改现有调用代码 -5. **Bug修复**: 发现并修复了方法不存在的bug - ---- - -## 📝 经验总结 - -### 成功因素 -- ✅ Agent工具高效提取代码 -- ✅ 完整的备份策略 -- ✅ 委托模式+属性代理保证API兼容性 -- ✅ 充分的测试验证 -- ✅ 清晰的文档记录 - -### 注意事项 -- ⚠️ 发现并修复了原代码中的bug (_setup_vr_render_buffers不存在) -- ⚠️ vr_manager.py仍然较大,需要继续拆分 -- ⚠️ 测试模式涉及渲染循环,集成时需要小心处理 - -### 优化建议 -- 继续执行阶段3-6的拆分计划 -- 最终目标: vr_manager.py < 900行 -- 考虑为test_mode添加更多单元测试 - ---- - -## ✅ 阶段2完成确认 - -- [x] 创建备份 -- [x] 创建目录结构 -- [x] 分析和提取代码 -- [x] 创建VRTestMode类 -- [x] 集成到VRManager -- [x] 添加委托方法和属性代理 -- [x] 编译检查通过 -- [x] 导入测试通过 -- [x] 集成测试通过 -- [x] 文档完善 - -**阶段2状态**: ✅ **圆满完成** - ---- - -**生成时间**: 2025-10-14 -**负责人**: Claude (Ultrathink模式) -**下一阶段**: 阶段3 - 对象池和优化系统拆分 diff --git a/core/vr/performance/optimization.py b/core/vr/performance/optimization.py new file mode 100644 index 00000000..42f5589a --- /dev/null +++ b/core/vr/performance/optimization.py @@ -0,0 +1,346 @@ +""" +VR对象池和优化系统 + +负责VR系统中的对象池管理、垃圾回收控制、分辨率缩放和性能模式控制。 +""" + +import gc +from panda3d.core import Mat4 + + +class VROptimization: + """VR优化系统 - 管理对象池、GC控制、分辨率缩放和性能模式""" + + def __init__(self, vr_manager): + """初始化VR优化系统 + + Args: + vr_manager: VR管理器实例引用 + """ + self.vr_manager = vr_manager + + # 对象池属性 + self._matrix_pool = [] # Mat4对象池 + self._matrix_pool_size = 8 # 池大小,足够处理多个控制器 + self._cached_matrices = {} # 设备ID到矩阵的缓存 + self._controller_poses_cache = {} # 控制器姿态缓存,避免每帧clear() + + # OpenVR Texture对象缓存 - 避免每帧创建openvr.Texture_t() + self._left_ovr_texture = None # 左眼纹理对象缓存 + self._right_ovr_texture = None # 右眼纹理对象缓存 + + # Python垃圾回收控制 + self._gc_control_enabled = True # 是否启用GC控制 + self._gc_disabled = False # GC是否被禁用 + self._manual_gc_interval = 900 # 每900帧手动触发一次GC (15秒@60fps) - 减少GC频率 + self._last_manual_gc_frame = 0 + + # VR分辨率缩放优化 + self.resolution_scale = 0.75 # 默认0.75倍分辨率,性能和质量平衡 + self.base_eye_width = 1080 # 原始推荐分辨率 + self.base_eye_height = 1200 + self.scaled_eye_width = 1080 # 实际使用的缩放后分辨率 + self.scaled_eye_height = 1200 + + # VR质量预设 + self.quality_presets = { + 'performance': 0.6, # 性能模式 - 约60%分辨率 + 'balanced': 0.75, # 平衡模式 - 约75%分辨率 + 'quality': 1.0 # 质量模式 - 100%分辨率 + } + self.current_quality_preset = 'balanced' # 默认平衡模式 + + # 性能模式控制 + self.performance_mode_enabled = False # 是否启用性能模式 + self.performance_mode_trigger_frame = 600 # 600帧后自动启用性能模式 + + def _initialize_object_pools(self): + """初始化对象池 - 修复16-19帧周期性GPU峰值""" + try: + # 预填充Mat4对象池 + for _ in range(self._matrix_pool_size): + self._matrix_pool.append(Mat4()) + + print(f"✅ Mat4对象池初始化完成 - 池大小: {self._matrix_pool_size}") + + # 🚀 预创建OpenVR Texture对象 - 消除每帧创建openvr.Texture_t()的开销 + try: + import openvr + self._left_ovr_texture = openvr.Texture_t() + self._right_ovr_texture = openvr.Texture_t() + + # 设置固定属性(这些不变) + self._left_ovr_texture.eType = openvr.TextureType_OpenGL + self._left_ovr_texture.eColorSpace = openvr.ColorSpace_Gamma + self._right_ovr_texture.eType = openvr.TextureType_OpenGL + self._right_ovr_texture.eColorSpace = openvr.ColorSpace_Gamma + + print("✅ OpenVR Texture对象缓存已创建 - 避免每帧创建新对象") + except Exception as texture_error: + print(f"⚠️ OpenVR Texture对象创建失败: {texture_error}") + # 不影响整体初始化,但性能可能不是最优 + + # 启用GC控制 + if self._gc_control_enabled: + # 禁用自动垃圾回收,改为手动控制 + gc.disable() + self._gc_disabled = True + print("✅ Python垃圾回收已禁用,改为手动控制") + + except Exception as e: + print(f"⚠️ 对象池初始化失败: {e}") + + def _get_pooled_matrix(self): + """从对象池获取Mat4对象""" + if self._matrix_pool: + return self._matrix_pool.pop() + else: + # 池为空时创建新对象(不应该发生,但作为备用) + return Mat4() + + def _return_pooled_matrix(self, matrix): + """将Mat4对象返回对象池""" + if len(self._matrix_pool) < self._matrix_pool_size: + # 重置矩阵到单位矩阵 + matrix.identMat() + self._matrix_pool.append(matrix) + + def _manual_gc_control(self): + """手动垃圾回收控制 - 避免VR渲染期间的GC峰值""" + if not self._gc_control_enabled or not self._gc_disabled: + return + + # 🚀 智能GC间隔:性能模式下减少GC频率 + current_interval = self._manual_gc_interval + if self.performance_mode_enabled: + current_interval = self._manual_gc_interval * 2 # 性能模式下间隔翻倍 + + # 每N帧手动触发一次垃圾回收 + if self.vr_manager.frame_count - self._last_manual_gc_frame >= current_interval: + # 在非渲染关键时刻触发GC + collected = gc.collect() + self._last_manual_gc_frame = self.vr_manager.frame_count + + # 仅在收集到对象时输出信息 + if collected > 0: + print(f"🗑️ 手动GC: 清理了 {collected} 个对象 (帧#{self.vr_manager.frame_count})") + + def enable_gc_control(self): + """启用垃圾回收控制 - 减少VR渲染期间的GC峰值""" + if not self._gc_control_enabled: + self._gc_control_enabled = True + if not self._gc_disabled: + gc.disable() + self._gc_disabled = True + print("✅ VR垃圾回收控制已启用") + else: + print("ℹ️ VR垃圾回收控制已经启用") + + def disable_gc_control(self): + """禁用垃圾回收控制 - 恢复自动垃圾回收""" + if self._gc_control_enabled: + self._gc_control_enabled = False + if self._gc_disabled: + gc.enable() + self._gc_disabled = False + print("✅ VR垃圾回收控制已禁用,恢复自动垃圾回收") + else: + print("ℹ️ VR垃圾回收控制已经禁用") + + def set_manual_gc_interval(self, frames): + """设置手动垃圾回收间隔 + + Args: + frames: 帧数间隔 (建议100-600) + """ + if 50 <= frames <= 1800: + old_interval = self._manual_gc_interval + self._manual_gc_interval = frames + print(f"✅ 手动GC间隔: {old_interval} → {frames} 帧") + else: + print("⚠️ GC间隔应在50-1800帧之间") + + def force_manual_gc(self): + """强制执行一次垃圾回收""" + collected = gc.collect() + print(f"🗑️ 强制GC: 清理了 {collected} 个对象") + return collected + + def get_object_pool_status(self): + """获取对象池状态""" + return { + 'matrix_pool_size': len(self._matrix_pool), + 'matrix_pool_capacity': self._matrix_pool_size, + 'cached_controllers': len(self.vr_manager.controller_poses), + 'cached_matrices': len(self._cached_matrices), + } + + # ====== VR分辨率缩放和质量预设系统 ====== + + def set_resolution_scale(self, scale): + """设置VR分辨率缩放系数 + + Args: + scale: 缩放系数 (0.3-1.0),0.75表示75%分辨率 + """ + if not (0.3 <= scale <= 1.0): + print(f"⚠️ 分辨率缩放系数应在0.3-1.0之间,当前: {scale}") + return False + + old_scale = self.resolution_scale + self.resolution_scale = scale + + # 如果VR已初始化,重新创建缓冲区 + if self.vr_manager.vr_initialized: + self._apply_resolution_scale() + + print(f"✓ VR分辨率缩放: {old_scale} → {scale}") + pixel_reduction = (1 - scale**2) * 100 + print(f"📊 像素减少: {pixel_reduction:.1f}%") + + return True + + def set_quality_preset(self, preset_name): + """设置VR质量预设 + + Args: + preset_name: 'performance', 'balanced', 'quality' + """ + if preset_name not in self.quality_presets: + print(f"⚠️ 未知的质量预设: {preset_name}") + print(f" 可用预设: {list(self.quality_presets.keys())}") + return False + + old_preset = self.current_quality_preset + self.current_quality_preset = preset_name + scale = self.quality_presets[preset_name] + + print(f"🎯 切换VR质量预设: {old_preset} → {preset_name}") + + return self.set_resolution_scale(scale) + + def cycle_quality_preset(self): + """循环切换质量预设""" + presets = list(self.quality_presets.keys()) + current_index = presets.index(self.current_quality_preset) + next_index = (current_index + 1) % len(presets) + next_preset = presets[next_index] + + return self.set_quality_preset(next_preset) + + def _apply_resolution_scale(self): + """应用分辨率缩放,重新创建VR缓冲区""" + try: + # 计算新的分辨率 + self.scaled_eye_width = int(self.base_eye_width * self.resolution_scale) + self.scaled_eye_height = int(self.base_eye_height * self.resolution_scale) + + # 更新当前分辨率 + self.vr_manager.eye_width = self.scaled_eye_width + self.vr_manager.eye_height = self.scaled_eye_height + if hasattr(self.vr_manager, 'current_eye_resolution'): + self.vr_manager.current_eye_resolution = (self.vr_manager.eye_width, self.vr_manager.eye_height) + + print(f"🔄 重新创建VR缓冲区...") + print(f" 新分辨率: {self.vr_manager.eye_width}x{self.vr_manager.eye_height}") + + # 清理旧的缓冲区 + self.vr_manager._cleanup_vr_buffers() + + # 🔧 关键修复:根据渲染模式选择创建方法 + success = False + if self.vr_manager.vr_render_mode.name == "RENDER_PIPELINE": + print(f" 使用RenderPipeline模式重建...") + success = self.vr_manager._create_vr_buffers_with_pipeline() + if not success: + print("⚠️ RenderPipeline模式创建失败,回退到普通渲染模式") + self.vr_manager.vr_render_mode = self.vr_manager.VRRenderMode.NORMAL + success = self.vr_manager._create_vr_buffers() + else: + print(f" 使用普通模式重建...") + success = self.vr_manager._create_vr_buffers() + + if success: + # 重新设置相机 + self.vr_manager._setup_vr_cameras() + print("✅ VR缓冲区重新创建成功") + return True + else: + print("❌ VR缓冲区重新创建失败") + return False + + except Exception as e: + print(f"❌ 应用分辨率缩放失败: {e}") + import traceback + traceback.print_exc() + return False + + def get_resolution_info(self): + """获取分辨率相关信息""" + return { + 'base_resolution': (self.base_eye_width, self.base_eye_height), + 'current_resolution': (self.vr_manager.eye_width, self.vr_manager.eye_height), + 'resolution_scale': self.resolution_scale, + 'current_preset': self.current_quality_preset, + 'available_presets': self.quality_presets, + 'pixel_reduction_percent': (1 - self.resolution_scale**2) * 100 + } + + def print_resolution_info(self): + """输出分辨率信息""" + info = self.get_resolution_info() + print("🔧 ===== VR分辨率信息 =====") + print(f" 推荐分辨率: {info['base_resolution'][0]}x{info['base_resolution'][1]}") + print(f" 当前分辨率: {info['current_resolution'][0]}x{info['current_resolution'][1]}") + print(f" 缩放系数: {info['resolution_scale']}") + print(f" 当前预设: {info['current_preset']}") + print(f" 像素减少: {info['pixel_reduction_percent']:.1f}%") + print(" 可用预设:") + for name, scale in info['available_presets'].items(): + marker = "✓" if name == info['current_preset'] else " " + print(f" {marker} {name}: {scale} ({scale*100:.0f}%)") + print("==========================") + + # ====== 性能模式控制方法 ====== + + def enable_performance_mode(self): + """手动启用性能模式 - 立即禁用详细监控以提升性能""" + if not self.performance_mode_enabled: + self.performance_mode_enabled = True + print("🎯 性能模式已手动启用 - 禁用详细监控以提升性能") + print(" 现在将减少每帧对象创建,显著提升VR性能稳定性") + else: + print("ℹ️ 性能模式已经启用") + + def disable_performance_mode(self): + """禁用性能模式 - 重新启用详细监控(用于调试)""" + if self.performance_mode_enabled: + self.performance_mode_enabled = False + print("🔍 性能模式已禁用 - 重新启用详细监控") + print(" 注意:这将增加每帧对象创建,可能影响VR性能") + else: + print("ℹ️ 性能模式已经禁用") + + def set_performance_mode_trigger_frame(self, frame_count): + """设置性能模式自动触发的帧数 + + Args: + frame_count: 触发帧数 (建议300-1200) + """ + if 100 <= frame_count <= 3600: + old_trigger = self.performance_mode_trigger_frame + self.performance_mode_trigger_frame = frame_count + print(f"✅ 性能模式触发帧数: {old_trigger} → {frame_count}") + else: + print("⚠️ 触发帧数应在100-3600之间") + + def get_performance_mode_status(self): + """获取性能模式状态""" + return { + 'performance_mode_enabled': self.performance_mode_enabled, + 'trigger_frame': self.performance_mode_trigger_frame, + 'current_frame': self.vr_manager.frame_count, + 'will_trigger_at_frame': self.performance_mode_trigger_frame if not self.performance_mode_enabled else None, + 'gc_interval_normal': self._manual_gc_interval, + 'gc_interval_performance': self._manual_gc_interval * 2, + } \ No newline at end of file diff --git a/core/vr_manager.py b/core/vr_manager.py index f12cdaa6..07c4e778 100644 --- a/core/vr_manager.py +++ b/core/vr_manager.py @@ -35,6 +35,7 @@ from core.vr.interaction.grab import VRInteractionManager from core.vr.interaction.joystick import VRJoystickManager from core.vr.interaction.teleport import VRTeleportSystem from core.vr.performance.monitoring import VRPerformanceMonitor +from core.vr.performance.optimization import VROptimization from core.vr.testing import VRTestMode from enum import Enum @@ -82,24 +83,15 @@ class VRManager(DirectObject): self.poses = None # OpenVR渲染姿态数组 self.game_poses = None # OpenVR游戏逻辑姿态数组 - # 🚀 对象池和缓存系统 - 修复16-19帧周期性GPU峰值 - self._matrix_pool = [] # Mat4对象池 - self._matrix_pool_size = 8 # 池大小,足够处理多个控制器 - self._cached_matrices = {} # 设备ID到矩阵的缓存 - self._controller_poses_cache = {} # 控制器姿态缓存,避免每帧clear() - - # 🚀 OpenVR Texture对象缓存 - 避免每帧创建openvr.Texture_t() - self._left_ovr_texture = None # 左眼纹理对象缓存 - self._right_ovr_texture = None # 右眼纹理对象缓存 - - # Python垃圾回收控制 - self._gc_control_enabled = True # 是否启用GC控制 - self._gc_disabled = False # GC是否被禁用 - self._manual_gc_interval = 900 # 每900帧手动触发一次GC (15秒@60fps) - 减少GC频率 - self._last_manual_gc_frame = 0 - # 🚀 立即初始化对象池和GC控制(在其他组件之前) - self._initialize_object_pools() + # 对象池和优化系统 - 模块化重构 + try: + self.optimization = VROptimization(self) + self.optimization._initialize_object_pools() + print("✓ VR对象池和优化系统初始化完成") + except Exception as e: + print(f"⚠️ VR对象池和优化系统初始化失败: {e}") + self.optimization = None # VR渲染参数 self.eye_width = 1080 @@ -107,7 +99,7 @@ class VRManager(DirectObject): self.near_clip = 0.1 self.far_clip = 1000.0 - # VR分辨率缩放优化 + # VR分辨率缩放优化 - 现在由优化模块管理 self.resolution_scale = 0.75 # 默认0.75倍分辨率,性能和质量平衡 self.base_eye_width = 1080 # 原始推荐分辨率 self.base_eye_height = 1200 @@ -250,103 +242,107 @@ class VRManager(DirectObject): print("✓ VR管理器初始化完成") - def _initialize_object_pools(self): - """初始化对象池 - 修复16-19帧周期性GPU峰值""" - try: - # 预填充Mat4对象池 - for _ in range(self._matrix_pool_size): - self._matrix_pool.append(Mat4()) + # ====== 对象池和优化系统委托方法 ====== - print(f"✅ Mat4对象池初始化完成 - 池大小: {self._matrix_pool_size}") + def enable_gc_control(self): + """启用垃圾回收控制 - 减少VR渲染期间的GC峰值""" + if self.optimization: + return self.optimization.enable_gc_control() + return False - # 🚀 预创建OpenVR Texture对象 - 消除每帧创建openvr.Texture_t()的开销 - try: - import openvr - self._left_ovr_texture = openvr.Texture_t() - self._right_ovr_texture = openvr.Texture_t() + def disable_gc_control(self): + """禁用垃圾回收控制 - 恢复自动垃圾回收""" + if self.optimization: + return self.optimization.disable_gc_control() + return False - # 设置固定属性(这些不变) - self._left_ovr_texture.eType = openvr.TextureType_OpenGL - self._left_ovr_texture.eColorSpace = openvr.ColorSpace_Gamma - self._right_ovr_texture.eType = openvr.TextureType_OpenGL - self._right_ovr_texture.eColorSpace = openvr.ColorSpace_Gamma + def set_manual_gc_interval(self, frames): + """设置手动垃圾回收间隔 - print("✅ OpenVR Texture对象缓存已创建 - 避免每帧创建新对象") - except Exception as texture_error: - print(f"⚠️ OpenVR Texture对象创建失败: {texture_error}") - # 不影响整体初始化,但性能可能不是最优 + Args: + frames: 帧数间隔 (建议100-600) + """ + if self.optimization: + return self.optimization.set_manual_gc_interval(frames) + return False - # 启用GC控制 - if self._gc_control_enabled: - # 禁用自动垃圾回收,改为手动控制 - gc.disable() - self._gc_disabled = True - print("✅ Python垃圾回收已禁用,改为手动控制") + def force_manual_gc(self): + """强制执行一次垃圾回收""" + if self.optimization: + return self.optimization.force_manual_gc() + return 0 - except Exception as e: - print(f"⚠️ 对象池初始化失败: {e}") + def get_object_pool_status(self): + """获取对象池状态""" + if self.optimization: + return self.optimization.get_object_pool_status() + return {} - def _get_pooled_matrix(self): - """从对象池获取Mat4对象""" - if self._matrix_pool: - return self._matrix_pool.pop() - else: - # 池为空时创建新对象(不应该发生,但作为备用) - return Mat4() + def set_resolution_scale(self, scale): + """设置VR分辨率缩放系数 - def _return_pooled_matrix(self, matrix): - """将Mat4对象返回对象池""" - if len(self._matrix_pool) < self._matrix_pool_size: - # 重置矩阵到单位矩阵 - matrix.identMat() - self._matrix_pool.append(matrix) + Args: + scale: 缩放系数 (0.3-1.0),0.75表示75%分辨率 + """ + if self.optimization: + return self.optimization.set_resolution_scale(scale) + return False - def _manual_gc_control(self): - """手动垃圾回收控制 - 避免VR渲染期间的GC峰值""" - if not self._gc_control_enabled or not self._gc_disabled: - return + def set_quality_preset(self, preset_name): + """设置VR质量预设 - # 🚀 智能GC间隔:性能模式下减少GC频率 - current_interval = self._manual_gc_interval - if self.performance_mode_enabled: - current_interval = self._manual_gc_interval * 2 # 性能模式下间隔翻倍 + Args: + preset_name: 'performance', 'balanced', 'quality' + """ + if self.optimization: + return self.optimization.set_quality_preset(preset_name) + return False - # 每N帧手动触发一次垃圾回收 - if self.frame_count - self._last_manual_gc_frame >= current_interval: - # 在非渲染关键时刻触发GC - collected = gc.collect() - self._last_manual_gc_frame = self.frame_count + def cycle_quality_preset(self): + """循环切换质量预设""" + if self.optimization: + return self.optimization.cycle_quality_preset() + return False - # 仅在收集到对象时输出信息 - if collected > 0: - print(f"🗑️ 手动GC: 清理了 {collected} 个对象 (帧#{self.frame_count})") + def get_resolution_info(self): + """获取分辨率相关信息""" + if self.optimization: + return self.optimization.get_resolution_info() + return {} - def _update_matrix_from_openvr(self, panda_mat, ovr_matrix): - """直接更新现有Mat4对象的数值,避免创建新对象""" - # 复用_convert_openvr_matrix_to_panda中的转换逻辑 - # X轴行:Panda3D的X轴对应OpenVR的X轴 - panda_mat.setCell(0, 0, ovr_matrix[0][0]) # X_x → X_x - panda_mat.setCell(0, 1, ovr_matrix[0][1]) # X_y → X_y - panda_mat.setCell(0, 2, ovr_matrix[0][2]) # X_z → X_z - panda_mat.setCell(0, 3, ovr_matrix[0][3]) # 位移X分量 + def print_resolution_info(self): + """输出分辨率信息""" + if self.optimization: + return self.optimization.print_resolution_info() - # Y轴行:Panda3D的Y轴对应OpenVR的-Z轴 - panda_mat.setCell(1, 0, -ovr_matrix[2][0]) # -Z_x → Y_x - panda_mat.setCell(1, 1, -ovr_matrix[2][1]) # -Z_y → Y_y - panda_mat.setCell(1, 2, -ovr_matrix[2][2]) # -Z_z → Y_z - panda_mat.setCell(1, 3, -ovr_matrix[2][3]) # 位移Y分量(-Z位移) + def enable_performance_mode(self): + """手动启用性能模式 - 立即禁用详细监控以提升性能""" + if self.optimization: + return self.optimization.enable_performance_mode() - # Z轴行:Panda3D的Z轴对应OpenVR的Y轴 - panda_mat.setCell(2, 0, ovr_matrix[1][0]) # Y_x → Z_x - panda_mat.setCell(2, 1, ovr_matrix[1][1]) # Y_y → Z_y - panda_mat.setCell(2, 2, ovr_matrix[1][2]) # Y_z → Z_z - panda_mat.setCell(2, 3, ovr_matrix[1][3]) # 位移Z分量(Y位移) + def disable_performance_mode(self): + """禁用性能模式 - 重新启用详细监控(用于调试)""" + if self.optimization: + return self.optimization.disable_performance_mode() - # 齐次坐标 - panda_mat.setCell(3, 0, 0) - panda_mat.setCell(3, 1, 0) - panda_mat.setCell(3, 2, 0) - panda_mat.setCell(3, 3, 1) + def set_performance_mode_trigger_frame(self, frame_count): + """设置性能模式自动触发的帧数 + + Args: + frame_count: 触发帧数 (建议300-1200) + """ + if self.optimization: + return self.optimization.set_performance_mode_trigger_frame(frame_count) + + def get_performance_mode_status(self): + """获取性能模式状态""" + if self.optimization: + return self.optimization.get_performance_mode_status() + return {} + + + + def convert_mat(self, mat): """ @@ -392,9 +388,11 @@ class VRManager(DirectObject): print("🔄 正在初始化VR系统...") # 🚀 确保对象池已正确初始化(备用检查) - if not hasattr(self, '_matrix_pool') or len(self._matrix_pool) == 0: - print("⚠️ 对象池未初始化,正在重新初始化...") - self._initialize_object_pools() + if self.optimization is None: + print("⚠️ 优化系统未初始化,正在重新初始化...") + from core.vr.performance.optimization import VROptimization + self.optimization = VROptimization(self) + self.optimization._initialize_object_pools() # 初始化OpenVR - 使用Scene应用类型确保正确的焦点管理 self.vr_system = openvr.init(openvr.VRApplication_Scene) @@ -1284,9 +1282,11 @@ class VRManager(DirectObject): self.frame_count += 1 # 🚀 自动启用性能模式 - 减少计时对象创建 - if not self.performance_mode_enabled and self.frame_count >= self.performance_mode_trigger_frame: - self.performance_mode_enabled = True - if self.frame_count <= self.performance_mode_trigger_frame + 5: # 只输出一次 + if (self.optimization and + not self.optimization.performance_mode_enabled and + self.frame_count >= self.optimization.performance_mode_trigger_frame): + self.optimization.performance_mode_enabled = True + if self.frame_count <= self.optimization.performance_mode_trigger_frame + 5: # 只输出一次 print(f"🎯 性能模式已启用 (帧#{self.frame_count}) - 禁用详细监控以提升性能") # 记录帧时间 @@ -1344,7 +1344,8 @@ class VRManager(DirectObject): self._get_gpu_frame_timing() # 🚀 手动垃圾回收控制 - 避免16-19帧周期性峰值 - self._manual_gc_control() + if self.optimization: + self.optimization._manual_gc_control() # 定期输出性能报告 - 默认10秒间隔 report_interval = getattr(self, 'performance_report_interval', 600) @@ -1580,7 +1581,8 @@ class VRManager(DirectObject): # 设备姿态无效,从字典中移除(如果存在) if device_id in self.controller_poses: # 将矩阵返回对象池 - self._return_pooled_matrix(self.controller_poses[device_id]) + if self.optimization: + self.optimization._return_pooled_matrix(self.controller_poses[device_id]) del self.controller_poses[device_id] # 🔧 关键修复:立即更新手柄和跟踪设备 @@ -1725,7 +1727,10 @@ class VRManager(DirectObject): OpenVR -Z → Panda3D Y """ # 🚀 使用对象池获取预分配的Mat4对象,避免每帧创建新对象 - mat = self._get_pooled_matrix() + if self.optimization: + mat = self.optimization._get_pooled_matrix() + else: + mat = Mat4() # 修正的坐标转换矩阵 # OpenVR: X右, Y上, -Z前 → Panda3D: X右, Y前, Z上 @@ -2130,33 +2135,33 @@ class VRManager(DirectObject): self.vr_task = None # 🚀 恢复Python垃圾回收并清理对象池 - if self._gc_disabled: + if self.optimization and self.optimization._gc_disabled: # 最后一次手动垃圾回收 collected = gc.collect() print(f"🗑️ 最终GC清理: {collected} 个对象") # 恢复自动垃圾回收 gc.enable() - self._gc_disabled = False + self.optimization._gc_disabled = False print("✅ Python垃圾回收已恢复为自动模式") # 清理对象池 - if hasattr(self, '_matrix_pool'): - pool_size = len(self._matrix_pool) - self._matrix_pool.clear() + if self.optimization and hasattr(self.optimization, '_matrix_pool'): + pool_size = len(self.optimization._matrix_pool) + self.optimization._matrix_pool.clear() print(f"🧹 Mat4对象池已清理: {pool_size} 个对象") # 清理缓存 - if hasattr(self, '_cached_matrices'): - self._cached_matrices.clear() - if hasattr(self, '_controller_poses_cache'): - self._controller_poses_cache.clear() + if self.optimization and hasattr(self.optimization, '_cached_matrices'): + self.optimization._cached_matrices.clear() + if self.optimization and hasattr(self.optimization, '_controller_poses_cache'): + self.optimization._controller_poses_cache.clear() # 清理OpenVR Texture对象缓存 - if hasattr(self, '_left_ovr_texture'): - self._left_ovr_texture = None - if hasattr(self, '_right_ovr_texture'): - self._right_ovr_texture = None + # 清理OpenVR Texture对象缓存 + if self.optimization: + self.optimization._left_ovr_texture = None + self.optimization._right_ovr_texture = None print("🧹 OpenVR Texture对象缓存已清理") # 清理渲染缓冲区 @@ -2328,9 +2333,9 @@ class VRManager(DirectObject): # 🚀 关键优化:使用缓存的OpenVR Texture对象,避免每帧创建 if eye == openvr.Eye_Left: - ovr_texture = self._left_ovr_texture + ovr_texture = self.optimization._left_ovr_texture if self.optimization else None else: - ovr_texture = self._right_ovr_texture + ovr_texture = self.optimization._right_ovr_texture if self.optimization else None # 检查缓存对象是否存在(向后兼容) if ovr_texture is None: @@ -2798,225 +2803,18 @@ class VRManager(DirectObject): self.disable_async_reprojection = False print("📝 异步重投影禁用选项已关闭,将使用默认ATW行为") - def enable_gc_control(self): - """启用垃圾回收控制 - 减少VR渲染期间的GC峰值""" - if not self._gc_control_enabled: - self._gc_control_enabled = True - if not self._gc_disabled: - gc.disable() - self._gc_disabled = True - print("✅ VR垃圾回收控制已启用") - else: - print("ℹ️ VR垃圾回收控制已经启用") - - def disable_gc_control(self): - """禁用垃圾回收控制 - 恢复自动垃圾回收""" - if self._gc_control_enabled: - self._gc_control_enabled = False - if self._gc_disabled: - gc.enable() - self._gc_disabled = False - print("✅ VR垃圾回收控制已禁用,恢复自动垃圾回收") - else: - print("ℹ️ VR垃圾回收控制已经禁用") - - def set_manual_gc_interval(self, frames): - """设置手动垃圾回收间隔 - - Args: - frames: 帧数间隔 (建议100-600) - """ - if 50 <= frames <= 1800: - old_interval = self._manual_gc_interval - self._manual_gc_interval = frames - print(f"✅ 手动GC间隔: {old_interval} → {frames} 帧") - else: - print("⚠️ GC间隔应在50-1800帧之间") - - def force_manual_gc(self): - """强制执行一次垃圾回收""" - collected = gc.collect() - print(f"🗑️ 强制GC: 清理了 {collected} 个对象") - return collected - - def get_object_pool_status(self): - """获取对象池状态""" - return { - 'matrix_pool_size': len(self._matrix_pool) if hasattr(self, '_matrix_pool') else 0, - 'matrix_pool_capacity': getattr(self, '_matrix_pool_size', 0), - 'cached_controllers': len(self.controller_poses), - 'cached_matrices': len(getattr(self, '_cached_matrices', {})), - } + # ====== VR分辨率缩放和质量预设系统 ====== - def set_resolution_scale(self, scale): - """设置VR分辨率缩放系数 - - Args: - scale: 缩放系数 (0.3-1.0),0.75表示75%分辨率 - """ - if not (0.3 <= scale <= 1.0): - print(f"⚠️ 分辨率缩放系数应在0.3-1.0之间,当前: {scale}") - return False - - old_scale = self.resolution_scale - self.resolution_scale = scale - - # 如果VR已初始化,重新创建缓冲区 - if self.vr_initialized: - self._apply_resolution_scale() - - print(f"✓ VR分辨率缩放: {old_scale} → {scale}") - pixel_reduction = (1 - scale**2) * 100 - print(f"📊 像素减少: {pixel_reduction:.1f}%") - - return True - - def set_quality_preset(self, preset_name): - """设置VR质量预设 - - Args: - preset_name: 'performance', 'balanced', 'quality' - """ - if preset_name not in self.quality_presets: - print(f"⚠️ 未知的质量预设: {preset_name}") - print(f" 可用预设: {list(self.quality_presets.keys())}") - return False - - old_preset = self.current_quality_preset - self.current_quality_preset = preset_name - scale = self.quality_presets[preset_name] - - print(f"🎯 切换VR质量预设: {old_preset} → {preset_name}") - - return self.set_resolution_scale(scale) - - def cycle_quality_preset(self): - """循环切换质量预设""" - presets = list(self.quality_presets.keys()) - current_index = presets.index(self.current_quality_preset) - next_index = (current_index + 1) % len(presets) - next_preset = presets[next_index] - - return self.set_quality_preset(next_preset) - - def _apply_resolution_scale(self): - """应用分辨率缩放,重新创建VR缓冲区""" - try: - # 计算新的分辨率 - self.scaled_eye_width = int(self.base_eye_width * self.resolution_scale) - self.scaled_eye_height = int(self.base_eye_height * self.resolution_scale) - - # 更新当前分辨率 - self.eye_width = self.scaled_eye_width - self.eye_height = self.scaled_eye_height - self.current_eye_resolution = (self.eye_width, self.eye_height) - - print(f"🔄 重新创建VR缓冲区...") - print(f" 新分辨率: {self.eye_width}x{self.eye_height}") - - # 清理旧的缓冲区 - self._cleanup_vr_buffers() - - # 🔧 关键修复:根据渲染模式选择创建方法 - success = False - if self.vr_render_mode == VRRenderMode.RENDER_PIPELINE: - print(f" 使用RenderPipeline模式重建...") - success = self._create_vr_buffers_with_pipeline() - if not success: - print("⚠️ RenderPipeline模式创建失败,回退到普通渲染模式") - self.vr_render_mode = VRRenderMode.NORMAL - success = self._create_vr_buffers() - else: - print(f" 使用普通模式重建...") - success = self._create_vr_buffers() - - if success: - # 重新设置相机 - self._setup_vr_cameras() - print("✅ VR缓冲区重新创建成功") - return True - else: - print("❌ VR缓冲区重新创建失败") - return False - - except Exception as e: - print(f"❌ 应用分辨率缩放失败: {e}") - import traceback - traceback.print_exc() - return False + - def get_resolution_info(self): - """获取分辨率相关信息""" - return { - 'base_resolution': (self.base_eye_width, self.base_eye_height), - 'current_resolution': (self.eye_width, self.eye_height), - 'resolution_scale': self.resolution_scale, - 'current_preset': self.current_quality_preset, - 'available_presets': self.quality_presets, - 'pixel_reduction_percent': (1 - self.resolution_scale**2) * 100 - } - - def print_resolution_info(self): - """输出分辨率信息""" - info = self.get_resolution_info() - print("🔧 ===== VR分辨率信息 =====") - print(f" 推荐分辨率: {info['base_resolution'][0]}x{info['base_resolution'][1]}") - print(f" 当前分辨率: {info['current_resolution'][0]}x{info['current_resolution'][1]}") - print(f" 缩放系数: {info['resolution_scale']}") - print(f" 当前预设: {info['current_preset']}") - print(f" 像素减少: {info['pixel_reduction_percent']:.1f}%") - print(" 可用预设:") - for name, scale in info['available_presets'].items(): - marker = "✓" if name == info['current_preset'] else " " - print(f" {marker} {name}: {scale} ({scale*100:.0f}%)") - print("==========================") + # ====== 性能模式控制方法 ====== - def enable_performance_mode(self): - """手动启用性能模式 - 立即禁用详细监控以提升性能""" - if not self.performance_mode_enabled: - self.performance_mode_enabled = True - print("🎯 性能模式已手动启用 - 禁用详细监控以提升性能") - print(" 现在将减少每帧对象创建,显著提升VR性能稳定性") - else: - print("ℹ️ 性能模式已经启用") - - def disable_performance_mode(self): - """禁用性能模式 - 重新启用详细监控(用于调试)""" - if self.performance_mode_enabled: - self.performance_mode_enabled = False - print("🔍 性能模式已禁用 - 重新启用详细监控") - print(" 注意:这将增加每帧对象创建,可能影响VR性能") - else: - print("ℹ️ 性能模式已经禁用") - - def set_performance_mode_trigger_frame(self, frame_count): - """设置性能模式自动触发的帧数 - - Args: - frame_count: 触发帧数 (建议300-1200) - """ - if 100 <= frame_count <= 3600: - old_trigger = self.performance_mode_trigger_frame - self.performance_mode_trigger_frame = frame_count - print(f"✅ 性能模式触发帧数: {old_trigger} → {frame_count}") - else: - print("⚠️ 触发帧数应在100-3600之间") - - def get_performance_mode_status(self): - """获取性能模式状态""" - return { - 'performance_mode_enabled': self.performance_mode_enabled, - 'trigger_frame': self.performance_mode_trigger_frame, - 'current_frame': self.frame_count, - 'will_trigger_at_frame': self.performance_mode_trigger_frame if not self.performance_mode_enabled else None, - 'gc_interval_normal': self._manual_gc_interval, - 'gc_interval_performance': self._manual_gc_interval * 2, - } + # ======================================================================== # 性能监控属性代理 - 属性级别的API向后兼容 @@ -3181,31 +2979,7 @@ class VRManager(DirectObject): if self.performance_monitor: self.performance_monitor.debug_output_enabled = value - @property - def performance_mode_enabled(self): - """性能模式开关 - 代理到性能监控系统""" - if self.performance_monitor: - return self.performance_monitor.performance_mode_enabled - return False - - @performance_mode_enabled.setter - def performance_mode_enabled(self, value): - """性能模式开关设置 - 代理到性能监控系统""" - if self.performance_monitor: - self.performance_monitor.performance_mode_enabled = value - - @property - def performance_mode_trigger_frame(self): - """性能模式触发帧 - 代理到性能监控系统""" - if self.performance_monitor: - return self.performance_monitor.performance_mode_trigger_frame - return 600 - - @performance_mode_trigger_frame.setter - def performance_mode_trigger_frame(self, value): - """性能模式触发帧设置 - 代理到性能监控系统""" - if self.performance_monitor: - self.performance_monitor.performance_mode_trigger_frame = value + # 时间监控属性 @property @@ -3261,6 +3035,128 @@ class VRManager(DirectObject): if self.performance_monitor: self.performance_monitor.enable_pipeline_monitoring = value + @property + def performance_mode_enabled(self): + """性能模式开关 - 代理到优化模块""" + if self.optimization: + return self.optimization.performance_mode_enabled + return False + + @performance_mode_enabled.setter + def performance_mode_enabled(self, value): + """性能模式开关设置 - 代理到优化模块""" + if self.optimization: + self.optimization.performance_mode_enabled = value + + @property + def performance_mode_trigger_frame(self): + """性能模式触发帧 - 代理到优化模块""" + if self.optimization: + return self.optimization.performance_mode_trigger_frame + return 600 + + @performance_mode_trigger_frame.setter + def performance_mode_trigger_frame(self, value): + """性能模式触发帧设置 - 代理到优化模块""" + if self.optimization: + self.optimization.performance_mode_trigger_frame = value + + # 分辨率缩放属性代理 + @property + def resolution_scale(self): + """分辨率缩放系数 - 代理到优化模块""" + if self.optimization: + return self.optimization.resolution_scale + return 0.75 + + @resolution_scale.setter + def resolution_scale(self, value): + """分辨率缩放系数设置 - 代理到优化模块""" + if self.optimization: + self.optimization.resolution_scale = value + + @property + def base_eye_width(self): + """基础眼宽 - 代理到优化模块""" + if self.optimization: + return self.optimization.base_eye_width + return 1080 + + @base_eye_width.setter + def base_eye_width(self, value): + """基础眼宽设置 - 代理到优化模块""" + if self.optimization: + self.optimization.base_eye_width = value + + @property + def base_eye_height(self): + """基础眼高 - 代理到优化模块""" + if self.optimization: + return self.optimization.base_eye_height + return 1200 + + @base_eye_height.setter + def base_eye_height(self, value): + """基础眼高设置 - 代理到优化模块""" + if self.optimization: + self.optimization.base_eye_height = value + + @property + def scaled_eye_width(self): + """缩放后眼宽 - 代理到优化模块""" + if self.optimization: + return self.optimization.scaled_eye_width + return 1080 + + @scaled_eye_width.setter + def scaled_eye_width(self, value): + """缩放后眼宽设置 - 代理到优化模块""" + if self.optimization: + self.optimization.scaled_eye_width = value + + @property + def scaled_eye_height(self): + """缩放后眼高 - 代理到优化模块""" + if self.optimization: + return self.optimization.scaled_eye_height + return 1200 + + @scaled_eye_height.setter + def scaled_eye_height(self, value): + """缩放后眼高设置 - 代理到优化模块""" + if self.optimization: + self.optimization.scaled_eye_height = value + + @property + def current_quality_preset(self): + """当前质量预设 - 代理到优化模块""" + if self.optimization: + return self.optimization.current_quality_preset + return "balanced" + + @current_quality_preset.setter + def current_quality_preset(self, value): + """当前质量预设设置 - 代理到优化模块""" + if self.optimization: + self.optimization.current_quality_preset = value + + @property + def quality_presets(self): + """质量预设 - 代理到优化模块""" + if self.optimization: + return self.optimization.quality_presets + return { + "performance": 0.6, + "balanced": 0.75, + "quality": 1.0 + } + + @quality_presets.setter + def quality_presets(self, value): + """质量预设设置 - 代理到优化模块""" + if self.optimization: + self.optimization.quality_presets = value + # ======================================================================== # 性能监控委托方法 - API向后兼容层 # ======================================================================== diff --git a/test_test_mode_integration.py b/test_test_mode_integration.py deleted file mode 100644 index 9149dc08..00000000 --- a/test_test_mode_integration.py +++ /dev/null @@ -1,200 +0,0 @@ -""" -测试VRTestMode集成测试 -验证测试模式系统是否正确集成到VRManager -""" - -print("=" * 60) -print("VR测试模式系统集成测试") -print("=" * 60) - -# 测试1: 导入VRTestMode -print("\n测试1: 导入VRTestMode...") -try: - from core.vr.testing import VRTestMode - print("✓ VRTestMode导入成功") -except Exception as e: - print(f"✗ VRTestMode导入失败: {e}") - exit(1) - -# 测试2: 检查VRTestMode类结构 -print("\n测试2: 检查VRTestMode类结构...") -try: - # 检查关键方法是否存在 - required_methods = [ - 'enable_vr_test_mode', - 'disable_vr_test_mode', - 'switch_test_display_mode', - 'get_test_mode_status', - 'set_test_mode_features', - 'get_test_mode_features', - 'run_vr_performance_test', - '_ensure_test_mode_textures', - '_initialize_test_display', - '_update_test_display', - '_initialize_test_performance_hud', - '_update_test_performance_hud' - ] - - missing_methods = [] - for method in required_methods: - if not hasattr(VRTestMode, method): - missing_methods.append(method) - - if missing_methods: - print(f"✗ 缺少方法: {missing_methods}") - exit(1) - - print(f"✓ 所有{len(required_methods)}个关键方法都存在") -except Exception as e: - print(f"✗ 类结构检查失败: {e}") - exit(1) - -# 测试3: 初始化VRTestMode -print("\n测试3: 初始化VRTestMode...") -try: - from unittest.mock import Mock - - # 创建模拟的VRManager - mock_vr_manager = Mock() - mock_vr_manager.world = Mock() - mock_vr_manager.world.render2d = Mock() - mock_vr_manager.vr_initialized = False - mock_vr_manager.vr_enabled = False - - # 创建VRTestMode实例 - test_mode = VRTestMode(mock_vr_manager) - - # 检查核心属性是否正确初始化 - assert test_mode.vr_test_mode == False, "vr_test_mode应该初始化为False" - assert test_mode.test_display_mode == 'stereo', "test_display_mode应该初始化为stereo" - assert test_mode.test_mode_initialized == False, "test_mode_initialized应该初始化为False" - assert test_mode.test_mode_submit_texture == False, "test_mode_submit_texture应该初始化为False" - assert test_mode.test_mode_wait_poses == False, "test_mode_wait_poses应该初始化为False" - - print("✓ VRTestMode初始化成功") - print("✓ 核心属性初始化正确") -except Exception as e: - print(f"✗ VRTestMode初始化失败: {e}") - import traceback - traceback.print_exc() - exit(1) - -# 测试4: 测试状态查询方法 -print("\n测试4: 测试状态查询方法...") -try: - # get_test_mode_status() - 未启用时应返回None - status = test_mode.get_test_mode_status() - assert status is None, "未启用测试模式时应返回None" - print("✓ get_test_mode_status() 返回正确") - - # get_test_mode_features() - features = test_mode.get_test_mode_features() - assert isinstance(features, dict), "应返回字典" - assert 'submit_texture' in features, "应包含submit_texture" - assert 'wait_poses' in features, "应包含wait_poses" - assert 'test_mode_active' in features, "应包含test_mode_active" - print("✓ get_test_mode_features() 返回正确格式") - -except Exception as e: - print(f"✗ 状态查询测试失败: {e}") - import traceback - traceback.print_exc() - exit(1) - -# 测试5: 测试配置方法 -print("\n测试5: 测试配置方法...") -try: - # set_test_mode_features() - test_mode.set_test_mode_features(submit_texture=True, wait_poses=True) - assert test_mode.test_mode_submit_texture == True - assert test_mode.test_mode_wait_poses == True - print("✓ set_test_mode_features() 正常工作") - - # 恢复默认值 - test_mode.set_test_mode_features(submit_texture=False, wait_poses=False) - assert test_mode.test_mode_submit_texture == False - assert test_mode.test_mode_wait_poses == False - print("✓ 配置状态正确更新") - -except Exception as e: - print(f"✗ 配置方法测试失败: {e}") - import traceback - traceback.print_exc() - exit(1) - -# 测试6: 测试与VRManager的委托 -print("\n测试6: 测试VRManager委托...") -try: - # 尝试导入VRManager并检查委托方法 - # 注意: 这里不实际启动VRManager,只检查方法存在性 - print(" 检查VRManager导入...") - from core.vr_manager import VRManager - print(" ✓ VRManager导入成功") - - # 检查委托方法是否存在 - delegate_methods = [ - 'enable_vr_test_mode', - 'disable_vr_test_mode', - 'switch_test_display_mode', - 'get_test_mode_status', - 'get_test_mode_features', - 'set_test_mode_features', - 'run_vr_performance_test' - ] - - for method in delegate_methods: - if not hasattr(VRManager, method): - print(f" ✗ VRManager缺少委托方法: {method}") - exit(1) - - print(f" ✓ 所有{len(delegate_methods)}个委托方法都存在") - - # 检查属性代理 - delegate_properties = [ - 'vr_test_mode', - 'test_display_mode', - 'test_mode_submit_texture', - 'test_mode_wait_poses', - 'test_mode_initialized' - ] - - # 注意: 这里只能检查类定义,不能检查实例属性 - print(f" ✓ 属性代理定义已检查") - -except Exception as e: - print(f"✗ VRManager委托测试失败: {e}") - import traceback - traceback.print_exc() - exit(1) - -# 测试7: 测试HUD更新计数器 -print("\n测试7: 测试HUD更新逻辑...") -try: - # 测试HUD更新计数器 - initial_counter = test_mode.hud_update_counter - assert initial_counter == 0, "初始计数器应该为0" - - # 测试HUD更新间隔 - assert test_mode.hud_update_interval == 30, "HUD更新间隔应该为30帧" - - print("✓ HUD更新逻辑初始化正确") - -except Exception as e: - print(f"✗ HUD更新测试失败: {e}") - import traceback - traceback.print_exc() - exit(1) - -print("\n" + "=" * 60) -print("✅ 所有测试通过!") -print("=" * 60) - -print("\n测试总结:") -print(" ✓ 模块导入正常") -print(" ✓ 类结构完整") -print(" ✓ 初始化成功") -print(" ✓ 状态查询方法正常") -print(" ✓ 配置方法正常") -print(" ✓ VRManager委托正常") -print(" ✓ HUD更新逻辑正常") -print("\nVRTestMode集成完成,准备投入使用!")