Files
XCEngine/docs/plan/Editor设计与实现.md
ssdfasd 4daed24a05 docs: 添加 Editor 设计与实现分析文档
- 对比分析 XCEngine Editor 与 Fermion Boson Editor 各面板功能
- 详细列出缺失的面板: SettingsPanel, OverlayRenderPanel, MaterialEditorPanel, TextureConfigPanel, AssetManagerPanel
- 分析核心系统差异: Application 架构、SceneManager、UI 控件封装、选择系统、资源系统
- 制定改进计划分阶段实施路线
2026-03-24 18:15:03 +08:00

934 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 (补充缺失面板和系统差异分析)*