# XCEngine Editor 设计分析与改进计划 ## 1. 项目概述 ### 1.1 当前状态 XCEngine Editor 是一个基于 ImGui 的 Unity 风格编辑器 UI,目前具备以下基础功能: - **渲染基础**: DirectX 12 + ImGui 对接 - **面板框架**: Docking 布局系统 - **UI 主题**: Unity 风格深色主题 ### 1.2 对比参考 参考项目 Fermion Boson Editor 是一个功能完整的游戏引擎编辑器,具有: - 完整的 3D Viewport - 场景层级系统 - 组件检查器 - 资源浏览器 - 材质编辑器 - Play/Edit/Simulate 模式切换 --- ## 2. 整体架构对比 ### 2.1 架构图 **Fermion 架构**: ``` Fermion::Application └── LayerStack ├── ImGuiLayer (overlay) └── BosonLayer (editor layer) ├── ViewportPanel (3D viewport + gizmos) ├── SceneHierarchyPanel (entity tree) │ └── InspectorPanel (embedded, component editor) ├── ContentBrowserPanel (asset browser) ├── MaterialEditorPanel (node-based material) ├── SettingsPanel (editor settings) ├── OverlayRenderPanel (physics debug) └── MenuBarPanel (menu bar) ``` **XCEngine 架构**: ``` UI::Application └── Panels (独立 Panel 类) ├── MenuBar ├── HierarchyPanel ├── InspectorPanel ├── SceneViewPanel (占位符) ├── GameViewPanel (占位符) ├── ProjectPanel └── ConsolePanel ``` ### 2.2 关键差异 | 方面 | Fermion | XCEngine | |------|---------|----------| | Layer 系统 | Application → LayerStack → BosonLayer | Application 直接管理 Panels | | Panel 集成 | SceneHierarchy 内嵌 InspectorPanel | 各 Panel 独立 | | Scene 管理 | BosonLayer 持有 Scene/SceneRenderer | SceneManager 单例 | | 渲染集成 | BosonLayer → SceneRenderer → Framebuffer | 无对接 | | 事件系统 | Layer::onEvent 统一分发 | 各 Panel 独立处理 | --- ## 3. 各面板详细分析 ### 3.1 SceneHierarchyPanel / HierarchyPanel #### 功能对比 | 功能 | Fermion | XCEngine | 状态 | |------|---------|----------|------| | 树节点渲染 | ✅ `TreeNodeEx` + UUID | ✅ `TreeNodeEx` + EntityID | 完成 | | 选中高亮 | ✅ | ✅ | 完成 | | 展开/折叠 | ✅ 自动记忆状态 | ✅ `isOpen` 状态 | 完成 | | 重命名 | ✅ 双击触发 | ⚠️ 有 bug | 需修复 | | 拖拽重排 | ✅ 完整 + 循环检测 | ⚠️ 基本实现 | 需完善 | | 右键菜单 | ✅ Create Child, Detach, Delete | ✅ Create, Rename, Delete, Copy/Paste, Duplicate | 需补充 | | 空区域点击 | ✅ 取消选中 | ✅ 取消选中 | 完成 | | 嵌入 Inspector | ✅ Panel 内嵌 InspectorPanel | ❌ 分离 | 架构差异 | #### XCEngine 问题详解 **问题 1: 重命名逻辑 bug** `HierarchyPanel.cpp` lines 106-113: ```cpp if (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0)) { if (strlen(m_renameBuffer) > 0) { sceneManager.RenameEntity(id, m_renameBuffer); } m_renaming = false; m_renamingEntity = INVALID_ENTITY_ID; } ``` 问题:点击 InputText 外部时,`IsItemActive()` 已经变为 false,此时 `IsMouseClicked(0)` 也已经错过。 **问题 2: 缺少 "Create Child" 选项** 右键菜单只有: - Create → Empty Object, Camera, Light, Cube, Sphere, Plane - Rename, Delete - Copy, Paste, Duplicate 缺少 "Create Child" 选项来在选中物体下创建子物体。 **问题 3: 没有 "Detach from Parent" 选项** 无法将子物体脱离父物体,直接变为根层级。 --- ### 3.2 InspectorPanel #### 功能对比 | 功能 | Fermion (1173 行) | XCEngine (94 行) | 状态 | |------|-------------------|------------------|------| | 组件显示 | ✅ 模板系统 | ⚠️ 只实现 2 种组件 (Engine 有完整组件库) | 需完善 | | 动态增删组件 | ✅ 分类菜单 | ❌ 无 | 需实现 | | 删除组件 | ✅ 右键 Remove | ❌ 无 | 需实现 | | Transform 编辑 | ✅ `drawVec3Control` | ⚠️ `DragFloat3` 简陋 | 需改进 | | Mesh 编辑 | ✅ Drag-drop + popup | ⚠️ 只有 InputText | 需改进 | | 材质预览 | ✅ 缩略图渲染 | ❌ 无 | 需实现 | | Camera 编辑 | ✅ 完整 | ❌ 无 | 需实现 | | Light 编辑 | ✅ D/P/S Light | ❌ 无 | 需实现 | | Physics 编辑 | ✅ 完整 | ❌ 无 | 需实现 | | Script 编辑 | ✅ 字段编辑 | ❌ 无 | 需实现 | | Entity Picking | ✅ 关节连接 | ❌ 无 | 需实现 | #### XCEngine 实现现状 `InspectorPanel.cpp` lines 44-92: ```cpp void InspectorPanel::RenderComponent(Component* component) { if (auto* transform = dynamic_cast(component)) { ImGui::DragFloat3("##Position", transform->position, 0.1f); ImGui::DragFloat3("##Rotation", transform->rotation, 1.0f); ImGui::DragFloat3("##Scale", transform->scale, 0.1f); } else if (auto* meshRenderer = dynamic_cast(component)) { // 只有 InputText,没有预览,没有拖拽 } } ``` **主要问题**: 1. Editor Inspector 面板只实现了 Transform 和 MeshRenderer 显示编辑,但 Engine 核心已有完整组件系统 2. 没有 Add Component 菜单 3. 没有 Remove Component 功能 4. 没有 CollapsingHeader 折叠 5. 布局简陋,没有缩进和对齐 --- ### 3.3 ProjectPanel / ContentBrowserPanel #### 功能对比 | 功能 | Fermion | XCEngine | 状态 | |------|---------|----------|------| | 布局 | ✅ 两列 (树 + 网格) | ⚠️ 只有网格 | 需补充 | | 文件夹树 | ✅ 左侧导航树 | ❌ 无 | 需实现 | | 缩略图 | ✅ 加载 Texture | ⚠️ 彩色方块 | 需改进 | | 材质预览 | ✅ 缩略图渲染 | ❌ 无 | 需实现 | | 拖拽移动 | ✅ 完整实现 | ⚠️ stubbed | 需修复 | | 双击打开 | ✅ 打开文件夹 | ✅ 实现 | 完成 | | 面包屑导航 | ✅ 路径按钮 | ✅ 实现 | 完成 | | 搜索过滤 | ✅ 实现 | ✅ 实现 | 完成 | #### XCEngine 问题详解 **问题: HandleDrop() 返回 false** `ProjectPanel.cpp` line 294: ```cpp bool ProjectPanel::HandleDrop(const AssetItemPtr& targetFolder) { return false; // STUBBED OUT - 拖拽移动功能不工作 } ``` 虽然 `RenderAssetItem()` 中有拖拽目标代码,但实际上 `HandleDrop()` 从未被调用,拖拽移动功能完全失效。 --- ### 3.4 MenuBar #### 功能对比 | 功能 | Fermion (271 行) | XCEngine (55 行) | 状态 | |------|------------------|-------------------|------| | 实现方式 | ✅ 自定义窗口边框 | ✅ `BeginMainMenuBar` | 完成 | | 菜单项 | ✅ 实际回调 | ❌ **全部 stubbed** | 需实现 | | 项目操作 | ✅ new/open/save | ❌ 无 | 需实现 | | 创建菜单 | ✅ Material/Texture | ❌ 无 | 需实现 | | 窗口控制 | ✅ 有 (已注释) | ❌ 无 | 可选 | #### XCEngine 问题详解 **所有菜单项都是空的**: ```cpp // MenuBar.cpp if (ImGui::MenuItem("New Scene", "Ctrl+N")) {} // 空 if (ImGui::MenuItem("Open Scene", "Ctrl+O")) {} // 空 if (ImGui::MenuItem("Save Scene", "Ctrl+S")) {} // 空 // ... 所有项都是空的 ``` --- ### 3.5 ConsolePanel #### 功能对比 | 功能 | Fermion (84 行) | XCEngine (70 行) | 状态 | |------|------------------|-------------------|------| | 日志显示 | ✅ 彩色 + 前缀 | ✅ 彩色 + 前缀 | 完成 | | 命令输入 | ✅ 底部输入框 | ❌ 无 | 需补充 | | 命令处理 | ✅ clear/help | ❌ 无 | 需实现 | | 自动滚动 | ✅ 新日志时滚动 | ⚠️ flag 设置但逻辑不完整 | 需改进 | #### XCEngine 优点 - 测试按钮注入日志功能完善 - 日志级别颜色区分正确 - 基本显示功能正常 --- ### 3.6 SceneViewPanel / ViewportPanel #### 功能对比 | 功能 | Fermion (356 行) | XCEngine (54 行) | 状态 | |------|------------------|-------------------|------| | 3D 渲染 | ✅ Framebuffer | ❌ **只有网格** | 需重构 | | 相机 | ✅ EditorCamera | ❌ 无 | 需实现 | | 鼠标拾取 | ✅ readPixel | ❌ 无 | 需实现 | | Gizmo | ✅ ImGuizmo | ❌ 无 | 需实现 | | 工具栏 | ✅ Q/W/E/R | ❌ 无 | 需实现 | | Play 控制 | ✅ Play/Stop/Pause/Step | ❌ 无 | 需实现 | | 状态切换 | ✅ Edit/Play/Simulate | ❌ 无 | 需实现 | #### XCEngine 实现现状 ```cpp // SceneViewPanel.cpp void SceneViewPanel::RenderGrid() { // 只画了 50px 网格背景 for (float x = 0; x < canvasSize.x; x += gridSize) { drawList->AddLine(...); } // 没有任何 3D 渲染 } ``` **问题**: 完全没有任何 3D 渲染能力,只是占位符。 --- ### 3.7 GameViewPanel | 功能 | Fermion | XCEngine | 状态 | |------|---------|----------|------| | 游戏视图 | ✅ Framebuffer 渲染 | ❌ **纯占位符** | 需重构 | | 状态栏 | ✅ Play/Simulate 指示 | ❌ 无 | 需实现 | --- ## 4. XCEngine 缺失的面板 XCEngine Editor 只有 7 个面板,而 Fermion 有 10 个。以下是缺失的面板: ### 4.1 SettingsPanel - 编辑器设置 **Fermion 功能**: - Renderer Info: 相机设置、设备信息、帧时间统计 - Environment Settings: Skybox、阴影、IBL、HDR 加载、环境光强度、法线强度 - Debug Settings: 渲染模式 (Forward/Deferred Hybrid)、GBuffer 调试、深度视图、物理调试开关、无限网格、轮廓设置 - Project Settings: 项目信息、默认字体配置 **XCEngine 状态**: 无此面板 **实现建议**: 可以作为 InspectorPanel 的扩展,或者单独的设置浮窗 --- ### 4.2 OverlayRenderPanel - 调试可视化 **Fermion 功能**: ```cpp class OverlayRenderPanel { void render(const Context &ctx) const; void renderPhysicsColliders(); // 物理碰撞体可视化 void renderPhysics2DColliders(); // 2D 碰撞体 void renderPhysics3DColliders(); // 3D 碰撞体 void renderJoints(); // 关节连接可视化 void renderSelectedEntityOutline(); // 选中物体轮廓 }; ``` **功能说明**: - 在 Viewport 上叠加渲染物理调试信息 - 2D 碰撞体: Box、Circle、BoxSensor、CircleSensor - 3D 碰撞体: Box、Sphere、Capsule、Mesh (三角形线框) - 关节: RevoluteJoint (锚点圆)、DistanceJoint (锚点圆 + 线段) - 选中物体白色轮廓 **XCEngine 状态**: 无此面板,但可以在 SceneViewPanel 完善后添加 --- ### 4.3 MaterialEditorPanel - 材质编辑器 **Fermion 功能**: - 基于 `ax::NodeEditor` (imnodes) 的节点式材质编辑器 - PBR Output 节点 (ID=1) 固定在右侧 - Texture 节点可动态创建 - 引脚连接系统 (Pin ID 约定: `nodeID*100 + pinIndex`) - 材质预览渲染 (`MaterialPreviewRenderer`) - 材质编译 (`compileMaterial()`) **节点系统**: ```cpp // PBR Output 节点输入引脚 enum PBRInputPin { Albedo = 1, // 引脚 ID = 101 Normal = 2, // 引脚 ID = 102 Metallic = 3, // 引脚 ID = 103 Roughness = 4,// 引脚 ID = 104 AO = 5 // 引脚 ID = 105 }; // Texture 节点输出引脚 // 引脚 ID = nodeID * 100 + 1 ``` **UI 布局**: ``` ┌─────────────────────────────────────────────────────┐ │ [Texture Node] ──────→ [Albedo] │ │ [Texture Node] ──────→ [Normal] │ │ [Texture Node] ──────→ [PBR Output] → [Material] │ │ → [Metallic] │ │ → [Roughness] │ │ → [AO] │ └─────────────────────────────────────────────────────┘ ``` **XCEngine 状态**: 无此面板,需要独立开发 **实现难度**: 高,需要 imnodes 库集成和材质编译系统 --- ### 4.4 TextureConfigPanel - 纹理配置 **Fermion 功能**: ```cpp class TextureConfigPanel { void loadTexture(const std::filesystem::path &ftexPath); void loadTextures(const vector &ftexPaths); void saveTexture(TextureConfigData &data); void saveAllTextures(); struct TextureConfigData { std::filesystem::path FtexPath; std::string Name; TextureAssetSpecification Spec; bool Modified = false; }; bool m_BatchMode = false; // 批量配置模式 TextureAssetSpecification m_BatchSpec; }; ``` **功能**: - 批量纹理加载 - 纹理规格编辑 (格式、过滤器、Mipmaps 等) - 保存/导出功能 **XCEngine 状态**: 无此面板,ProjectPanel 只做文件浏览 --- ### 4.5 AssetManagerPanel - 资源注册表 **Fermion 功能**: ```cpp class AssetManagerPanel { void onImGuiRender(); // 显示所有注册的资源 // 可搜索、可过滤 // Asset 类型过滤 // Load/Unload 按钮 // 显示: asset path, type, handle ID, loading status }; ``` **功能**: - 查看所有已注册资产 - 按类型过滤 (Texture, Mesh, Material, etc.) - 搜索功能 - 手动加载/卸载资产 - 显示资源路径、类型、句柄 ID、加载状态 **XCEngine 状态**: 无此面板,ProjectPanel 只做文件系统浏览 --- ## 5. 核心系统差异分析 ### 5.1 Application 架构对比 **Fermion Application**: ```cpp class Application { std::unique_ptr m_window; std::unique_ptr m_imGuiLayer; std::unique_ptr m_layerStack; void pushLayer(std::unique_ptr layer); // 在 ImGui 之前更新 void pushOverlay(std::unique_ptr overlay); // 在 ImGui 之后更新 }; ``` **XCEngine Application**: ```cpp class Application { HWND m_hwnd; ID3D12Device* m_device; // 直接管理所有 Panels std::unique_ptr m_menuBar; std::unique_ptr m_hierarchyPanel; // ... }; ``` **关键差异**: 1. Fermion 使用 Layer/Overlay 模式,事件按倒序传播 2. XCEngine 直接管理 Panels,缺乏层次化设计 3. Fermion 有 ImGuiLayer 专门处理 ImGui 事件阻塞 4. XCEngine 需要手动在 Panel 内部处理焦点判断 --- ### 5.2 SceneManager vs Scene/EntityManager **XCEngine SceneManager**: ```cpp class SceneManager { std::unordered_map m_entities; std::vector m_rootEntities; EntityID CreateEntity(name, parent); void DeleteEntity(id); void MoveEntity(id, newParent); EntityID CopyEntity(id); EntityID PasteEntity(parent); }; ``` **Fermion Scene + EntityManager**: ```cpp class Scene { std::unique_ptr m_entityManager; std::unique_ptr m_physicsWorld2D; std::unique_ptr m_physicsWorld3D; }; class EntityManager { entt::registry m_registry; // EnTT ECS std::unordered_map m_entityMap; }; ``` **XCEngine 实际情况**: 1. ✅ 有 Scene 类和 SceneManager (见 engine/include/XCEngine/Scene/) 2. ❌ 没有物理世界集成 3. ✅ 有 Component/GameObject 系统,但非 EnTT ECS (使用 dynamic_cast) 4. ✅ EntityID 是 uint64_t 递增整数,不是 UUID 5. ❌ Editor 没有场景状态 (Edit/Play/Simulate) 切换机制 --- ### 5.3 BosonUI 自定义控件 Fermion 定义了 `ui` 命名空间的自定义控件,XCEngine 没有: **Fermion ui 控件**: ```cpp namespace ui { // 向量编辑器 (带 XYZ 标签和 reset 按钮) void drawVec3Control(const char* label, glm::vec3& values, float resetValue = 0.0f, float columnWidth = 120.0f); // 浮点数编辑器 bool drawFloatControl(const char* label, float& value, float columnWidth = 120.0f, float speed = 0.1f); // 复选框 void drawCheckboxControl(const char* label, bool& value, float width = 120.0f); // 自定义 Popup 包装 bool BeginPopup(const char* name); void EndPopup(); } ``` **XCEngine**: 直接使用原生 ImGui API,没有封装 --- ### 5.4 选择系统差异 **Fermion 选择 + Entity Picking**: ```cpp // InspectorPanel 实体拾取用于关节连接 bool m_entityPickingActive = false; Entity m_pickingTargetEntity; // 当用户在 Viewport 点击时 void deliverPickedEntity(Entity pickedEntity) { if (m_pickingTargetEntity.hasComponent()) { m_pickingTargetEntity.getComponent() .connectedBodyID = pickedEntity.getUUID(); } } ``` **XCEngine SelectionManager**: ```cpp class SelectionManager { Event OnSelectionChanged; EntityID GetSelectedEntity(); void SetSelectedEntity(EntityID entity); }; ``` **XCEngine 问题**: 没有 Entity Picking 机制,无法在编辑关节时拾取场景中的物体 --- ### 5.5 资源系统对比 **Fermion 资源系统**: ``` AssetManager (抽象基类) ├── EditorAssetManager (编辑器资源管理) │ └── importAsset() 导入资源 └── RuntimeAssetManager (运行时资源管理) └── getAsset() 获取资源 AssetRegistry (资源注册表) AssetHandle (资源句柄) ``` **XCEngine 资源系统**: ``` ProjectManager (文件系统浏览) └── GetCurrentItems() 返回 AssetItem 列表 AssetItem (只包含文件信息) ├── name ├── type ├── isFolder └── fullPath ``` **XCEngine 问题**: 1. 没有真正的资源导入流程 2. 没有 AssetRegistry 资源注册表 3. 没有 AssetHandle 统一资源句柄 4. 没有资源缓存和加载/卸载管理 --- ## 7. 核心问题总结 ### 7.1 已完成功能 | 面板 | 完成度 | 说明 | |------|--------|------| | HierarchyPanel | 70% | 基本树视图、选中、重命名、复制、拖拽 | | ProjectPanel | 60% | 文件浏览、网格显示、导航,但拖拽移动失效 | | ConsolePanel | 60% | 日志显示,缺少命令输入 | | MenuBar | 30% | 菜单结构存在,但所有项 stubbed | | InspectorPanel | 20% | 只实现 Transform 和 MeshRenderer 编辑,但 Engine 核心有完整组件库 | | SceneViewPanel | 5% | 纯占位符 | | GameViewPanel | 5% | 纯占位符 | ### 7.2 高优先级问题 1. **MenuBar 所有菜单项 stubbed** - 无法进行任何 Scene/Project 操作 2. **Inspector 没有 Add/Remove Component** - 无法添加/删除组件 3. **SceneViewPanel 完全是占位符** - 无法预览场景 4. **Project 拖拽移动失效** - HandleDrop() 返回 false 5. **缺少 5 个重要面板** - SettingsPanel, OverlayRenderPanel, MaterialEditorPanel, TextureConfigPanel, AssetManagerPanel ### 7.3 RHI 限制 当前 RHI 模块状态: - D3D12: PipelineState 返回 nullptr,无法创建 3D 渲染 Pipeline - OpenGL: Framebuffer、PipelineState、Shader 正常工作 **影响**: 在 RHI 重构完成前,3D Viewport 无法实现。 --- ## 8. 改进计划 ### 8.1 第一阶段: 完善现有面板功能 **目标**: 不依赖 RHI,完善 Editor UI 功能 #### 8.1.1 MenuBar 菜单功能对接 ``` 优先级: 高 预计工作量: 1-2 天 依赖: 无 ``` **需要实现**: - File 菜单: New Scene, Open Scene, Save Scene, Exit - Edit 菜单: Undo, Redo (需要命令历史系统), Cut, Copy, Paste - View 菜单: Reset Layout - Help 菜单: About **实现方案**: ```cpp // MenuBar.cpp if (ImGui::MenuItem("New Scene", "Ctrl+N")) { m_onNewSceneCallback(); // 通过回调连接到 BosonLayer } ``` #### 8.1.2 Inspector Add/Remove Component ``` 优先级: 高 预计工作量: 2-3 天 依赖: 组件系统完善 ``` **需要实现**: 1. 添加 "Add Component" 按钮 2. 分类组件菜单 (2D, 3D, Other) 3. 右键 "Remove Component" 选项 **实现方案**: ```cpp // InspectorPanel.cpp void InspectorPanel::drawComponent(Entity entity, UIFunction uiFunction) { // 右键菜单 if (ImGui::BeginPopupContextItem("ComponentSettings")) { if (ImGui::MenuItem("Remove Component")) entity.removeComponent(); ImGui::EndPopup(); } } // Add Component 按钮 if (ImGui::Button("Add Component")) { ImGui::OpenPopup("AddComponentMenu"); } // 分类显示组件列表 ``` #### 8.1.3 修复 Project 拖拽移动 ``` 优先级: 中 预计工作量: 0.5 天 依赖: 无 ``` **问题**: `HandleDrop()` 返回 false,从未被调用 **修复方案**: 在双击打开文件夹时,检查是否正在拖拽,如果是则执行移动操作。 --- ### 8.2 第二阶段: Inspector 组件系统完善 **目标**: 实现完整的组件编辑功能 #### 8.2.1 Inspector 组件编辑支持 Engine 核心已有完整组件系统,Editor Inspector 需要添加对这些组件的编辑支持: | 组件 | Engine 状态 | Inspector 编辑复杂度 | 说明 | |------|------------|---------------------|------| | TransformComponent | ✅ | 低 | 需改进 UI (drawVec3Control) | | MeshRendererComponent | ✅ | 中 | 需添加拖拽、预览 | | CameraComponent | ✅ | 中 | 投影、FOV、近远裁剪 | | DirectionalLightComponent | ✅ | 低 | 颜色、强度 | | PointLightComponent | ✅ | 低 | 颜色、强度、范围 | | SpotLightComponent | ✅ | 中 | 颜色、强度、范围、角度 | | Rigidbody2DComponent | ✅ | 高 | 物理引擎对接 | | Rigidbody3DComponent | ✅ | 高 | 物理引擎对接 | | Collider2D/3D | ✅ | 高 | 碰撞体 | | SpriteRendererComponent | ✅ | 中 | 2D 精灵 | | CircleRendererComponent | ✅ | 低 | 圆形渲染 | | TextComponent | ✅ | 中 | 文本渲染 | | ScriptComponent | ✅ | 高 | 脚本字段编辑 | #### 8.2.2 Transform UI 改进 **当前**: ```cpp ImGui::DragFloat3("##Position", transform->position, 0.1f); ``` **改进方案** (参考 Fermion `ui::drawVec3Control`): - 添加 XYZ 标签 - 添加 Per-axis reset 按钮 - 统一对齐和缩进 - 添加合适的刻度 (speed) --- ### 8.3 第三阶段: 场景序列化 **目标**: 实现 Scene Save/Load ``` 优先级: 中 预计工作量: 2-3 天 依赖: Scene 序列化框架 (Engine Scene 类已有基础 Serialize/Deserialize) ``` **需要实现**: - Scene 序列化到文件 (Engine 核心已有基础) - Scene 反序列化 - 资源路径管理 - Editor/Runtime 场景分离 --- ### 8.4 第四阶段: 3D Viewport (依赖 RHI) **目标**: 实现完整的 3D Viewport ``` 优先级: 高 (但依赖 RHI) 预计工作量: 2-4 周 依赖: RHI 重构完成 ``` #### 8.4.1 OpenGL Backend 优先方案 由于 D3D12 PipelineState 当前 broken,可以先用 OpenGL Backend 实现 Viewport: **优势**: - OpenGL Framebuffer 正常工作 - OpenGL PipelineState 正常工作 - Shader uniform 设置正常工作 **需要工作**: 1. EditorCamera 实现 (Orbit/Pan/Zoom) 2. SceneRenderer 中间层 3. ViewportPanel Framebuffer 渲染 4. 鼠标拾取 (readPixel from entity ID attachment) 5. ImGuizmo 集成 #### 8.4.2 实现步骤 **Step 1: EditorCamera** (3-5 天) ```cpp class EditorCamera { // Orbit 模式 void orbit(float deltaX, float deltaY); void pan(float deltaX, float deltaY); void zoom(float delta); // FPS 模式 void moveForward(float delta); void moveRight(float delta); }; ``` **Step 2: SceneRenderer 中间层** (1 周) ```cpp class ViewportRenderer { std::shared_ptr m_framebuffer; std::shared_ptr m_scene; void beginScene(const EditorCamera& camera); void submitMesh(MeshComponent& mesh, glm::mat4 transform); void endScene(); }; ``` **Step 3: ViewportPanel 集成** (3-5 天) ```cpp void ViewportPanel::onImGuiRender() { // 渲染到 framebuffer m_framebuffer->bind(); m_viewportRenderer->beginScene(m_editorCamera); // ... 提交场景物体 m_viewportRenderer->endScene(); m_framebuffer->unbind(); // 显示到 ImGui ImGui::Image(m_framebuffer->getColorTexture(), ...); // 鼠标拾取 int entityID = m_framebuffer->readPixel(1, pixelX, pixelY); } ``` **Step 4: ImGuizmo 集成** (2-3 天) ```cpp ImGuizmo::SetOrthographic(isOrthographic); ImGuizmo::SetRect(viewportBounds); ImGuizmo::Manipulate( cameraView, cameraProjection, operation, LOCAL, glm::value_ptr(worldTransform) ); ``` --- ### 8.5 第五阶段: Play/Edit 模式 **目标**: 实现场景状态切换 ``` 优先级: 中 预计工作量: 1-2 周 依赖: 3D Viewport + 组件系统 ``` **状态机**: ```cpp enum class SceneState { Edit, Play, Simulate }; void BosonLayer::onScenePlay() { m_runtimeScene = Scene::copy(m_editorScene); m_activeScene = m_runtimeScene; m_activeScene->onRuntimeStart(); } void BosonLayer::onSceneStop() { m_activeScene->onRuntimeStop(); m_activeScene = m_editorScene; } ``` --- ## 9. 技术债务 ### 9.1 架构问题 1. **Editor 和 Engine 使用两套不同的 GameObject/Component 系统** - **Editor** (`editor/src/Core/GameObject.h`): 简化版,使用 `float position[3]` 数组存储变换 - **Engine** (`engine/include/XCEngine/Components/`): 完整 ECS,使用 `TransformComponent` 组件 - **后果**: Editor 无法直接使用 Engine 的组件系统,需要重新实现 - **建议**: Editor 应复用 Engine 的 Components::GameObject/Scene 系统 2. **Panel 独立设计 vs Layer 组合** - Fermion: BosonLayer 组合所有面板,共享 Context - XCEngine: 各 Panel 独立,通过 SceneManager 单例通信 3. **SceneManager 单例 vs Scene 指针传递** - Editor 使用简化版 SceneManager,与 Engine 的 Scene 类不兼容 - 建议: 考虑使用 Context 模式传递 Scene 引用 4. **缺少 BosonUI 自定义控件封装** - Fermion 有 ui::drawVec3Control, ui::drawFloatControl 等 - XCEngine 直接使用原生 ImGui API,代码重复 ### 9.2 代码质量问题 1. **注释掉的代码** - 建议清理 2. **TODO/FIXME** - 建议跟踪 3. **Magic numbers** - 建议定义常量 --- ## 10. 建议实施路线 ### 短期 (1-2 周) ``` □ MenuBar 菜单功能对接 □ Inspector Add/Remove Component □ 修复 Project 拖拽移动 □ Transform UI 改进 □ Console 命令输入 ``` ### 中期 (1-2 月,RHI 完成后) ``` □ EditorCamera 实现 □ SceneRenderer 中间层 □ ViewportPanel 3D 渲染 □ 鼠标拾取 □ ImGuizmo 集成 □ Play/Edit/Simulate 模式 ``` ### 长期 ``` □ 完整的 Inspector 组件编辑界面 (Engine 核心组件已有) □ 场景序列化 □ 资源导入系统 □ 材质编辑器 □ 动画编辑器 □ OverlayRenderPanel (物理调试可视化) □ TextureConfigPanel (纹理配置) □ AssetManagerPanel (资源注册表) □ SettingsPanel (编辑器设置) □ Play/Edit/Simulate 模式切换 ``` --- ## 11. 参考资料 - Fermion Boson Editor 源码: `参考/Fermion/Boson/` - XCEngine Editor 源码: `editor/` - RHI 模块: `engine/include/XCEngine/RHI/` --- *文档生成时间: 2026-03-24* *最后更新: 2026-03-24 (更正 Component 系统描述,补充 Editor/Engine 架构问题)*