docs: 添加 Editor 设计与实现分析文档

- 对比分析 XCEngine Editor 与 Fermion Boson Editor 各面板功能
- 详细列出缺失的面板: SettingsPanel, OverlayRenderPanel, MaterialEditorPanel, TextureConfigPanel, AssetManagerPanel
- 分析核心系统差异: Application 架构、SceneManager、UI 控件封装、选择系统、资源系统
- 制定改进计划分阶段实施路线
This commit is contained in:
2026-03-24 18:15:03 +08:00
parent 0dde7234b7
commit 4daed24a05

View File

@@ -0,0 +1,933 @@
# 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 种 | 需重写 |
| 动态增删组件 | ✅ 分类菜单 | ❌ 无 | 需实现 |
| 删除组件 | ✅ 右键 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<TransformComponent*>(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<MeshRendererComponent*>(component)) {
// 只有 InputText没有预览没有拖拽
}
}
```
**主要问题**:
1. 组件类型太少 (只有 TransformComponent, MeshRendererComponent)
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<path> &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<IWindow> m_window;
std::unique_ptr<ImGuiLayer> m_imGuiLayer;
std::unique_ptr<LayerStack> m_layerStack;
void pushLayer(std::unique_ptr<Layer> layer); // 在 ImGui 之前更新
void pushOverlay(std::unique_ptr<Layer> overlay); // 在 ImGui 之后更新
};
```
**XCEngine Application**:
```cpp
class Application {
HWND m_hwnd;
ID3D12Device* m_device;
// 直接管理所有 Panels
std::unique_ptr<MenuBar> m_menuBar;
std::unique_ptr<HierarchyPanel> 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<EntityID, GameObject> m_entities;
std::vector<EntityID> 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<EntityManager> m_entityManager;
std::unique_ptr<Physics2DWorld> m_physicsWorld2D;
std::unique_ptr<Physics3DWorld> m_physicsWorld3D;
};
class EntityManager {
entt::registry m_registry; // EnTT ECS
std::unordered_map<UUID, entt::entity> m_entityMap;
};
```
**XCEngine 问题**:
1. 没有真正的 Scene 概念,只有实体列表
2. 没有物理世界集成
3. 没有 ECS 系统 (使用简单的 Component 基类)
4. EntityID 是简单递增整数,不是 UUID
5. 没有场景状态 (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<RevoluteJoint2DComponent>()) {
m_pickingTargetEntity.getComponent<RevoluteJoint2DComponent>()
.connectedBodyID = pickedEntity.getUUID();
}
}
```
**XCEngine SelectionManager**:
```cpp
class SelectionManager {
Event<EntityID> OnSelectionChanged;
EntityID GetSelectedEntity();
void SetSelectedEntity(EntityID entity);
};
```
**XCEngine 问题**: 没有 Entity Picking 机制,无法在编辑关节时拾取场景中的物体
---
### 5.5 资源系统对比
**Fermion 资源系统**:
```
AssetManager (抽象基类)
├── EditorAssetManager (编辑器资源管理)
│ └── importAsset() 导入资源
└── RuntimeAssetManager (运行时资源管理)
└── getAsset<T>() 获取资源
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 | 15% | 只有 Transform 和 MeshRenderer 显示 |
| 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<T>(Entity entity, UIFunction uiFunction) {
// 右键菜单
if (ImGui::BeginPopupContextItem("ComponentSettings")) {
if (ImGui::MenuItem("Remove Component"))
entity.removeComponent<T>();
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 组件类型补充
需要添加的组件类型:
| 组件 | 复杂度 | 说明 |
|------|--------|------|
| TransformComponent | 已实现 | 需改进 UI |
| 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 天
依赖: RHI 完善后
```
**需要实现**:
- Scene 序列化 (YAML/JSON)
- 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<Framebuffer> m_framebuffer;
std::shared_ptr<Scene> 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. **Panel 独立设计 vs Layer 组合**
- Fermion: BosonLayer 组合所有面板,共享 Context
- XCEngine: 各 Panel 独立,通过 SceneManager 单例通信
2. **SceneManager 单例 vs Scene 指针传递**
- 单例方便访问,但耦合紧密
- 建议: 考虑使用 Context 模式传递 Scene 引用
3. **缺少 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 模式
```
### 长期
```
□ 完整的组件系统
□ 场景序列化
□ 资源导入系统
□ 材质编辑器
□ 动画编辑器
□ OverlayRenderPanel (物理调试可视化)
□ TextureConfigPanel (纹理配置)
□ AssetManagerPanel (资源注册表)
□ SettingsPanel (编辑器设置)
```
---
## 11. 参考资料
- Fermion Boson Editor 源码: `参考/Fermion/Boson/`
- XCEngine Editor 源码: `editor/`
- RHI 模块: `engine/include/XCEngine/RHI/`
---
*文档生成时间: 2026-03-24*
*最后更新: 2026-03-24 (补充缺失面板和系统差异分析)*