Compare commits
202 Commits
7e60bc568a
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| aa727202af | |||
| ec6965b0dd | |||
| 82b8bd22cc | |||
| d0ce2d7883 | |||
| 65b3078c7f | |||
| f6fb396a41 | |||
| f064d6ed68 | |||
| 0afcaa0b3b | |||
| 00fa6fffa0 | |||
| ac836ae961 | |||
| 5edc4ed242 | |||
| d92afa27da | |||
| 8232f59276 | |||
| 16f994b5e5 | |||
| bc6fb25ff0 | |||
| f26b0024f2 | |||
| 3e5b7287c7 | |||
| 39c7ef5fdf | |||
| abf30ecfd3 | |||
| 61ecb7146d | |||
| 599f622ba4 | |||
| 3ea8ce81d6 | |||
| a67f8597ba | |||
| a02ff65651 | |||
| a3efcda550 | |||
| 86eb455ab9 | |||
| 5b0a1743d9 | |||
| 1e189ff558 | |||
| 9980aa9be5 | |||
| 1d171ea61c | |||
| e1734181a0 | |||
| c710063d92 | |||
| c4fe643427 | |||
| 23bdf9ed48 | |||
| 78556ea683 | |||
| 5a938935e1 | |||
| 882df1ae5a | |||
| e77dbe40b1 | |||
| 4c79554050 | |||
| 4fe456c1a2 | |||
| 3e6e997485 | |||
| 2a9264cfe4 | |||
| a4c48c1b3f | |||
| ee03f7035b | |||
| 3e56757910 | |||
| a91df8b4cd | |||
| 0060a348f6 | |||
| 2eaab2481f | |||
| c495581878 | |||
| 307259091e | |||
| 4b58df9a61 | |||
| 5de4848d70 | |||
| 3f871a4f45 | |||
| 804e5138d7 | |||
| af6de86647 | |||
| 91c62c6b14 | |||
| 4ee1bcc599 | |||
| 31a8125fc1 | |||
| 87bf83451b | |||
| 9950e0a44f | |||
| 8bd375cd24 | |||
| c0d62dc749 | |||
| c98b41f6f4 | |||
| 72d09a1c49 | |||
| ba91e0f5dd | |||
| 9064c2f5f2 | |||
| 5797a75619 | |||
| e83f911aef | |||
| dd2299c8b0 | |||
| b8d29e39f6 | |||
| 72914b3865 | |||
| e6950fa704 | |||
| 21b0530f7b | |||
| c3d443eb85 | |||
| d705cc839b | |||
| 0d6b8bf7d8 | |||
| 4362008b39 | |||
| 712f99e723 | |||
| 48daaa1bd0 | |||
| e462f7d6f7 | |||
| 5b89c2bb76 | |||
| f3fc34898a | |||
| d2140bf5cc | |||
| a0d5e84516 | |||
| 8ba05216fb | |||
| 0cc3d6da46 | |||
| adb6fe4659 | |||
| 95edf0435f | |||
| 82c55b3999 | |||
| 00875e0c90 | |||
| b7428b0ef1 | |||
| 1d6f2e290d | |||
| 2ee74e7761 | |||
| 64212a53c7 | |||
| 6f876678f5 | |||
| 2326857a43 | |||
| 0f60f0f657 | |||
| dd3731ba66 | |||
| 941034b387 | |||
| 89590242bd | |||
| a660fc489a | |||
| e86d260d64 | |||
| 347d08463b | |||
| 7ee28a7969 | |||
| b7ce8618d2 | |||
| 7ad4bfbb1c | |||
| 838f676fa6 | |||
| 0ff02150c0 | |||
| 8848cfd958 | |||
| 3e55f8c204 | |||
| 0a015b52ca | |||
| 030230eb1f | |||
| 8f71f99de4 | |||
| 443c56ed08 | |||
| 2958dcc491 | |||
| 35d3d6328b | |||
| c03c7379c8 | |||
| 0a2bdedc59 | |||
| 2fb6eca854 | |||
| c543ccf79c | |||
| 88a71a5426 | |||
| ff4e3f639a | |||
| 92d5cc61cf | |||
| b3acb5afc2 | |||
| 785377bc9b | |||
| 5200fca82f | |||
| 39632e1a04 | |||
| 3622bf3aa2 | |||
| fac6e588a8 | |||
| 5191bb1149 | |||
| d9bc0f1457 | |||
| 4080b2e5fe | |||
| be5dabd820 | |||
| 107b320aa7 | |||
| 15b42c248f | |||
| 977a4cf2a4 | |||
| b187c8970b | |||
| 1119af2e38 | |||
| 2338e306bf | |||
| 87ad489bfd | |||
| 503e6408ed | |||
| 8f5c342799 | |||
| 84faa585d5 | |||
| ac9388445c | |||
| 3561bf22bb | |||
| e6ac43b454 | |||
| 2f3a28ec3e | |||
| 737ccd2e0c | |||
| bdf0b9a16b | |||
| 0c52e0f640 | |||
| bb9a4d5ef4 | |||
| a990553ade | |||
| de2fc8be43 | |||
| effca78771 | |||
| 0602b34652 | |||
| 85b8b3e583 | |||
| cba3823ea2 | |||
| 89bbad2786 | |||
| 00cf3850d5 | |||
| 81d0d92aed | |||
| 2d8ada03a1 | |||
| 7fc7bb0a22 | |||
| 447977214e | |||
| 46fac8a215 | |||
| e2e4e08479 | |||
| e69240db49 | |||
| dd467d2468 | |||
| 71a27d7c9c | |||
| f401a54806 | |||
| f917040e9a | |||
| 66ae9ec919 | |||
| 6b90c2f6c3 | |||
| 4d8a51aee2 | |||
| 8cde4e0649 | |||
| 1f79afba3c | |||
| 57331c1c25 | |||
| ff6d6d31fe | |||
| 152997c409 | |||
| 54eb2415ff | |||
| f476890116 | |||
| f9bfd48479 | |||
| 131f46682b | |||
| 899442c64d | |||
| b5ba985831 | |||
| 4debbbea1f | |||
| 4111f841d4 | |||
| 34a32b73dd | |||
| 02a0e626fe | |||
| 4b47764f26 | |||
| 225f533c7c | |||
| 9b074e3020 | |||
| 3ed69aa82f | |||
| a545951a58 | |||
| 2bb511087f | |||
| 4aaac9887e | |||
| cb3d558aaa | |||
| b0625a30bd | |||
| d4bec254d1 | |||
| 7733d59ed1 | |||
| 681452c70e | |||
| 20b5c22a6a | |||
| 84db2e951d |
55
AGENT.md
55
AGENT.md
@@ -20,9 +20,11 @@
|
||||
- [docs/plan/Library启动预热与运行时异步加载混合重构计划_2026-04-04.md](docs/plan/Library启动预热与运行时异步加载混合重构计划_2026-04-04.md)
|
||||
- [docs/plan/Library启动预热与运行时异步加载混合重构计划_进度更新_2026-04-04.md](docs/plan/Library启动预热与运行时异步加载混合重构计划_进度更新_2026-04-04.md)
|
||||
- [docs/plan/Editor架构说明.md](docs/plan/Editor架构说明.md)
|
||||
- [docs/plan/Renderer下一阶段_Unity风格Shader体系正式化计划_2026-04-06.md](docs/plan/Renderer下一阶段_Unity风格Shader体系正式化计划_2026-04-06.md)
|
||||
- [docs/plan/Unity风格模型导入与Model资产架构重构计划_2026-04-10.md](docs/plan/Unity风格模型导入与Model资产架构重构计划_2026-04-10.md)
|
||||
- [docs/plan/NanoVDB体积云加载阻塞与Runtime上传修复计划_2026-04-10.md](docs/plan/NanoVDB体积云加载阻塞与Runtime上传修复计划_2026-04-10.md)
|
||||
- [docs/plan/3DGS专用PLY导入器与GaussianSplat资源缓存正式化计划_2026-04-10.md](docs/plan/3DGS专用PLY导入器与GaussianSplat资源缓存正式化计划_2026-04-10.md)
|
||||
- [docs/plan/XCUI_NewEditor主线重建计划_2026-04-07.md](docs/plan/XCUI_NewEditor主线重建计划_2026-04-07.md)
|
||||
- [docs/plan/XCUI完整架构设计与执行计划.md](docs/plan/XCUI完整架构设计与执行计划.md)
|
||||
- [docs/plan/XCUI_Phase_Status_2026-04-05.md](docs/plan/XCUI_Phase_Status_2026-04-05.md)
|
||||
- [docs/plan/C#脚本模块下一阶段计划.md](docs/plan/C%23脚本模块下一阶段计划.md)
|
||||
- [tests/TEST_SPEC.md](tests/TEST_SPEC.md)
|
||||
- [tests/UI/TEST_SPEC.md](tests/UI/TEST_SPEC.md)
|
||||
@@ -30,22 +32,35 @@
|
||||
已归档但当前仍常用的背景文档:
|
||||
|
||||
- [Library资产导入与缓存系统收口计划(归档)](docs/used/Library资产导入与缓存系统收口计划_完成归档_2026-04-03.md)
|
||||
- [API 文档第三轮任务池(归档基线)](docs/used/API文档实时同步任务池_2026-04-03.md)
|
||||
- [XCUI Phase Status 2026-04-05(归档)](docs/used/XCUI_Phase_Status_2026-04-05.md)
|
||||
- [Shader与Material系统下一阶段计划(归档)](docs/used/Shader与Material系统下一阶段计划_完成归档_2026-04-04.md)
|
||||
- [Unity 风格 Shader 体系正式化计划(归档)](docs/used/Renderer下一阶段_Unity风格Shader体系正式化计划_完成归档_2026-04-07.md)
|
||||
- [Renderer 当前阶段正式收口(阶段归档)](docs/used/Renderer当前阶段正式收口计划_阶段归档_2026-04-10.md)
|
||||
- [NanoVDB 后续正式化(阶段归档)](docs/used/NanoVDB稀疏体积渲染后续正式化计划_阶段归档_2026-04-10.md)
|
||||
- [SceneViewport Overlay / Gizmo 重构计划(归档)](docs/used/SceneViewport_Overlay_Gizmo_Rework_Plan_完成归档_2026-04-04.md)
|
||||
- [Unity式 SceneView Gizmo 正式化方案(归档)](docs/used/Unity式SceneView_Gizmo系统完整审查与正式化重构方案_完成归档_2026-04-06.md)
|
||||
- [NanoVDB 第一阶段完成归档](docs/used/NanoVDB稀疏体积渲染正式集成计划_第一阶段完成归档_2026-04-09.md)
|
||||
|
||||
如果任务落在 API 文档:
|
||||
|
||||
1. 先检查 `docs/plan/` 下有没有日期更晚的 API 相关计划或归档;当前活跃任务池是 [docs/plan/API文档实时同步任务池_2026-04-03.md](docs/plan/API文档实时同步任务池_2026-04-03.md)。这份任务池目前已经推进到第三轮 `T01-T20` 全部完成,结构审计保持全绿,但开始新一轮前仍要先确认是否又追加了新任务块。
|
||||
2. 再看 [docs/api-skill.md](docs/api-skill.md)。
|
||||
3. 再看 `docs/api/_meta/rebuild-status.md`。
|
||||
4. 一次只认领一个任务块,先改状态为 `DOING`,只写自己任务块允许的范围。
|
||||
1. 先检查 `docs/plan/` 下最新的 API 相关计划或并行任务板。当前工作树里已经存在多份 2026-04-09 的活跃文件,例如:
|
||||
- [docs/plan/API文档目录重构计划_2026-04-09.md](docs/plan/API文档目录重构计划_2026-04-09.md)
|
||||
- [docs/plan/API文档目录结构重大重构并行任务板_2026-04-09.md](docs/plan/API文档目录结构重大重构并行任务板_2026-04-09.md)
|
||||
- [docs/plan/API文档目录结构第二轮重构计划_2026-04-09.md](docs/plan/API文档目录结构第二轮重构计划_2026-04-09.md)
|
||||
- [docs/plan/API文档目录结构第二轮并行任务板_2026-04-09.md](docs/plan/API文档目录结构第二轮并行任务板_2026-04-09.md)
|
||||
- [docs/plan/API文档目录结构重构并行任务板_2026-04-09_第二轮.md](docs/plan/API文档目录结构重构并行任务板_2026-04-09_第二轮.md)
|
||||
2. 如果这些活跃文件都不覆盖当前问题,再回看 [docs/used/API文档实时同步任务池_2026-04-03.md](docs/used/API文档实时同步任务池_2026-04-03.md) 作为最近一轮完成基线。
|
||||
3. 再看 [docs/api-skill.md](docs/api-skill.md)。
|
||||
4. 再看 `docs/api/main.md` 和 `docs/api/_meta/rebuild-status.md`,确认当前问题落在 `XCEngine` 还是 `XCEditor` 根树。
|
||||
5. 一次只认领一个任务块,先改状态为 `DOING`,只写自己任务块允许的范围。
|
||||
|
||||
## 2. 当前工程事实
|
||||
|
||||
- 顶层 `CMakeLists.txt` 当前纳入 `engine/`、`editor/`、`new_editor/`、`managed/`、`mvs/RenderDoc/` 和 `tests/`。
|
||||
- `engine/` 构建静态库 `XCEngine`;`editor/` 构建 `XCEditor`,但输出文件名仍是 `editor/bin/<Config>/XCEngine.exe`。
|
||||
- `new_editor/` 当前构建 `XCUIEditorLib`、`XCUIEditorHost`;启用 `XCENGINE_BUILD_XCUI_EDITOR_APP` 时会输出 `new_editor/bin/<Config>/XCUIEditor.exe`。
|
||||
- `editor/` 目前继续保留为当前正式编辑器、行为对照和视觉基线来源。
|
||||
- `new_editor/` 当前构建 `XCUIEditorLib`、`XCUIEditorHost`;启用 `XCENGINE_BUILD_XCUI_EDITOR_APP` 时会输出 `new_editor/bin/<Config>/XCUIEditor.exe`,并被视为未来正式编辑器主线,而不再只是临时 sandbox。
|
||||
- editor 默认把仓库内的 `project/` 识别为工程根目录,也支持 `--project <path>` 覆盖。
|
||||
- 当前工程真实使用 `Assets/ + .meta + Library/` 的项目布局;`project/Library/` 是当前 workflow 的一部分,不是可随手忽略的垃圾目录。
|
||||
- Mono 运行时与 editor 的脚本类发现都从 `<project>/Library/ScriptAssemblies/` 加载程序集。
|
||||
@@ -81,8 +96,13 @@
|
||||
- `ObjectId` 渲染与 editor picking
|
||||
- `BuiltinInfiniteGridPass`
|
||||
- `BuiltinObjectIdOutlinePass`
|
||||
- `directional shadow`
|
||||
- `skybox`
|
||||
- `CameraRenderRequest::postScenePasses`
|
||||
- `CameraRenderRequest::overlayPasses`
|
||||
- `post-process / final color` 当前处于正式化收口阶段,不再是纯预留接口。
|
||||
- `NanoVDB` 体积渲染已进入当前正式运行链路,但 Vulkan / OpenGL 的 rollout 和多后端能力边界仍在继续收口。
|
||||
- 当前资源与导入主线正在继续向 `Model` 资产架构与 `3DGS GaussianSplat` 资源链扩展,不要再把 `.obj/.fbx/.ply` 简化理解为“文件直读后立刻渲染”的旧 sample 流程。
|
||||
- 当前主线不是 render graph,而是 shader / material contract、builtin pass contract 和 renderer-owned feature contract。
|
||||
|
||||
### 3.3 Editor
|
||||
@@ -126,13 +146,13 @@
|
||||
|
||||
### 3.4 XCUI / New Editor
|
||||
|
||||
- `new_editor/` 是当前 `XCUI` editor sandbox 主线;旧 `editor/` 的整体替换仍处于延后状态,不要把 `XCUI` 计划误读成“已经整体替换现有 editor”。
|
||||
- `new_editor/` 是未来正式编辑器主线,不再只是 sandbox;旧 `editor/` 当前继续保留为正式编辑器、行为对照和视觉基线。
|
||||
- 当前宿主分层是:
|
||||
- `XCUIEditorLib`
|
||||
- `XCUIEditorHost`
|
||||
- `XCUIEditorApp`(可选应用壳)
|
||||
- 共享 UI core、runtime screen host 与 widget 基础能力主要沉淀在 `engine/include/XCEngine/UI/` 与 `engine/src/UI/`;`new_editor/` 负责 XCUI editor 壳、宿主与 widget sandbox。
|
||||
- XCUI / new_editor 的测试规范以 [tests/UI/TEST_SPEC.md](tests/UI/TEST_SPEC.md) 为准;根目录虽然有 `tests/NewEditor/`,但当前具体测试实现主要放在 `tests/UI/` 下。
|
||||
- 共享 UI core、runtime screen host 与 widget 基础能力主要沉淀在 `engine/include/XCEngine/UI/` 与 `engine/src/UI/`;`new_editor/` 负责 XCUI editor 壳、宿主与产品装配。
|
||||
- `tests/UI/` 是当前 XCUI `Core / Editor / Runtime` 三层的唯一正式基础层验证入口;`new_editor/` 不承担测试堆场职责。
|
||||
|
||||
### 3.5 Scripting
|
||||
|
||||
@@ -262,15 +282,21 @@
|
||||
|
||||
只要任务涉及 `docs/api/`:
|
||||
|
||||
1. 先检查 `docs/plan/` 下有没有更新日期更晚的 API 计划或归档。
|
||||
2. 以最新任务池和 [docs/api-skill.md](docs/api-skill.md) 为执行规范。
|
||||
3. 改完必须重新执行:
|
||||
1. 先读 `docs/plan/API文档目录*.md` 里日期最新的 API 计划 / 并行任务板。
|
||||
2. 再看 [docs/api-skill.md](docs/api-skill.md) 和 `docs/api/_meta/rebuild-status.md`。
|
||||
3. 如果活跃计划没有覆盖当前问题,再回看 [docs/used/API文档实时同步任务池_2026-04-03.md](docs/used/API文档实时同步任务池_2026-04-03.md) 作为最近一轮归档基线。
|
||||
4. 改完必须重新执行:
|
||||
|
||||
```powershell
|
||||
python -B docs/api/_tools/audit_api_docs.py
|
||||
```
|
||||
|
||||
如果审计没回绿,不算完成。
|
||||
当前审计口径已经同时覆盖:
|
||||
|
||||
- `engine/include/XCEngine/**`
|
||||
- `new_editor/include/XCEditor/**`
|
||||
- `editor/src/**`
|
||||
|
||||
## 5. 推荐构建与验证入口
|
||||
|
||||
@@ -321,9 +347,10 @@ ctest --test-dir build -C Debug --output-on-failure
|
||||
- 资源导入与工程布局:`engine/include/XCEngine/Core/Asset/`、`engine/src/Core/Asset/`、`editor/src/Managers/ProjectManager.cpp`、`project/Assets/`、`project/Library/`
|
||||
- Material / shader / artifact:`engine/include/XCEngine/Resources/Material/`、`engine/src/Resources/Material/`、`engine/include/XCEngine/Core/Asset/ArtifactFormats.h`、`tests/Resources/Material/`
|
||||
- Editor viewport / gizmo / picking:`editor/src/Viewport/`、`editor/src/panels/SceneViewPanel.cpp`、`tests/Editor/`
|
||||
- XCUI / new_editor:`engine/include/XCEngine/UI/`、`engine/src/UI/`、`new_editor/include/XCEditor/`、`new_editor/src/`、`tests/UI/`
|
||||
- Editor actions / project routing:`editor/src/Actions/`、`editor/src/Commands/`、`editor/src/Core/`、`editor/src/Managers/`、`tests/Editor/test_action_routing.cpp`
|
||||
- 脚本运行时与程序集:`engine/include/XCEngine/Scripting/`、`engine/src/Scripting/`、`managed/`、`project/Assets/Scripts/`、`tests/Scripting/`
|
||||
- API 文档:`docs/api/XCEngine/`、`docs/api/_guides/`、`docs/api/_tools/audit_api_docs.py`、`docs/plan/API文档实时同步任务池_2026-04-03.md`
|
||||
- API 文档:`docs/api/main.md`、`docs/api/XCEngine/`、`docs/api/XCEditor/`、`docs/api/_guides/`、`docs/api/_tools/audit_api_docs.py`、`docs/plan/API文档目录*.md`、`docs/used/API文档实时同步任务池_2026-04-03.md`
|
||||
|
||||
## 7. 适合当前仓库的工作方式
|
||||
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
if(MSVC)
|
||||
if(POLICY CMP0141)
|
||||
cmake_policy(SET CMP0141 NEW)
|
||||
endif()
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
|
||||
"$<$<CONFIG:Debug,RelWithDebInfo>:Embedded>")
|
||||
if(POLICY CMP0141)
|
||||
cmake_policy(SET CMP0141 NEW)
|
||||
endif()
|
||||
|
||||
project(XCEngine)
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
|
||||
"$<$<CONFIG:Debug,RelWithDebInfo>:Embedded>")
|
||||
add_compile_options("$<$<COMPILE_LANGUAGE:C,CXX>:/MP>")
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
set(CMAKE_VS_GLOBALS "UseMultiToolTask=true")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
@@ -43,9 +48,18 @@ set(
|
||||
CACHE PATH
|
||||
"Path to the bundled Mono distribution used by the scripting runtime")
|
||||
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/engine/third_party/mono/binary/mscorlib.dll")
|
||||
set(
|
||||
XCENGINE_MONO_ROOT_DIR
|
||||
"${CMAKE_SOURCE_DIR}/engine/third_party/mono"
|
||||
CACHE PATH
|
||||
"Path to the bundled Mono distribution used by the scripting runtime"
|
||||
FORCE)
|
||||
endif()
|
||||
|
||||
add_subdirectory(engine)
|
||||
add_subdirectory(managed)
|
||||
add_subdirectory(editor)
|
||||
add_subdirectory(new_editor)
|
||||
add_subdirectory(managed)
|
||||
add_subdirectory(mvs/RenderDoc)
|
||||
add_subdirectory(tests)
|
||||
|
||||
158
MVS/3DGS-D3D12/CMakeLists.txt
Normal file
158
MVS/3DGS-D3D12/CMakeLists.txt
Normal file
@@ -0,0 +1,158 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(XC3DGSD3D12MVS LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_program(XC_DXC_EXECUTABLE NAMES dxc)
|
||||
if(NOT XC_DXC_EXECUTABLE)
|
||||
message(FATAL_ERROR "dxc is required to build the 3DGS D3D12 MVS sort shaders.")
|
||||
endif()
|
||||
|
||||
get_filename_component(XCENGINE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../.." ABSOLUTE)
|
||||
set(XCENGINE_BUILD_DIR "${XCENGINE_ROOT}/build")
|
||||
set(XCENGINE_INCLUDE_DIR "${XCENGINE_ROOT}/engine/include")
|
||||
set(XCENGINE_LIBRARY_DEBUG "${XCENGINE_BUILD_DIR}/engine/Debug/XCEngine.lib")
|
||||
|
||||
if(NOT EXISTS "${XCENGINE_LIBRARY_DEBUG}")
|
||||
message(FATAL_ERROR "Prebuilt XCEngine library was not found: ${XCENGINE_LIBRARY_DEBUG}")
|
||||
endif()
|
||||
|
||||
add_library(XCEngine STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(XCEngine PROPERTIES
|
||||
IMPORTED_CONFIGURATIONS "Debug;Release;RelWithDebInfo;MinSizeRel"
|
||||
IMPORTED_LOCATION_DEBUG "${XCENGINE_LIBRARY_DEBUG}"
|
||||
IMPORTED_LOCATION_RELEASE "${XCENGINE_LIBRARY_DEBUG}"
|
||||
IMPORTED_LOCATION_RELWITHDEBINFO "${XCENGINE_LIBRARY_DEBUG}"
|
||||
IMPORTED_LOCATION_MINSIZEREL "${XCENGINE_LIBRARY_DEBUG}"
|
||||
)
|
||||
|
||||
add_executable(xc_3dgs_d3d12_mvs
|
||||
WIN32
|
||||
src/main.cpp
|
||||
src/App.cpp
|
||||
src/GaussianPlyLoader.cpp
|
||||
include/XC3DGSD3D12/App.h
|
||||
include/XC3DGSD3D12/GaussianPlyLoader.h
|
||||
shaders/PreparedSplatView.hlsli
|
||||
shaders/PrepareGaussiansCS.hlsl
|
||||
shaders/BuildSortKeysCS.hlsl
|
||||
shaders/SortCommon.hlsl
|
||||
shaders/DeviceRadixSort.hlsl
|
||||
shaders/DebugPointsVS.hlsl
|
||||
shaders/DebugPointsPS.hlsl
|
||||
shaders/CompositeVS.hlsl
|
||||
shaders/CompositePS.hlsl
|
||||
)
|
||||
|
||||
set_source_files_properties(
|
||||
shaders/PreparedSplatView.hlsli
|
||||
shaders/PrepareGaussiansCS.hlsl
|
||||
shaders/BuildSortKeysCS.hlsl
|
||||
shaders/SortCommon.hlsl
|
||||
shaders/DeviceRadixSort.hlsl
|
||||
shaders/DebugPointsVS.hlsl
|
||||
shaders/DebugPointsPS.hlsl
|
||||
shaders/CompositeVS.hlsl
|
||||
shaders/CompositePS.hlsl
|
||||
PROPERTIES
|
||||
HEADER_FILE_ONLY TRUE
|
||||
)
|
||||
|
||||
target_include_directories(xc_3dgs_d3d12_mvs PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${XCENGINE_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(xc_3dgs_d3d12_mvs PRIVATE
|
||||
UNICODE
|
||||
_UNICODE
|
||||
NOMINMAX
|
||||
WIN32_LEAN_AND_MEAN
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(xc_3dgs_d3d12_mvs PRIVATE /utf-8)
|
||||
endif()
|
||||
|
||||
target_link_libraries(xc_3dgs_d3d12_mvs PRIVATE
|
||||
XCEngine
|
||||
d3d12
|
||||
dxgi
|
||||
dxguid
|
||||
d3dcompiler
|
||||
winmm
|
||||
delayimp
|
||||
bcrypt
|
||||
opengl32
|
||||
)
|
||||
|
||||
set_target_properties(xc_3dgs_d3d12_mvs PROPERTIES
|
||||
VS_DEBUGGER_WORKING_DIRECTORY "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET xc_3dgs_d3d12_mvs POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/room.ply"
|
||||
"$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/room.ply"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET xc_3dgs_d3d12_mvs POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/shaders"
|
||||
"$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET xc_3dgs_d3d12_mvs POST_BUILD
|
||||
COMMAND "${XC_DXC_EXECUTABLE}"
|
||||
-T cs_6_6
|
||||
-E MainCS
|
||||
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/BuildSortKeysCS.dxil"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/BuildSortKeysCS.hlsl"
|
||||
COMMAND "${XC_DXC_EXECUTABLE}"
|
||||
-T cs_6_6
|
||||
-E InitDeviceRadixSort
|
||||
-D KEY_UINT=1
|
||||
-D PAYLOAD_UINT=1
|
||||
-D SORT_PAIRS=1
|
||||
-D SHOULD_ASCEND=1
|
||||
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/RadixInit.dxil"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/DeviceRadixSort.hlsl"
|
||||
COMMAND "${XC_DXC_EXECUTABLE}"
|
||||
-T cs_6_6
|
||||
-E Upsweep
|
||||
-D KEY_UINT=1
|
||||
-D PAYLOAD_UINT=1
|
||||
-D SORT_PAIRS=1
|
||||
-D SHOULD_ASCEND=1
|
||||
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/RadixUpsweep.dxil"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/DeviceRadixSort.hlsl"
|
||||
COMMAND "${XC_DXC_EXECUTABLE}"
|
||||
-T cs_6_6
|
||||
-E BuildGlobalHistogram
|
||||
-D KEY_UINT=1
|
||||
-D PAYLOAD_UINT=1
|
||||
-D SORT_PAIRS=1
|
||||
-D SHOULD_ASCEND=1
|
||||
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/RadixGlobalHistogram.dxil"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/DeviceRadixSort.hlsl"
|
||||
COMMAND "${XC_DXC_EXECUTABLE}"
|
||||
-T cs_6_6
|
||||
-E Scan
|
||||
-D KEY_UINT=1
|
||||
-D PAYLOAD_UINT=1
|
||||
-D SORT_PAIRS=1
|
||||
-D SHOULD_ASCEND=1
|
||||
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/RadixScan.dxil"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/DeviceRadixSort.hlsl"
|
||||
COMMAND "${XC_DXC_EXECUTABLE}"
|
||||
-T cs_6_6
|
||||
-E Downsweep
|
||||
-D KEY_UINT=1
|
||||
-D PAYLOAD_UINT=1
|
||||
-D SORT_PAIRS=1
|
||||
-D SHOULD_ASCEND=1
|
||||
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/RadixDownsweep.dxil"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/DeviceRadixSort.hlsl"
|
||||
)
|
||||
162
MVS/3DGS-D3D12/include/XC3DGSD3D12/App.h
Normal file
162
MVS/3DGS-D3D12/include/XC3DGSD3D12/App.h
Normal file
@@ -0,0 +1,162 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include "XC3DGSD3D12/GaussianPlyLoader.h"
|
||||
#include "XCEngine/RHI/RHIEnums.h"
|
||||
#include "XCEngine/RHI/RHITypes.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12CommandAllocator.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12Buffer.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12CommandList.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12CommandQueue.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12Device.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12ResourceView.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12SwapChain.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12Texture.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
class RHIDescriptorPool;
|
||||
class RHIDescriptorSet;
|
||||
class RHIPipelineLayout;
|
||||
class RHIPipelineState;
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
|
||||
namespace XC3DGSD3D12 {
|
||||
|
||||
struct PreparedSplatView {
|
||||
float clipPosition[4] = {};
|
||||
float axis1[2] = {};
|
||||
float axis2[2] = {};
|
||||
uint32_t packedColor[2] = {};
|
||||
};
|
||||
|
||||
class App {
|
||||
public:
|
||||
App();
|
||||
~App();
|
||||
|
||||
bool Initialize(HINSTANCE instance, int showCommand);
|
||||
int Run();
|
||||
void SetFrameLimit(unsigned int frameLimit);
|
||||
void SetGaussianScenePath(std::wstring scenePath);
|
||||
void SetSummaryPath(std::wstring summaryPath);
|
||||
void SetScreenshotPath(std::wstring screenshotPath);
|
||||
const std::wstring& GetLastErrorMessage() const;
|
||||
|
||||
private:
|
||||
static constexpr int kBackBufferCount = 2;
|
||||
static constexpr int kDefaultWidth = 1280;
|
||||
static constexpr int kDefaultHeight = 720;
|
||||
|
||||
static LRESULT CALLBACK StaticWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
bool RegisterWindowClass(HINSTANCE instance);
|
||||
bool CreateMainWindow(HINSTANCE instance, int showCommand);
|
||||
bool LoadGaussianScene();
|
||||
bool InitializeRhi();
|
||||
bool InitializeGaussianGpuResources();
|
||||
bool InitializePreparePassResources();
|
||||
bool InitializeSortResources();
|
||||
bool InitializeDebugDrawResources();
|
||||
bool InitializeCompositeResources();
|
||||
void ShutdownGaussianGpuResources();
|
||||
void ShutdownPreparePassResources();
|
||||
void ShutdownSortResources();
|
||||
void ShutdownDebugDrawResources();
|
||||
void ShutdownCompositeResources();
|
||||
void Shutdown();
|
||||
bool CaptureSortSnapshot();
|
||||
bool CapturePass3HistogramDebug();
|
||||
void RenderFrame(bool captureScreenshot);
|
||||
|
||||
HWND m_hwnd = nullptr;
|
||||
HINSTANCE m_instance = nullptr;
|
||||
int m_width = kDefaultWidth;
|
||||
int m_height = kDefaultHeight;
|
||||
bool m_running = false;
|
||||
bool m_isInitialized = false;
|
||||
bool m_hasRenderedAtLeastOneFrame = false;
|
||||
unsigned int m_frameLimit = 0;
|
||||
unsigned int m_renderedFrameCount = 0;
|
||||
std::wstring m_gaussianScenePath = L"room.ply";
|
||||
std::wstring m_summaryPath;
|
||||
std::wstring m_screenshotPath = L"phase3_debug_points.ppm";
|
||||
std::wstring m_sortKeySnapshotPath = L"phase3_sortkeys.txt";
|
||||
std::wstring m_lastErrorMessage;
|
||||
GaussianSplatRuntimeData m_gaussianSceneData;
|
||||
XCEngine::RHI::D3D12Buffer m_gaussianPositionBuffer;
|
||||
XCEngine::RHI::D3D12Buffer m_gaussianOtherBuffer;
|
||||
XCEngine::RHI::D3D12Buffer m_gaussianShBuffer;
|
||||
XCEngine::RHI::D3D12Texture m_gaussianColorTexture;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_gaussianPositionView;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_gaussianOtherView;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_gaussianShView;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_gaussianColorView;
|
||||
std::vector<Microsoft::WRL::ComPtr<ID3D12Resource>> m_gaussianUploadBuffers;
|
||||
XCEngine::RHI::D3D12Buffer* m_preparedViewBuffer = nullptr;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_preparedViewSrv;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_preparedViewUav;
|
||||
XCEngine::RHI::RHIPipelineLayout* m_preparePipelineLayout = nullptr;
|
||||
XCEngine::RHI::RHIPipelineState* m_preparePipelineState = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorPool* m_prepareDescriptorPool = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorSet* m_prepareDescriptorSet = nullptr;
|
||||
XCEngine::RHI::D3D12Buffer* m_sortKeyBuffer = nullptr;
|
||||
XCEngine::RHI::D3D12Buffer* m_sortKeyScratchBuffer = nullptr;
|
||||
XCEngine::RHI::D3D12Buffer* m_orderBuffer = nullptr;
|
||||
XCEngine::RHI::D3D12Buffer* m_orderScratchBuffer = nullptr;
|
||||
XCEngine::RHI::D3D12Buffer* m_passHistogramBuffer = nullptr;
|
||||
XCEngine::RHI::D3D12Buffer* m_globalHistogramBuffer = nullptr;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_sortKeyUav;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_sortKeyScratchUav;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_orderBufferSrv;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_orderBufferUav;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_orderScratchUav;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_passHistogramUav;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_globalHistogramUav;
|
||||
XCEngine::RHI::RHIPipelineLayout* m_buildSortKeyPipelineLayout = nullptr;
|
||||
XCEngine::RHI::RHIPipelineState* m_buildSortKeyPipelineState = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorPool* m_buildSortKeyDescriptorPool = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorSet* m_buildSortKeyDescriptorSet = nullptr;
|
||||
XCEngine::RHI::RHIPipelineLayout* m_radixSortPipelineLayout = nullptr;
|
||||
XCEngine::RHI::RHIPipelineState* m_radixSortInitPipelineState = nullptr;
|
||||
XCEngine::RHI::RHIPipelineState* m_radixSortUpsweepPipelineState = nullptr;
|
||||
XCEngine::RHI::RHIPipelineState* m_radixSortGlobalHistogramPipelineState = nullptr;
|
||||
XCEngine::RHI::RHIPipelineState* m_radixSortScanPipelineState = nullptr;
|
||||
XCEngine::RHI::RHIPipelineState* m_radixSortDownsweepPipelineState = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorPool* m_radixSortDescriptorPool = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorSet* m_radixSortDescriptorSetPrimaryToScratch = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorSet* m_radixSortDescriptorSetScratchToPrimary = nullptr;
|
||||
XCEngine::RHI::RHIPipelineLayout* m_debugPipelineLayout = nullptr;
|
||||
XCEngine::RHI::RHIPipelineState* m_debugPipelineState = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorPool* m_debugDescriptorPool = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorSet* m_debugDescriptorSet = nullptr;
|
||||
XCEngine::RHI::D3D12Texture m_splatRenderTargetTexture;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_splatRenderTargetRtv;
|
||||
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_splatRenderTargetSrv;
|
||||
XCEngine::RHI::RHIPipelineLayout* m_compositePipelineLayout = nullptr;
|
||||
XCEngine::RHI::RHIPipelineState* m_compositePipelineState = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorPool* m_compositeDescriptorPool = nullptr;
|
||||
XCEngine::RHI::RHIDescriptorSet* m_compositeDescriptorSet = nullptr;
|
||||
|
||||
XCEngine::RHI::D3D12Device m_device;
|
||||
XCEngine::RHI::D3D12CommandQueue m_commandQueue;
|
||||
XCEngine::RHI::D3D12SwapChain m_swapChain;
|
||||
XCEngine::RHI::D3D12CommandAllocator m_commandAllocator;
|
||||
XCEngine::RHI::D3D12CommandList m_commandList;
|
||||
XCEngine::RHI::D3D12Texture m_depthStencil;
|
||||
XCEngine::RHI::D3D12DescriptorHeap m_rtvHeap;
|
||||
XCEngine::RHI::D3D12DescriptorHeap m_dsvHeap;
|
||||
XCEngine::RHI::D3D12ResourceView m_rtvs[kBackBufferCount];
|
||||
XCEngine::RHI::D3D12ResourceView m_dsv;
|
||||
};
|
||||
|
||||
} // namespace XC3DGSD3D12
|
||||
46
MVS/3DGS-D3D12/include/XC3DGSD3D12/GaussianPlyLoader.h
Normal file
46
MVS/3DGS-D3D12/include/XC3DGSD3D12/GaussianPlyLoader.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace XC3DGSD3D12 {
|
||||
|
||||
struct Float3 {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
};
|
||||
|
||||
struct GaussianSplatRuntimeData {
|
||||
static constexpr uint32_t kColorTextureWidth = 2048;
|
||||
static constexpr uint32_t kPositionStride = sizeof(float) * 3;
|
||||
static constexpr uint32_t kOtherStride = sizeof(uint32_t) + sizeof(float) * 3;
|
||||
static constexpr uint32_t kColorStride = sizeof(float) * 4;
|
||||
static constexpr uint32_t kShCoefficientCount = 15;
|
||||
static constexpr uint32_t kShStride = sizeof(float) * 3 * 16;
|
||||
|
||||
uint32_t splatCount = 0;
|
||||
uint32_t colorTextureWidth = kColorTextureWidth;
|
||||
uint32_t colorTextureHeight = 0;
|
||||
Float3 boundsMin = {};
|
||||
Float3 boundsMax = {};
|
||||
std::vector<std::byte> positionData;
|
||||
std::vector<std::byte> otherData;
|
||||
std::vector<std::byte> colorData;
|
||||
std::vector<std::byte> shData;
|
||||
};
|
||||
|
||||
bool LoadGaussianSceneFromPly(
|
||||
const std::filesystem::path& filePath,
|
||||
GaussianSplatRuntimeData& outData,
|
||||
std::string& outErrorMessage);
|
||||
|
||||
bool WriteGaussianSceneSummary(
|
||||
const std::filesystem::path& filePath,
|
||||
const GaussianSplatRuntimeData& data,
|
||||
std::string& outErrorMessage);
|
||||
|
||||
} // namespace XC3DGSD3D12
|
||||
43
MVS/3DGS-D3D12/shaders/BuildSortKeysCS.hlsl
Normal file
43
MVS/3DGS-D3D12/shaders/BuildSortKeysCS.hlsl
Normal file
@@ -0,0 +1,43 @@
|
||||
#define GROUP_SIZE 64
|
||||
|
||||
cbuffer FrameConstants : register(b0)
|
||||
{
|
||||
float4x4 gViewProjection;
|
||||
float4x4 gView;
|
||||
float4x4 gProjection;
|
||||
float4 gCameraWorldPos;
|
||||
float4 gScreenParams;
|
||||
float4 gSettings;
|
||||
};
|
||||
|
||||
ByteAddressBuffer gPositions : register(t0);
|
||||
StructuredBuffer<uint> gOrderBuffer : register(t1);
|
||||
RWStructuredBuffer<uint> gSortKeys : register(u0);
|
||||
|
||||
float3 LoadFloat3(ByteAddressBuffer buffer, uint byteOffset)
|
||||
{
|
||||
return asfloat(buffer.Load3(byteOffset));
|
||||
}
|
||||
|
||||
uint FloatToSortableUint(float value)
|
||||
{
|
||||
uint bits = asuint(value);
|
||||
uint mask = (0u - (bits >> 31)) | 0x80000000u;
|
||||
return bits ^ mask;
|
||||
}
|
||||
|
||||
[numthreads(GROUP_SIZE, 1, 1)]
|
||||
void MainCS(uint3 dispatchThreadId : SV_DispatchThreadID)
|
||||
{
|
||||
uint index = dispatchThreadId.x;
|
||||
uint splatCount = (uint)gSettings.x;
|
||||
if (index >= splatCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint splatIndex = gOrderBuffer[index];
|
||||
float3 position = LoadFloat3(gPositions, splatIndex * 12);
|
||||
float3 viewPosition = mul(float4(position, 1.0), gView).xyz;
|
||||
gSortKeys[index] = FloatToSortableUint(viewPosition.z);
|
||||
}
|
||||
12
MVS/3DGS-D3D12/shaders/CompositePS.hlsl
Normal file
12
MVS/3DGS-D3D12/shaders/CompositePS.hlsl
Normal file
@@ -0,0 +1,12 @@
|
||||
Texture2D<float4> gSplatTexture : register(t0);
|
||||
|
||||
struct PixelInput
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
};
|
||||
|
||||
float4 MainPS(PixelInput input) : SV_Target0
|
||||
{
|
||||
float4 color = gSplatTexture.Load(int3(int2(input.position.xy), 0));
|
||||
return float4(color.rgb, color.a);
|
||||
}
|
||||
12
MVS/3DGS-D3D12/shaders/CompositeVS.hlsl
Normal file
12
MVS/3DGS-D3D12/shaders/CompositeVS.hlsl
Normal file
@@ -0,0 +1,12 @@
|
||||
struct VertexOutput
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
};
|
||||
|
||||
VertexOutput MainVS(uint vertexId : SV_VertexID)
|
||||
{
|
||||
VertexOutput output = (VertexOutput)0;
|
||||
float2 quadPosition = float2(vertexId & 1, (vertexId >> 1) & 1) * 4.0 - 1.0;
|
||||
output.position = float4(quadPosition, 1.0, 1.0);
|
||||
return output;
|
||||
}
|
||||
19
MVS/3DGS-D3D12/shaders/DebugPointsPS.hlsl
Normal file
19
MVS/3DGS-D3D12/shaders/DebugPointsPS.hlsl
Normal file
@@ -0,0 +1,19 @@
|
||||
struct PixelInput
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float4 color : COLOR0;
|
||||
float2 localPosition : TEXCOORD0;
|
||||
};
|
||||
|
||||
float4 MainPS(PixelInput input) : SV_Target0
|
||||
{
|
||||
float alpha = exp(-dot(input.localPosition, input.localPosition));
|
||||
alpha = saturate(alpha * input.color.a);
|
||||
|
||||
if (alpha < (1.0 / 255.0))
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
return float4(input.color.rgb * alpha, alpha);
|
||||
}
|
||||
48
MVS/3DGS-D3D12/shaders/DebugPointsVS.hlsl
Normal file
48
MVS/3DGS-D3D12/shaders/DebugPointsVS.hlsl
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "PreparedSplatView.hlsli"
|
||||
|
||||
cbuffer FrameConstants : register(b0)
|
||||
{
|
||||
float4x4 gViewProjection;
|
||||
float4x4 gView;
|
||||
float4x4 gProjection;
|
||||
float4 gCameraWorldPos;
|
||||
float4 gScreenParams;
|
||||
float4 gSettings;
|
||||
};
|
||||
|
||||
StructuredBuffer<PreparedSplatView> gPreparedViews : register(t0);
|
||||
StructuredBuffer<uint> gOrderBuffer : register(t1);
|
||||
|
||||
struct VertexOutput
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float4 color : COLOR0;
|
||||
float2 localPosition : TEXCOORD0;
|
||||
};
|
||||
|
||||
VertexOutput MainVS(uint vertexId : SV_VertexID, uint instanceId : SV_InstanceID)
|
||||
{
|
||||
VertexOutput output = (VertexOutput)0;
|
||||
uint splatIndex = gOrderBuffer[instanceId];
|
||||
PreparedSplatView view = gPreparedViews[splatIndex];
|
||||
float4 color = UnpackPreparedColor(view);
|
||||
|
||||
if (view.clipPosition.w <= 0.0)
|
||||
{
|
||||
const float nanValue = asfloat(0x7fc00000);
|
||||
output.position = float4(nanValue, nanValue, nanValue, nanValue);
|
||||
return output;
|
||||
}
|
||||
|
||||
float2 quadPosition = float2(vertexId & 1, (vertexId >> 1) & 1) * 2.0 - 1.0;
|
||||
quadPosition *= 2.0;
|
||||
|
||||
float2 deltaScreenPosition =
|
||||
(quadPosition.x * view.axis1 + quadPosition.y * view.axis2) * 2.0 / gScreenParams.xy;
|
||||
|
||||
output.position = view.clipPosition;
|
||||
output.position.xy += deltaScreenPosition * view.clipPosition.w;
|
||||
output.color = color;
|
||||
output.localPosition = quadPosition;
|
||||
return output;
|
||||
}
|
||||
477
MVS/3DGS-D3D12/shaders/DeviceRadixSort.hlsl
Normal file
477
MVS/3DGS-D3D12/shaders/DeviceRadixSort.hlsl
Normal file
@@ -0,0 +1,477 @@
|
||||
/******************************************************************************
|
||||
* DeviceRadixSort
|
||||
* Device Level 8-bit LSD Radix Sort using reduce then scan
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
* Copyright Thomas Smith 5/17/2024
|
||||
* https://github.com/b0nes164/GPUSorting
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
#include "SortCommon.hlsl"
|
||||
|
||||
#define US_DIM 128U //The number of threads in a Upsweep threadblock
|
||||
#define SCAN_DIM 128U //The number of threads in a Scan threadblock
|
||||
|
||||
RWStructuredBuffer<uint> b_globalHist : register(u5); //buffer holding device level offsets for each binning pass
|
||||
RWStructuredBuffer<uint> b_passHist : register(u4); //buffer used to store reduced sums of partition tiles
|
||||
|
||||
groupshared uint g_us[RADIX * 2]; //Shared memory for upsweep
|
||||
groupshared uint g_scan[SCAN_DIM]; //Shared memory for the scan
|
||||
|
||||
//*****************************************************************************
|
||||
//INIT KERNEL
|
||||
//*****************************************************************************
|
||||
//Clear the global histogram, as we will be adding to it atomically
|
||||
[numthreads(1024, 1, 1)]
|
||||
void InitDeviceRadixSort(int3 id : SV_DispatchThreadID)
|
||||
{
|
||||
b_globalHist[id.x] = 0;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//UPSWEEP KERNEL
|
||||
//*****************************************************************************
|
||||
//histogram, 64 threads to a histogram
|
||||
inline void HistogramDigitCounts(uint gtid, uint gid)
|
||||
{
|
||||
const uint histOffset = gtid / 64 * RADIX;
|
||||
const uint partitionEnd = gid == e_threadBlocks - 1 ?
|
||||
e_numKeys : (gid + 1) * PART_SIZE;
|
||||
for (uint i = gtid + gid * PART_SIZE; i < partitionEnd; i += US_DIM)
|
||||
{
|
||||
#if defined(KEY_UINT)
|
||||
InterlockedAdd(g_us[ExtractDigit(b_sort[i]) + histOffset], 1);
|
||||
#elif defined(KEY_INT)
|
||||
InterlockedAdd(g_us[ExtractDigit(IntToUint(b_sort[i])) + histOffset], 1);
|
||||
#elif defined(KEY_FLOAT)
|
||||
InterlockedAdd(g_us[ExtractDigit(FloatToUint(b_sort[i])) + histOffset], 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//reduce and pass to tile histogram
|
||||
inline void ReduceWriteDigitCounts(uint gtid, uint gid)
|
||||
{
|
||||
for (uint i = gtid; i < RADIX; i += US_DIM)
|
||||
{
|
||||
g_us[i] += g_us[i + RADIX];
|
||||
b_passHist[i * e_threadBlocks + gid] = g_us[i];
|
||||
}
|
||||
}
|
||||
|
||||
//Build the per-pass 256-bin exclusive prefix from the reduced pass histogram.
|
||||
inline void BuildGlobalHistogramExclusive(uint gtid)
|
||||
{
|
||||
uint digitIndices[2];
|
||||
uint digitTotals[2];
|
||||
uint digitCount = 0;
|
||||
for (uint i = gtid; i < RADIX; i += US_DIM)
|
||||
{
|
||||
uint total = 0u;
|
||||
const uint baseOffset = i * e_threadBlocks;
|
||||
for (uint blockIndex = 0; blockIndex < e_threadBlocks; ++blockIndex)
|
||||
{
|
||||
total += b_passHist[baseOffset + blockIndex];
|
||||
}
|
||||
|
||||
g_us[i] = total;
|
||||
digitIndices[digitCount] = i;
|
||||
digitTotals[digitCount] = total;
|
||||
++digitCount;
|
||||
}
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
for (uint offset = 1; offset < RADIX; offset <<= 1)
|
||||
{
|
||||
for (uint i = gtid; i < RADIX; i += US_DIM)
|
||||
{
|
||||
g_us[i + RADIX] = g_us[i] + (i >= offset ? g_us[i - offset] : 0u);
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
for (uint i = gtid; i < RADIX; i += US_DIM)
|
||||
{
|
||||
g_us[i] = g_us[i + RADIX];
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
}
|
||||
|
||||
const uint globalHistOffset = GlobalHistOffset();
|
||||
for (uint localIndex = 0; localIndex < digitCount; ++localIndex)
|
||||
{
|
||||
const uint digitIndex = digitIndices[localIndex];
|
||||
b_globalHist[digitIndex + globalHistOffset] = g_us[digitIndex] - digitTotals[localIndex];
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(US_DIM, 1, 1)]
|
||||
void Upsweep(uint3 gtid : SV_GroupThreadID, uint3 gid : SV_GroupID)
|
||||
{
|
||||
//get the wave size
|
||||
const uint waveSize = getWaveSize();
|
||||
|
||||
//clear shared memory
|
||||
const uint histsEnd = RADIX * 2;
|
||||
for (uint i = gtid.x; i < histsEnd; i += US_DIM)
|
||||
g_us[i] = 0;
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
HistogramDigitCounts(gtid.x, gid.x);
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
ReduceWriteDigitCounts(gtid.x, gid.x);
|
||||
}
|
||||
|
||||
[numthreads(US_DIM, 1, 1)]
|
||||
void BuildGlobalHistogram(uint3 gtid : SV_GroupThreadID)
|
||||
{
|
||||
const uint histsEnd = RADIX * 2;
|
||||
for (uint i = gtid.x; i < histsEnd; i += US_DIM)
|
||||
g_us[i] = 0;
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
BuildGlobalHistogramExclusive(gtid.x);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//SCAN KERNEL
|
||||
//*****************************************************************************
|
||||
inline void ExclusiveThreadBlockScanFullWGE16(
|
||||
uint gtid,
|
||||
uint laneMask,
|
||||
uint circularLaneShift,
|
||||
uint partEnd,
|
||||
uint deviceOffset,
|
||||
uint waveSize,
|
||||
inout uint reduction)
|
||||
{
|
||||
for (uint i = gtid; i < partEnd; i += SCAN_DIM)
|
||||
{
|
||||
g_scan[gtid] = b_passHist[i + deviceOffset];
|
||||
g_scan[gtid] += WavePrefixSum(g_scan[gtid]);
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if (gtid < SCAN_DIM / waveSize)
|
||||
{
|
||||
g_scan[(gtid + 1) * waveSize - 1] +=
|
||||
WavePrefixSum(g_scan[(gtid + 1) * waveSize - 1]);
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
uint t = (WaveGetLaneIndex() != laneMask ? g_scan[gtid] : 0) + reduction;
|
||||
if (gtid >= waveSize)
|
||||
t += WaveReadLaneAt(g_scan[gtid - 1], 0);
|
||||
b_passHist[circularLaneShift + (i & ~laneMask) + deviceOffset] = t;
|
||||
|
||||
reduction += g_scan[SCAN_DIM - 1];
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
}
|
||||
}
|
||||
|
||||
inline void ExclusiveThreadBlockScanPartialWGE16(
|
||||
uint gtid,
|
||||
uint laneMask,
|
||||
uint circularLaneShift,
|
||||
uint partEnd,
|
||||
uint deviceOffset,
|
||||
uint waveSize,
|
||||
uint reduction)
|
||||
{
|
||||
uint i = gtid + partEnd;
|
||||
if (i < e_threadBlocks)
|
||||
g_scan[gtid] = b_passHist[deviceOffset + i];
|
||||
g_scan[gtid] += WavePrefixSum(g_scan[gtid]);
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if (gtid < SCAN_DIM / waveSize)
|
||||
{
|
||||
g_scan[(gtid + 1) * waveSize - 1] +=
|
||||
WavePrefixSum(g_scan[(gtid + 1) * waveSize - 1]);
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
const uint index = circularLaneShift + (i & ~laneMask);
|
||||
if (index < e_threadBlocks)
|
||||
{
|
||||
uint t = (WaveGetLaneIndex() != laneMask ? g_scan[gtid] : 0) + reduction;
|
||||
if (gtid >= waveSize)
|
||||
t += g_scan[(gtid & ~laneMask) - 1];
|
||||
b_passHist[index + deviceOffset] = t;
|
||||
}
|
||||
}
|
||||
|
||||
inline void ExclusiveThreadBlockScanWGE16(uint gtid, uint gid, uint waveSize)
|
||||
{
|
||||
uint reduction = 0;
|
||||
const uint laneMask = waveSize - 1;
|
||||
const uint circularLaneShift = WaveGetLaneIndex() + 1 & laneMask;
|
||||
const uint partionsEnd = e_threadBlocks / SCAN_DIM * SCAN_DIM;
|
||||
const uint deviceOffset = gid * e_threadBlocks;
|
||||
|
||||
ExclusiveThreadBlockScanFullWGE16(
|
||||
gtid,
|
||||
laneMask,
|
||||
circularLaneShift,
|
||||
partionsEnd,
|
||||
deviceOffset,
|
||||
waveSize,
|
||||
reduction);
|
||||
|
||||
ExclusiveThreadBlockScanPartialWGE16(
|
||||
gtid,
|
||||
laneMask,
|
||||
circularLaneShift,
|
||||
partionsEnd,
|
||||
deviceOffset,
|
||||
waveSize,
|
||||
reduction);
|
||||
}
|
||||
|
||||
inline void ExclusiveThreadBlockScanFullWLT16(
|
||||
uint gtid,
|
||||
uint partitions,
|
||||
uint deviceOffset,
|
||||
uint laneLog,
|
||||
uint circularLaneShift,
|
||||
uint waveSize,
|
||||
inout uint reduction)
|
||||
{
|
||||
for (uint k = 0; k < partitions; ++k)
|
||||
{
|
||||
g_scan[gtid] = b_passHist[gtid + k * SCAN_DIM + deviceOffset];
|
||||
g_scan[gtid] += WavePrefixSum(g_scan[gtid]);
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
if (gtid < waveSize)
|
||||
{
|
||||
b_passHist[circularLaneShift + k * SCAN_DIM + deviceOffset] =
|
||||
(circularLaneShift ? g_scan[gtid] : 0) + reduction;
|
||||
}
|
||||
|
||||
uint offset = laneLog;
|
||||
uint j = waveSize;
|
||||
for (; j < (SCAN_DIM >> 1); j <<= laneLog)
|
||||
{
|
||||
if (gtid < (SCAN_DIM >> offset))
|
||||
{
|
||||
g_scan[((gtid + 1) << offset) - 1] +=
|
||||
WavePrefixSum(g_scan[((gtid + 1) << offset) - 1]);
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if ((gtid & ((j << laneLog) - 1)) >= j)
|
||||
{
|
||||
if (gtid < (j << laneLog))
|
||||
{
|
||||
b_passHist[gtid + k * SCAN_DIM + deviceOffset] =
|
||||
WaveReadLaneAt(g_scan[((gtid >> offset) << offset) - 1], 0) +
|
||||
((gtid & (j - 1)) ? g_scan[gtid - 1] : 0) + reduction;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((gtid + 1) & (j - 1))
|
||||
{
|
||||
g_scan[gtid] +=
|
||||
WaveReadLaneAt(g_scan[((gtid >> offset) << offset) - 1], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
offset += laneLog;
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
//If SCAN_DIM is not a power of lanecount
|
||||
for (uint i = gtid + j; i < SCAN_DIM; i += SCAN_DIM)
|
||||
{
|
||||
b_passHist[i + k * SCAN_DIM + deviceOffset] =
|
||||
WaveReadLaneAt(g_scan[((i >> offset) << offset) - 1], 0) +
|
||||
((i & (j - 1)) ? g_scan[i - 1] : 0) + reduction;
|
||||
}
|
||||
|
||||
reduction += WaveReadLaneAt(g_scan[SCAN_DIM - 1], 0) +
|
||||
WaveReadLaneAt(g_scan[(((SCAN_DIM - 1) >> offset) << offset) - 1], 0);
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
}
|
||||
}
|
||||
|
||||
inline void ExclusiveThreadBlockScanParitalWLT16(
|
||||
uint gtid,
|
||||
uint partitions,
|
||||
uint deviceOffset,
|
||||
uint laneLog,
|
||||
uint circularLaneShift,
|
||||
uint waveSize,
|
||||
uint reduction)
|
||||
{
|
||||
const uint finalPartSize = e_threadBlocks - partitions * SCAN_DIM;
|
||||
if (gtid < finalPartSize)
|
||||
{
|
||||
g_scan[gtid] = b_passHist[gtid + partitions * SCAN_DIM + deviceOffset];
|
||||
g_scan[gtid] += WavePrefixSum(g_scan[gtid]);
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
if (gtid < waveSize && circularLaneShift < finalPartSize)
|
||||
{
|
||||
b_passHist[circularLaneShift + partitions * SCAN_DIM + deviceOffset] =
|
||||
(circularLaneShift ? g_scan[gtid] : 0) + reduction;
|
||||
}
|
||||
|
||||
uint offset = laneLog;
|
||||
for (uint j = waveSize; j < finalPartSize; j <<= laneLog)
|
||||
{
|
||||
if (gtid < (finalPartSize >> offset))
|
||||
{
|
||||
g_scan[((gtid + 1) << offset) - 1] +=
|
||||
WavePrefixSum(g_scan[((gtid + 1) << offset) - 1]);
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if ((gtid & ((j << laneLog) - 1)) >= j && gtid < finalPartSize)
|
||||
{
|
||||
if (gtid < (j << laneLog))
|
||||
{
|
||||
b_passHist[gtid + partitions * SCAN_DIM + deviceOffset] =
|
||||
WaveReadLaneAt(g_scan[((gtid >> offset) << offset) - 1], 0) +
|
||||
((gtid & (j - 1)) ? g_scan[gtid - 1] : 0) + reduction;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((gtid + 1) & (j - 1))
|
||||
{
|
||||
g_scan[gtid] +=
|
||||
WaveReadLaneAt(g_scan[((gtid >> offset) << offset) - 1], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
offset += laneLog;
|
||||
}
|
||||
}
|
||||
|
||||
inline void ExclusiveThreadBlockScanWLT16(uint gtid, uint gid, uint waveSize)
|
||||
{
|
||||
uint reduction = 0;
|
||||
const uint partitions = e_threadBlocks / SCAN_DIM;
|
||||
const uint deviceOffset = gid * e_threadBlocks;
|
||||
const uint laneLog = countbits(waveSize - 1);
|
||||
const uint circularLaneShift = WaveGetLaneIndex() + 1 & waveSize - 1;
|
||||
|
||||
ExclusiveThreadBlockScanFullWLT16(
|
||||
gtid,
|
||||
partitions,
|
||||
deviceOffset,
|
||||
laneLog,
|
||||
circularLaneShift,
|
||||
waveSize,
|
||||
reduction);
|
||||
|
||||
ExclusiveThreadBlockScanParitalWLT16(
|
||||
gtid,
|
||||
partitions,
|
||||
deviceOffset,
|
||||
laneLog,
|
||||
circularLaneShift,
|
||||
waveSize,
|
||||
reduction);
|
||||
}
|
||||
|
||||
//Scan does not need flattening of gids
|
||||
[numthreads(SCAN_DIM, 1, 1)]
|
||||
void Scan(uint3 gtid : SV_GroupThreadID, uint3 gid : SV_GroupID)
|
||||
{
|
||||
if (gtid.x != 0u)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const uint deviceOffset = gid.x * e_threadBlocks;
|
||||
uint runningOffset = 0u;
|
||||
for (uint blockIndex = 0u; blockIndex < e_threadBlocks; ++blockIndex)
|
||||
{
|
||||
const uint index = deviceOffset + blockIndex;
|
||||
const uint count = b_passHist[index];
|
||||
b_passHist[index] = runningOffset;
|
||||
runningOffset += count;
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//DOWNSWEEP KERNEL
|
||||
//*****************************************************************************
|
||||
inline void LoadThreadBlockReductions(uint gtid, uint gid, uint exclusiveHistReduction)
|
||||
{
|
||||
if (gtid < RADIX)
|
||||
{
|
||||
g_d[gtid + PART_SIZE] = b_globalHist[gtid + GlobalHistOffset()] +
|
||||
b_passHist[gtid * e_threadBlocks + gid] - exclusiveHistReduction;
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(D_DIM, 1, 1)]
|
||||
void Downsweep(uint3 gtid : SV_GroupThreadID, uint3 gid : SV_GroupID)
|
||||
{
|
||||
if (gtid.x != 0u)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const uint partitionStart = gid.x * PART_SIZE;
|
||||
const uint partitionEnd = min(partitionStart + PART_SIZE, e_numKeys);
|
||||
uint digitOffsets[RADIX];
|
||||
const uint globalHistOffset = GlobalHistOffset();
|
||||
for (uint digit = 0u; digit < RADIX; ++digit)
|
||||
{
|
||||
digitOffsets[digit] =
|
||||
b_globalHist[globalHistOffset + digit] +
|
||||
b_passHist[digit * e_threadBlocks + gid.x];
|
||||
}
|
||||
|
||||
for (uint index = partitionStart; index < partitionEnd; ++index)
|
||||
{
|
||||
uint key;
|
||||
#if defined(KEY_UINT)
|
||||
key = b_sort[index];
|
||||
#elif defined(KEY_INT)
|
||||
key = IntToUint(b_sort[index]);
|
||||
#elif defined(KEY_FLOAT)
|
||||
key = FloatToUint(b_sort[index]);
|
||||
#endif
|
||||
|
||||
const uint digit = ExtractDigit(key);
|
||||
const uint destinationIndex = digitOffsets[digit]++;
|
||||
|
||||
#if defined(KEY_UINT)
|
||||
b_alt[destinationIndex] = key;
|
||||
#elif defined(KEY_INT)
|
||||
b_alt[destinationIndex] = UintToInt(key);
|
||||
#elif defined(KEY_FLOAT)
|
||||
b_alt[destinationIndex] = UintToFloat(key);
|
||||
#endif
|
||||
|
||||
#if defined(SORT_PAIRS)
|
||||
#if defined(PAYLOAD_UINT)
|
||||
b_altPayload[destinationIndex] = b_sortPayload[index];
|
||||
#elif defined(PAYLOAD_INT)
|
||||
b_altPayload[destinationIndex] = b_sortPayload[index];
|
||||
#elif defined(PAYLOAD_FLOAT)
|
||||
b_altPayload[destinationIndex] = b_sortPayload[index];
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
272
MVS/3DGS-D3D12/shaders/PrepareGaussiansCS.hlsl
Normal file
272
MVS/3DGS-D3D12/shaders/PrepareGaussiansCS.hlsl
Normal file
@@ -0,0 +1,272 @@
|
||||
#include "PreparedSplatView.hlsli"
|
||||
|
||||
#define GROUP_SIZE 64
|
||||
|
||||
cbuffer FrameConstants : register(b0)
|
||||
{
|
||||
float4x4 gViewProjection;
|
||||
float4x4 gView;
|
||||
float4x4 gProjection;
|
||||
float4 gCameraWorldPos;
|
||||
float4 gScreenParams;
|
||||
float4 gSettings;
|
||||
};
|
||||
|
||||
ByteAddressBuffer gPositions : register(t0);
|
||||
ByteAddressBuffer gOther : register(t1);
|
||||
Texture2D<float4> gColor : register(t2);
|
||||
ByteAddressBuffer gSh : register(t3);
|
||||
RWStructuredBuffer<PreparedSplatView> gPreparedViews : register(u0);
|
||||
|
||||
static const float SH_C1 = 0.4886025;
|
||||
static const float SH_C2[] = { 1.0925484, -1.0925484, 0.3153916, -1.0925484, 0.5462742 };
|
||||
static const float SH_C3[] = { -0.5900436, 2.8906114, -0.4570458, 0.3731763, -0.4570458, 1.4453057, -0.5900436 };
|
||||
static const uint kColorTextureWidth = 2048;
|
||||
static const uint kOtherStride = 16;
|
||||
static const uint kShStride = 192;
|
||||
|
||||
struct SplatSHData
|
||||
{
|
||||
float3 col;
|
||||
float3 sh[15];
|
||||
};
|
||||
|
||||
float3 LoadFloat3(ByteAddressBuffer buffer, uint byteOffset)
|
||||
{
|
||||
return asfloat(buffer.Load3(byteOffset));
|
||||
}
|
||||
|
||||
uint EncodeMorton2D_16x16(uint2 c)
|
||||
{
|
||||
uint t = ((c.y & 0xF) << 8) | (c.x & 0xF);
|
||||
t = (t ^ (t << 2)) & 0x3333;
|
||||
t = (t ^ (t << 1)) & 0x5555;
|
||||
return (t | (t >> 7)) & 0xFF;
|
||||
}
|
||||
|
||||
uint2 DecodeMorton2D_16x16(uint t)
|
||||
{
|
||||
t = (t & 0xFF) | ((t & 0xFE) << 7);
|
||||
t &= 0x5555;
|
||||
t = (t ^ (t >> 1)) & 0x3333;
|
||||
t = (t ^ (t >> 2)) & 0x0F0F;
|
||||
return uint2(t & 0xF, t >> 8);
|
||||
}
|
||||
|
||||
uint3 SplatIndexToPixelIndex(uint index)
|
||||
{
|
||||
uint2 xy = DecodeMorton2D_16x16(index);
|
||||
uint tileWidth = kColorTextureWidth / 16;
|
||||
index >>= 8;
|
||||
|
||||
uint3 result;
|
||||
result.x = (index % tileWidth) * 16 + xy.x;
|
||||
result.y = (index / tileWidth) * 16 + xy.y;
|
||||
result.z = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 DecodePacked_10_10_10_2(uint encoded)
|
||||
{
|
||||
return float4(
|
||||
(encoded & 1023) / 1023.0,
|
||||
((encoded >> 10) & 1023) / 1023.0,
|
||||
((encoded >> 20) & 1023) / 1023.0,
|
||||
((encoded >> 30) & 3) / 3.0);
|
||||
}
|
||||
|
||||
float4 DecodeRotation(float4 packedRotation)
|
||||
{
|
||||
uint droppedIndex = (uint)round(packedRotation.w * 3.0);
|
||||
float4 rotation;
|
||||
rotation.xyz = packedRotation.xyz * sqrt(2.0) - (1.0 / sqrt(2.0));
|
||||
rotation.w = sqrt(1.0 - saturate(dot(rotation.xyz, rotation.xyz)));
|
||||
|
||||
if (droppedIndex == 0)
|
||||
{
|
||||
rotation = rotation.wxyz;
|
||||
}
|
||||
if (droppedIndex == 1)
|
||||
{
|
||||
rotation = rotation.xwyz;
|
||||
}
|
||||
if (droppedIndex == 2)
|
||||
{
|
||||
rotation = rotation.xywz;
|
||||
}
|
||||
|
||||
return rotation;
|
||||
}
|
||||
|
||||
float3x3 CalcMatrixFromRotationScale(float4 rotation, float3 scale)
|
||||
{
|
||||
float3x3 scaleMatrix = float3x3(
|
||||
scale.x, 0, 0,
|
||||
0, scale.y, 0,
|
||||
0, 0, scale.z);
|
||||
|
||||
float x = rotation.x;
|
||||
float y = rotation.y;
|
||||
float z = rotation.z;
|
||||
float w = rotation.w;
|
||||
|
||||
float3x3 rotationMatrix = float3x3(
|
||||
1 - 2 * (y * y + z * z), 2 * (x * y - w * z), 2 * (x * z + w * y),
|
||||
2 * (x * y + w * z), 1 - 2 * (x * x + z * z), 2 * (y * z - w * x),
|
||||
2 * (x * z - w * y), 2 * (y * z + w * x), 1 - 2 * (x * x + y * y));
|
||||
|
||||
return mul(rotationMatrix, scaleMatrix);
|
||||
}
|
||||
|
||||
void CalcCovariance3D(float3x3 rotationScaleMatrix, out float3 sigma0, out float3 sigma1)
|
||||
{
|
||||
float3x3 sigma = mul(rotationScaleMatrix, transpose(rotationScaleMatrix));
|
||||
sigma0 = float3(sigma._m00, sigma._m01, sigma._m02);
|
||||
sigma1 = float3(sigma._m11, sigma._m12, sigma._m22);
|
||||
}
|
||||
|
||||
float3 CalcCovariance2D(float3 worldPosition, float3 covariance0, float3 covariance1)
|
||||
{
|
||||
float3 viewPosition = mul(float4(worldPosition, 1.0), gView).xyz;
|
||||
|
||||
float aspect = gProjection._m00 / gProjection._m11;
|
||||
float tanFovX = rcp(gProjection._m00);
|
||||
float tanFovY = rcp(gProjection._m11 * aspect);
|
||||
float clampX = 1.3 * tanFovX;
|
||||
float clampY = 1.3 * tanFovY;
|
||||
viewPosition.x = clamp(viewPosition.x / viewPosition.z, -clampX, clampX) * viewPosition.z;
|
||||
viewPosition.y = clamp(viewPosition.y / viewPosition.z, -clampY, clampY) * viewPosition.z;
|
||||
|
||||
float focal = gScreenParams.x * gProjection._m00 * 0.5;
|
||||
|
||||
float3x3 jacobian = float3x3(
|
||||
focal / viewPosition.z, 0, -(focal * viewPosition.x) / (viewPosition.z * viewPosition.z),
|
||||
0, focal / viewPosition.z, -(focal * viewPosition.y) / (viewPosition.z * viewPosition.z),
|
||||
0, 0, 0);
|
||||
float3x3 worldToView = transpose((float3x3)gView);
|
||||
float3x3 transform = mul(jacobian, worldToView);
|
||||
float3x3 covariance = float3x3(
|
||||
covariance0.x, covariance0.y, covariance0.z,
|
||||
covariance0.y, covariance1.x, covariance1.y,
|
||||
covariance0.z, covariance1.y, covariance1.z);
|
||||
float3x3 projected = mul(transform, mul(covariance, transpose(transform)));
|
||||
projected._m00 += 0.3;
|
||||
projected._m11 += 0.3;
|
||||
return float3(projected._m00, projected._m01, projected._m11);
|
||||
}
|
||||
|
||||
void DecomposeCovariance(float3 covariance2D, out float2 axis1, out float2 axis2)
|
||||
{
|
||||
float diagonal0 = covariance2D.x;
|
||||
float diagonal1 = covariance2D.z;
|
||||
float offDiagonal = covariance2D.y;
|
||||
float mid = 0.5 * (diagonal0 + diagonal1);
|
||||
float radius = length(float2((diagonal0 - diagonal1) * 0.5, offDiagonal));
|
||||
float lambda0 = mid + radius;
|
||||
float lambda1 = max(mid - radius, 0.1);
|
||||
float2 diagonalVector = normalize(float2(offDiagonal, lambda0 - diagonal0));
|
||||
diagonalVector.y = -diagonalVector.y;
|
||||
const float maxSize = 4096.0;
|
||||
axis1 = min(sqrt(2.0 * lambda0), maxSize) * diagonalVector;
|
||||
axis2 = min(sqrt(2.0 * lambda1), maxSize) * float2(diagonalVector.y, -diagonalVector.x);
|
||||
}
|
||||
|
||||
SplatSHData LoadSplatSH(uint index)
|
||||
{
|
||||
SplatSHData sh;
|
||||
const uint shBaseOffset = index * kShStride;
|
||||
sh.col = gColor.Load(int3(SplatIndexToPixelIndex(index).xy, 0)).rgb;
|
||||
|
||||
[unroll]
|
||||
for (uint coefficientIndex = 0; coefficientIndex < 15; ++coefficientIndex)
|
||||
{
|
||||
sh.sh[coefficientIndex] = LoadFloat3(gSh, shBaseOffset + coefficientIndex * 12);
|
||||
}
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
float3 ShadeSH(SplatSHData sh, float3 direction, int shOrder)
|
||||
{
|
||||
direction *= -1.0;
|
||||
float x = direction.x;
|
||||
float y = direction.y;
|
||||
float z = direction.z;
|
||||
|
||||
float3 result = sh.col;
|
||||
if (shOrder >= 1)
|
||||
{
|
||||
result += SH_C1 * (-sh.sh[0] * y + sh.sh[1] * z - sh.sh[2] * x);
|
||||
if (shOrder >= 2)
|
||||
{
|
||||
float xx = x * x;
|
||||
float yy = y * y;
|
||||
float zz = z * z;
|
||||
float xy = x * y;
|
||||
float yz = y * z;
|
||||
float xz = x * z;
|
||||
result +=
|
||||
(SH_C2[0] * xy) * sh.sh[3] +
|
||||
(SH_C2[1] * yz) * sh.sh[4] +
|
||||
(SH_C2[2] * (2 * zz - xx - yy)) * sh.sh[5] +
|
||||
(SH_C2[3] * xz) * sh.sh[6] +
|
||||
(SH_C2[4] * (xx - yy)) * sh.sh[7];
|
||||
if (shOrder >= 3)
|
||||
{
|
||||
result +=
|
||||
(SH_C3[0] * y * (3 * xx - yy)) * sh.sh[8] +
|
||||
(SH_C3[1] * xy * z) * sh.sh[9] +
|
||||
(SH_C3[2] * y * (4 * zz - xx - yy)) * sh.sh[10] +
|
||||
(SH_C3[3] * z * (2 * zz - 3 * xx - 3 * yy)) * sh.sh[11] +
|
||||
(SH_C3[4] * x * (4 * zz - xx - yy)) * sh.sh[12] +
|
||||
(SH_C3[5] * z * (xx - yy)) * sh.sh[13] +
|
||||
(SH_C3[6] * x * (xx - 3 * yy)) * sh.sh[14];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return max(result, 0.0);
|
||||
}
|
||||
|
||||
[numthreads(GROUP_SIZE, 1, 1)]
|
||||
void MainCS(uint3 dispatchThreadId : SV_DispatchThreadID)
|
||||
{
|
||||
uint index = dispatchThreadId.x;
|
||||
uint splatCount = (uint)gSettings.x;
|
||||
if (index >= splatCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PreparedSplatView view = (PreparedSplatView)0;
|
||||
|
||||
float3 position = LoadFloat3(gPositions, index * 12);
|
||||
uint packedRotation = gOther.Load(index * kOtherStride);
|
||||
float4 rotation = DecodeRotation(DecodePacked_10_10_10_2(packedRotation));
|
||||
float3 scale = LoadFloat3(gOther, index * kOtherStride + 4);
|
||||
float4 colorOpacity = gColor.Load(int3(SplatIndexToPixelIndex(index).xy, 0));
|
||||
|
||||
view.clipPosition = mul(float4(position, 1.0), gViewProjection);
|
||||
if (view.clipPosition.w > 0.0)
|
||||
{
|
||||
float3x3 rotationScale = CalcMatrixFromRotationScale(rotation, scale);
|
||||
float3 covariance0;
|
||||
float3 covariance1;
|
||||
CalcCovariance3D(rotationScale, covariance0, covariance1);
|
||||
float splatScaleSquared = gSettings.w * gSettings.w;
|
||||
covariance0 *= splatScaleSquared;
|
||||
covariance1 *= splatScaleSquared;
|
||||
float3 covariance2D = CalcCovariance2D(position, covariance0, covariance1);
|
||||
DecomposeCovariance(covariance2D, view.axis1, view.axis2);
|
||||
|
||||
SplatSHData sh = LoadSplatSH(index);
|
||||
float3 viewDirection = normalize(gCameraWorldPos.xyz - position);
|
||||
float3 shadedColor = ShadeSH(sh, viewDirection, (int)gSettings.z);
|
||||
float opacity = saturate(colorOpacity.a * gSettings.y);
|
||||
|
||||
view.packedColor.x = (f32tof16(shadedColor.r) << 16) | f32tof16(shadedColor.g);
|
||||
view.packedColor.y = (f32tof16(shadedColor.b) << 16) | f32tof16(opacity);
|
||||
}
|
||||
|
||||
gPreparedViews[index] = view;
|
||||
}
|
||||
22
MVS/3DGS-D3D12/shaders/PreparedSplatView.hlsli
Normal file
22
MVS/3DGS-D3D12/shaders/PreparedSplatView.hlsli
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef PREPARED_SPLAT_VIEW_HLSLI
|
||||
#define PREPARED_SPLAT_VIEW_HLSLI
|
||||
|
||||
struct PreparedSplatView
|
||||
{
|
||||
float4 clipPosition;
|
||||
float2 axis1;
|
||||
float2 axis2;
|
||||
uint2 packedColor;
|
||||
};
|
||||
|
||||
float4 UnpackPreparedColor(PreparedSplatView view)
|
||||
{
|
||||
float4 color;
|
||||
color.r = f16tof32((view.packedColor.x >> 16) & 0xFFFF);
|
||||
color.g = f16tof32(view.packedColor.x & 0xFFFF);
|
||||
color.b = f16tof32((view.packedColor.y >> 16) & 0xFFFF);
|
||||
color.a = f16tof32(view.packedColor.y & 0xFFFF);
|
||||
return color;
|
||||
}
|
||||
|
||||
#endif
|
||||
959
MVS/3DGS-D3D12/shaders/SortCommon.hlsl
Normal file
959
MVS/3DGS-D3D12/shaders/SortCommon.hlsl
Normal file
@@ -0,0 +1,959 @@
|
||||
/******************************************************************************
|
||||
* SortCommon
|
||||
* Common functions for GPUSorting
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
* Copyright Thomas Smith 5/17/2024
|
||||
* https://github.com/b0nes164/GPUSorting
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
#define KEYS_PER_THREAD 15U
|
||||
#define D_DIM 256U
|
||||
#define PART_SIZE 3840U
|
||||
#define D_TOTAL_SMEM 4096U
|
||||
|
||||
#define RADIX 256U //Number of digit bins
|
||||
#define RADIX_MASK 255U //Mask of digit bins
|
||||
#define HALF_RADIX 128U //For smaller waves where bit packing is necessary
|
||||
#define HALF_MASK 127U // ''
|
||||
#define RADIX_LOG 8U //log2(RADIX)
|
||||
#define RADIX_PASSES 4U //(Key width) / RADIX_LOG
|
||||
|
||||
cbuffer cbGpuSorting : register(b0)
|
||||
{
|
||||
uint e_numKeys;
|
||||
uint e_radixShift;
|
||||
uint e_threadBlocks;
|
||||
uint padding;
|
||||
};
|
||||
|
||||
#if defined(KEY_UINT)
|
||||
RWStructuredBuffer<uint> b_sort : register(u0);
|
||||
RWStructuredBuffer<uint> b_alt : register(u1);
|
||||
#elif defined(KEY_INT)
|
||||
RWStructuredBuffer<int> b_sort : register(u0);
|
||||
RWStructuredBuffer<int> b_alt : register(u1);
|
||||
#elif defined(KEY_FLOAT)
|
||||
RWStructuredBuffer<float> b_sort : register(u0);
|
||||
RWStructuredBuffer<float> b_alt : register(u1);
|
||||
#endif
|
||||
|
||||
#if defined(PAYLOAD_UINT)
|
||||
RWStructuredBuffer<uint> b_sortPayload : register(u2);
|
||||
RWStructuredBuffer<uint> b_altPayload : register(u3);
|
||||
#elif defined(PAYLOAD_INT)
|
||||
RWStructuredBuffer<int> b_sortPayload : register(u2);
|
||||
RWStructuredBuffer<int> b_altPayload : register(u3);
|
||||
#elif defined(PAYLOAD_FLOAT)
|
||||
RWStructuredBuffer<float> b_sortPayload : register(u2);
|
||||
RWStructuredBuffer<float> b_altPayload : register(u3);
|
||||
#endif
|
||||
|
||||
groupshared uint g_d[D_TOTAL_SMEM]; //Shared memory for DigitBinningPass and DownSweep kernels
|
||||
|
||||
struct KeyStruct
|
||||
{
|
||||
uint k[KEYS_PER_THREAD];
|
||||
};
|
||||
|
||||
struct OffsetStruct
|
||||
{
|
||||
#if defined(ENABLE_16_BIT)
|
||||
uint16_t o[KEYS_PER_THREAD];
|
||||
#else
|
||||
uint o[KEYS_PER_THREAD];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct DigitStruct
|
||||
{
|
||||
#if defined(ENABLE_16_BIT)
|
||||
uint16_t d[KEYS_PER_THREAD];
|
||||
#else
|
||||
uint d[KEYS_PER_THREAD];
|
||||
#endif
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
//HELPER FUNCTIONS
|
||||
//*****************************************************************************
|
||||
//Due to a bug with SPIRV pre 1.6, we cannot use WaveGetLaneCount() to get the currently active wavesize
|
||||
inline uint getWaveSize()
|
||||
{
|
||||
#if defined(VULKAN)
|
||||
GroupMemoryBarrierWithGroupSync(); //Make absolutely sure the wave is not diverged here
|
||||
return dot(countbits(WaveActiveBallot(true)), uint4(1, 1, 1, 1));
|
||||
#else
|
||||
return WaveGetLaneCount();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint getWaveIndex(uint gtid, uint waveSize)
|
||||
{
|
||||
return gtid / waveSize;
|
||||
}
|
||||
|
||||
//Radix Tricks by Michael Herf
|
||||
//http://stereopsis.com/radix.html
|
||||
inline uint FloatToUint(float f)
|
||||
{
|
||||
uint mask = -((int) (asuint(f) >> 31)) | 0x80000000;
|
||||
return asuint(f) ^ mask;
|
||||
}
|
||||
|
||||
inline float UintToFloat(uint u)
|
||||
{
|
||||
uint mask = ((u >> 31) - 1) | 0x80000000;
|
||||
return asfloat(u ^ mask);
|
||||
}
|
||||
|
||||
inline uint IntToUint(int i)
|
||||
{
|
||||
return asuint(i ^ 0x80000000);
|
||||
}
|
||||
|
||||
inline int UintToInt(uint u)
|
||||
{
|
||||
return asint(u ^ 0x80000000);
|
||||
}
|
||||
|
||||
inline uint getWaveCountPass(uint waveSize)
|
||||
{
|
||||
return D_DIM / waveSize;
|
||||
}
|
||||
|
||||
inline uint ExtractDigit(uint key)
|
||||
{
|
||||
return key >> e_radixShift & RADIX_MASK;
|
||||
}
|
||||
|
||||
inline uint ExtractDigit(uint key, uint shift)
|
||||
{
|
||||
return key >> shift & RADIX_MASK;
|
||||
}
|
||||
|
||||
inline uint ExtractPackedIndex(uint key)
|
||||
{
|
||||
return key >> (e_radixShift + 1) & HALF_MASK;
|
||||
}
|
||||
|
||||
inline uint ExtractPackedShift(uint key)
|
||||
{
|
||||
return (key >> e_radixShift & 1) ? 16 : 0;
|
||||
}
|
||||
|
||||
inline uint ExtractPackedValue(uint packed, uint key)
|
||||
{
|
||||
return packed >> ExtractPackedShift(key) & 0xffff;
|
||||
}
|
||||
|
||||
inline uint SubPartSizeWGE16(uint waveSize)
|
||||
{
|
||||
return KEYS_PER_THREAD * waveSize;
|
||||
}
|
||||
|
||||
inline uint SharedOffsetWGE16(uint gtid, uint waveSize)
|
||||
{
|
||||
return WaveGetLaneIndex() + getWaveIndex(gtid, waveSize) * SubPartSizeWGE16(waveSize);
|
||||
}
|
||||
|
||||
inline uint SubPartSizeWLT16(uint waveSize, uint _serialIterations)
|
||||
{
|
||||
return KEYS_PER_THREAD * waveSize * _serialIterations;
|
||||
}
|
||||
|
||||
inline uint SharedOffsetWLT16(uint gtid, uint waveSize, uint _serialIterations)
|
||||
{
|
||||
return WaveGetLaneIndex() +
|
||||
(getWaveIndex(gtid, waveSize) / _serialIterations * SubPartSizeWLT16(waveSize, _serialIterations)) +
|
||||
(getWaveIndex(gtid, waveSize) % _serialIterations * waveSize);
|
||||
}
|
||||
|
||||
inline uint DeviceOffsetWGE16(uint gtid, uint waveSize, uint partIndex)
|
||||
{
|
||||
return SharedOffsetWGE16(gtid, waveSize) + partIndex * PART_SIZE;
|
||||
}
|
||||
|
||||
inline uint DeviceOffsetWLT16(uint gtid, uint waveSize, uint partIndex, uint serialIterations)
|
||||
{
|
||||
return SharedOffsetWLT16(gtid, waveSize, serialIterations) + partIndex * PART_SIZE;
|
||||
}
|
||||
|
||||
inline uint GlobalHistOffset()
|
||||
{
|
||||
return e_radixShift << 5;
|
||||
}
|
||||
|
||||
inline uint WaveHistsSizeWGE16(uint waveSize)
|
||||
{
|
||||
return D_DIM / waveSize * RADIX;
|
||||
}
|
||||
|
||||
inline uint WaveHistsSizeWLT16()
|
||||
{
|
||||
return D_TOTAL_SMEM;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//FUNCTIONS COMMON TO THE DOWNSWEEP / DIGIT BINNING PASS
|
||||
//*****************************************************************************
|
||||
//If the size of a wave is too small, we do not have enough space in
|
||||
//shared memory to assign a histogram to each wave, so instead,
|
||||
//some operations are peformed serially.
|
||||
inline uint SerialIterations(uint waveSize)
|
||||
{
|
||||
return (D_DIM / waveSize + 31) >> 5;
|
||||
}
|
||||
|
||||
inline void ClearWaveHists(uint gtid, uint waveSize)
|
||||
{
|
||||
const uint histsEnd = waveSize >= 16 ?
|
||||
WaveHistsSizeWGE16(waveSize) : WaveHistsSizeWLT16();
|
||||
for (uint i = gtid; i < histsEnd; i += D_DIM)
|
||||
g_d[i] = 0;
|
||||
}
|
||||
|
||||
inline void LoadKey(inout uint key, uint index)
|
||||
{
|
||||
#if defined(KEY_UINT)
|
||||
key = b_sort[index];
|
||||
#elif defined(KEY_INT)
|
||||
key = UintToInt(b_sort[index]);
|
||||
#elif defined(KEY_FLOAT)
|
||||
key = FloatToUint(b_sort[index]);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void LoadDummyKey(inout uint key)
|
||||
{
|
||||
key = 0xffffffff;
|
||||
}
|
||||
|
||||
inline KeyStruct LoadKeysWGE16(uint gtid, uint waveSize, uint partIndex)
|
||||
{
|
||||
KeyStruct keys;
|
||||
[unroll]
|
||||
for (uint i = 0, t = DeviceOffsetWGE16(gtid, waveSize, partIndex);
|
||||
i < KEYS_PER_THREAD;
|
||||
++i, t += waveSize)
|
||||
{
|
||||
LoadKey(keys.k[i], t);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
inline KeyStruct LoadKeysWLT16(uint gtid, uint waveSize, uint partIndex, uint serialIterations)
|
||||
{
|
||||
KeyStruct keys;
|
||||
[unroll]
|
||||
for (uint i = 0, t = DeviceOffsetWLT16(gtid, waveSize, partIndex, serialIterations);
|
||||
i < KEYS_PER_THREAD;
|
||||
++i, t += waveSize * serialIterations)
|
||||
{
|
||||
LoadKey(keys.k[i], t);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
inline KeyStruct LoadKeysPartialWGE16(uint gtid, uint waveSize, uint partIndex)
|
||||
{
|
||||
KeyStruct keys;
|
||||
[unroll]
|
||||
for (uint i = 0, t = DeviceOffsetWGE16(gtid, waveSize, partIndex);
|
||||
i < KEYS_PER_THREAD;
|
||||
++i, t += waveSize)
|
||||
{
|
||||
if (t < e_numKeys)
|
||||
LoadKey(keys.k[i], t);
|
||||
else
|
||||
LoadDummyKey(keys.k[i]);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
inline KeyStruct LoadKeysPartialWLT16(uint gtid, uint waveSize, uint partIndex, uint serialIterations)
|
||||
{
|
||||
KeyStruct keys;
|
||||
[unroll]
|
||||
for (uint i = 0, t = DeviceOffsetWLT16(gtid, waveSize, partIndex, serialIterations);
|
||||
i < KEYS_PER_THREAD;
|
||||
++i, t += waveSize * serialIterations)
|
||||
{
|
||||
if (t < e_numKeys)
|
||||
LoadKey(keys.k[i], t);
|
||||
else
|
||||
LoadDummyKey(keys.k[i]);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
inline uint WaveFlagsWGE16(uint waveSize)
|
||||
{
|
||||
return (waveSize & 31) ? (1U << waveSize) - 1 : 0xffffffff;
|
||||
}
|
||||
|
||||
inline uint WaveFlagsWLT16(uint waveSize)
|
||||
{
|
||||
return (1U << waveSize) - 1;;
|
||||
}
|
||||
|
||||
inline void WarpLevelMultiSplitWGE16(uint key, inout uint4 waveFlags)
|
||||
{
|
||||
[unroll]
|
||||
for (uint k = 0; k < RADIX_LOG; ++k)
|
||||
{
|
||||
const uint currentBit = 1U << (k + e_radixShift);
|
||||
const bool t = (key & currentBit) != 0;
|
||||
GroupMemoryBarrierWithGroupSync(); //Play on the safe side, throw in a barrier for convergence
|
||||
const uint4 ballot = WaveActiveBallot(t);
|
||||
if(t)
|
||||
waveFlags &= ballot;
|
||||
else
|
||||
waveFlags &= (~ballot);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint2 CountBitsWGE16(uint waveSize, uint ltMask, uint4 waveFlags)
|
||||
{
|
||||
uint2 count = uint2(0, 0);
|
||||
|
||||
for(uint wavePart = 0; wavePart < waveSize; wavePart += 32)
|
||||
{
|
||||
uint t = countbits(waveFlags[wavePart >> 5]);
|
||||
if (WaveGetLaneIndex() >= wavePart)
|
||||
{
|
||||
if (WaveGetLaneIndex() >= wavePart + 32)
|
||||
count.x += t;
|
||||
else
|
||||
count.x += countbits(waveFlags[wavePart >> 5] & ltMask);
|
||||
}
|
||||
count.y += t;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
inline void WarpLevelMultiSplitWLT16(uint key, inout uint waveFlags)
|
||||
{
|
||||
[unroll]
|
||||
for (uint k = 0; k < RADIX_LOG; ++k)
|
||||
{
|
||||
const bool t = key >> (k + e_radixShift) & 1;
|
||||
waveFlags &= (t ? 0 : 0xffffffff) ^ (uint) WaveActiveBallot(t);
|
||||
}
|
||||
}
|
||||
|
||||
inline OffsetStruct RankKeysWGE16(
|
||||
uint waveSize,
|
||||
uint waveOffset,
|
||||
KeyStruct keys)
|
||||
{
|
||||
OffsetStruct offsets;
|
||||
const uint initialFlags = WaveFlagsWGE16(waveSize);
|
||||
const uint ltMask = (1U << (WaveGetLaneIndex() & 31)) - 1;
|
||||
|
||||
[unroll]
|
||||
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
|
||||
{
|
||||
uint4 waveFlags = initialFlags;
|
||||
WarpLevelMultiSplitWGE16(keys.k[i], waveFlags);
|
||||
|
||||
const uint index = ExtractDigit(keys.k[i]) + waveOffset;
|
||||
const uint2 bitCount = CountBitsWGE16(waveSize, ltMask, waveFlags);
|
||||
|
||||
offsets.o[i] = g_d[index] + bitCount.x;
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
if (bitCount.x == 0)
|
||||
g_d[index] += bitCount.y;
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
}
|
||||
|
||||
return offsets;
|
||||
}
|
||||
|
||||
inline OffsetStruct RankKeysWLT16(uint waveSize, uint waveIndex, KeyStruct keys, uint serialIterations)
|
||||
{
|
||||
OffsetStruct offsets;
|
||||
const uint ltMask = (1U << WaveGetLaneIndex()) - 1;
|
||||
const uint initialFlags = WaveFlagsWLT16(waveSize);
|
||||
|
||||
[unroll]
|
||||
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
|
||||
{
|
||||
uint waveFlags = initialFlags;
|
||||
WarpLevelMultiSplitWLT16(keys.k[i], waveFlags);
|
||||
|
||||
const uint index = ExtractPackedIndex(keys.k[i]) +
|
||||
(waveIndex / serialIterations * HALF_RADIX);
|
||||
|
||||
const uint peerBits = countbits(waveFlags & ltMask);
|
||||
for (uint k = 0; k < serialIterations; ++k)
|
||||
{
|
||||
if (waveIndex % serialIterations == k)
|
||||
offsets.o[i] = ExtractPackedValue(g_d[index], keys.k[i]) + peerBits;
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
if (waveIndex % serialIterations == k && peerBits == 0)
|
||||
{
|
||||
InterlockedAdd(g_d[index],
|
||||
countbits(waveFlags) << ExtractPackedShift(keys.k[i]));
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
}
|
||||
}
|
||||
|
||||
return offsets;
|
||||
}
|
||||
|
||||
inline uint WaveHistInclusiveScanCircularShiftWGE16(uint gtid, uint waveSize)
|
||||
{
|
||||
uint histReduction = g_d[gtid];
|
||||
for (uint i = gtid + RADIX; i < WaveHistsSizeWGE16(waveSize); i += RADIX)
|
||||
{
|
||||
histReduction += g_d[i];
|
||||
g_d[i] = histReduction - g_d[i];
|
||||
}
|
||||
return histReduction;
|
||||
}
|
||||
|
||||
inline uint WaveHistInclusiveScanCircularShiftWLT16(uint gtid)
|
||||
{
|
||||
uint histReduction = g_d[gtid];
|
||||
for (uint i = gtid + HALF_RADIX; i < WaveHistsSizeWLT16(); i += HALF_RADIX)
|
||||
{
|
||||
histReduction += g_d[i];
|
||||
g_d[i] = histReduction - g_d[i];
|
||||
}
|
||||
return histReduction;
|
||||
}
|
||||
|
||||
inline void WaveHistReductionExclusiveScanWGE16(uint gtid, uint waveSize, uint histReduction)
|
||||
{
|
||||
if (gtid < RADIX)
|
||||
{
|
||||
const uint laneMask = waveSize - 1;
|
||||
g_d[((WaveGetLaneIndex() + 1) & laneMask) + (gtid & ~laneMask)] = histReduction;
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if (gtid < RADIX / waveSize)
|
||||
{
|
||||
g_d[gtid * waveSize] =
|
||||
WavePrefixSum(g_d[gtid * waveSize]);
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
uint t = WaveReadLaneAt(g_d[gtid], 0);
|
||||
if (gtid < RADIX && WaveGetLaneIndex())
|
||||
g_d[gtid] += t;
|
||||
}
|
||||
|
||||
//inclusive/exclusive prefix sum up the histograms,
|
||||
//use a blelloch scan for in place packed exclusive
|
||||
inline void WaveHistReductionExclusiveScanWLT16(uint gtid)
|
||||
{
|
||||
uint shift = 1;
|
||||
for (uint j = RADIX >> 2; j > 0; j >>= 1)
|
||||
{
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
if (gtid < j)
|
||||
{
|
||||
g_d[((((gtid << 1) + 2) << shift) - 1) >> 1] +=
|
||||
g_d[((((gtid << 1) + 1) << shift) - 1) >> 1] & 0xffff0000;
|
||||
}
|
||||
shift++;
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if (gtid == 0)
|
||||
g_d[HALF_RADIX - 1] &= 0xffff;
|
||||
|
||||
for (uint j = 1; j < RADIX >> 1; j <<= 1)
|
||||
{
|
||||
--shift;
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
if (gtid < j)
|
||||
{
|
||||
const uint t = ((((gtid << 1) + 1) << shift) - 1) >> 1;
|
||||
const uint t2 = ((((gtid << 1) + 2) << shift) - 1) >> 1;
|
||||
const uint t3 = g_d[t];
|
||||
g_d[t] = (g_d[t] & 0xffff) | (g_d[t2] & 0xffff0000);
|
||||
g_d[t2] += t3 & 0xffff0000;
|
||||
}
|
||||
}
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
if (gtid < HALF_RADIX)
|
||||
{
|
||||
const uint t = g_d[gtid];
|
||||
g_d[gtid] = (t >> 16) + (t << 16) + (t & 0xffff0000);
|
||||
}
|
||||
}
|
||||
|
||||
inline void UpdateOffsetsWGE16(
|
||||
uint gtid,
|
||||
uint waveSize,
|
||||
inout OffsetStruct offsets,
|
||||
KeyStruct keys)
|
||||
{
|
||||
if (gtid >= waveSize)
|
||||
{
|
||||
const uint t = getWaveIndex(gtid, waveSize) * RADIX;
|
||||
[unroll]
|
||||
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
|
||||
{
|
||||
const uint t2 = ExtractDigit(keys.k[i]);
|
||||
offsets.o[i] += g_d[t2 + t] + g_d[t2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
|
||||
offsets.o[i] += g_d[ExtractDigit(keys.k[i])];
|
||||
}
|
||||
}
|
||||
|
||||
inline void UpdateOffsetsWLT16(
|
||||
uint gtid,
|
||||
uint waveSize,
|
||||
uint serialIterations,
|
||||
inout OffsetStruct offsets,
|
||||
KeyStruct keys)
|
||||
{
|
||||
if (gtid >= waveSize * serialIterations)
|
||||
{
|
||||
const uint t = getWaveIndex(gtid, waveSize) / serialIterations * HALF_RADIX;
|
||||
[unroll]
|
||||
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
|
||||
{
|
||||
const uint t2 = ExtractPackedIndex(keys.k[i]);
|
||||
offsets.o[i] += ExtractPackedValue(g_d[t2 + t] + g_d[t2], keys.k[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
|
||||
offsets.o[i] += ExtractPackedValue(g_d[ExtractPackedIndex(keys.k[i])], keys.k[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterKeysShared(OffsetStruct offsets, KeyStruct keys)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
|
||||
g_d[offsets.o[i]] = keys.k[i];
|
||||
}
|
||||
|
||||
inline uint DescendingIndex(uint deviceIndex)
|
||||
{
|
||||
return e_numKeys - deviceIndex - 1;
|
||||
}
|
||||
|
||||
inline void WriteKey(uint deviceIndex, uint groupSharedIndex)
|
||||
{
|
||||
#if defined(KEY_UINT)
|
||||
b_alt[deviceIndex] = g_d[groupSharedIndex];
|
||||
#elif defined(KEY_INT)
|
||||
b_alt[deviceIndex] = UintToInt(g_d[groupSharedIndex]);
|
||||
#elif defined(KEY_FLOAT)
|
||||
b_alt[deviceIndex] = UintToFloat(g_d[groupSharedIndex]);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void LoadPayload(inout uint payload, uint deviceIndex)
|
||||
{
|
||||
#if defined(PAYLOAD_UINT)
|
||||
payload = b_sortPayload[deviceIndex];
|
||||
#elif defined(PAYLOAD_INT) || defined(PAYLOAD_FLOAT)
|
||||
payload = asuint(b_sortPayload[deviceIndex]);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void ScatterPayloadsShared(OffsetStruct offsets, KeyStruct payloads)
|
||||
{
|
||||
ScatterKeysShared(offsets, payloads);
|
||||
}
|
||||
|
||||
inline void WritePayload(uint deviceIndex, uint groupSharedIndex)
|
||||
{
|
||||
#if defined(PAYLOAD_UINT)
|
||||
b_altPayload[deviceIndex] = g_d[groupSharedIndex];
|
||||
#elif defined(PAYLOAD_INT)
|
||||
b_altPayload[deviceIndex] = asint(g_d[groupSharedIndex]);
|
||||
#elif defined(PAYLOAD_FLOAT)
|
||||
b_altPayload[deviceIndex] = asfloat(g_d[groupSharedIndex]);
|
||||
#endif
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//SCATTERING: FULL PARTITIONS
|
||||
//*****************************************************************************
|
||||
//KEYS ONLY
|
||||
inline void ScatterKeysOnlyDeviceAscending(uint gtid)
|
||||
{
|
||||
for (uint i = gtid; i < PART_SIZE; i += D_DIM)
|
||||
WriteKey(g_d[ExtractDigit(g_d[i]) + PART_SIZE] + i, i);
|
||||
}
|
||||
|
||||
inline void ScatterKeysOnlyDeviceDescending(uint gtid)
|
||||
{
|
||||
if (e_radixShift == 24)
|
||||
{
|
||||
for (uint i = gtid; i < PART_SIZE; i += D_DIM)
|
||||
WriteKey(DescendingIndex(g_d[ExtractDigit(g_d[i]) + PART_SIZE] + i), i);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScatterKeysOnlyDeviceAscending(gtid);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterKeysOnlyDevice(uint gtid)
|
||||
{
|
||||
#if defined(SHOULD_ASCEND)
|
||||
ScatterKeysOnlyDeviceAscending(gtid);
|
||||
#else
|
||||
ScatterKeysOnlyDeviceDescending(gtid);
|
||||
#endif
|
||||
}
|
||||
|
||||
//KEY VALUE PAIRS
|
||||
inline void ScatterPairsKeyPhaseAscending(
|
||||
uint gtid,
|
||||
inout DigitStruct digits)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
|
||||
{
|
||||
digits.d[i] = ExtractDigit(g_d[t]);
|
||||
WriteKey(g_d[digits.d[i] + PART_SIZE] + t, t);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterPairsKeyPhaseDescending(
|
||||
uint gtid,
|
||||
inout DigitStruct digits)
|
||||
{
|
||||
if (e_radixShift == 24)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
|
||||
{
|
||||
digits.d[i] = ExtractDigit(g_d[t]);
|
||||
WriteKey(DescendingIndex(g_d[digits.d[i] + PART_SIZE] + t), t);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ScatterPairsKeyPhaseAscending(gtid, digits);
|
||||
}
|
||||
}
|
||||
|
||||
inline void LoadPayloadsWGE16(
|
||||
uint gtid,
|
||||
uint waveSize,
|
||||
uint partIndex,
|
||||
inout KeyStruct payloads)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = DeviceOffsetWGE16(gtid, waveSize, partIndex);
|
||||
i < KEYS_PER_THREAD;
|
||||
++i, t += waveSize)
|
||||
{
|
||||
LoadPayload(payloads.k[i], t);
|
||||
}
|
||||
}
|
||||
|
||||
inline void LoadPayloadsWLT16(
|
||||
uint gtid,
|
||||
uint waveSize,
|
||||
uint partIndex,
|
||||
uint serialIterations,
|
||||
inout KeyStruct payloads)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = DeviceOffsetWLT16(gtid, waveSize, partIndex, serialIterations);
|
||||
i < KEYS_PER_THREAD;
|
||||
++i, t += waveSize * serialIterations)
|
||||
{
|
||||
LoadPayload(payloads.k[i], t);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterPayloadsAscending(uint gtid, DigitStruct digits)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
|
||||
WritePayload(g_d[digits.d[i] + PART_SIZE] + t, t);
|
||||
}
|
||||
|
||||
inline void ScatterPayloadsDescending(uint gtid, DigitStruct digits)
|
||||
{
|
||||
if (e_radixShift == 24)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
|
||||
WritePayload(DescendingIndex(g_d[digits.d[i] + PART_SIZE] + t), t);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScatterPayloadsAscending(gtid, digits);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterPairsDevice(
|
||||
uint gtid,
|
||||
uint waveSize,
|
||||
uint partIndex,
|
||||
OffsetStruct offsets)
|
||||
{
|
||||
DigitStruct digits;
|
||||
#if defined(SHOULD_ASCEND)
|
||||
ScatterPairsKeyPhaseAscending(gtid, digits);
|
||||
#else
|
||||
ScatterPairsKeyPhaseDescending(gtid, digits);
|
||||
#endif
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
KeyStruct payloads;
|
||||
if (waveSize >= 16)
|
||||
LoadPayloadsWGE16(gtid, waveSize, partIndex, payloads);
|
||||
else
|
||||
LoadPayloadsWLT16(gtid, waveSize, partIndex, SerialIterations(waveSize), payloads);
|
||||
ScatterPayloadsShared(offsets, payloads);
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
#if defined(SHOULD_ASCEND)
|
||||
ScatterPayloadsAscending(gtid, digits);
|
||||
#else
|
||||
ScatterPayloadsDescending(gtid, digits);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void ScatterDevice(
|
||||
uint gtid,
|
||||
uint waveSize,
|
||||
uint partIndex,
|
||||
OffsetStruct offsets)
|
||||
{
|
||||
#if defined(SORT_PAIRS)
|
||||
ScatterPairsDevice(
|
||||
gtid,
|
||||
waveSize,
|
||||
partIndex,
|
||||
offsets);
|
||||
#else
|
||||
ScatterKeysOnlyDevice(gtid);
|
||||
#endif
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//SCATTERING: PARTIAL PARTITIONS
|
||||
//*****************************************************************************
|
||||
//KEYS ONLY
|
||||
inline void ScatterKeysOnlyDevicePartialAscending(uint gtid, uint finalPartSize)
|
||||
{
|
||||
for (uint i = gtid; i < PART_SIZE; i += D_DIM)
|
||||
{
|
||||
if (i < finalPartSize)
|
||||
WriteKey(g_d[ExtractDigit(g_d[i]) + PART_SIZE] + i, i);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterKeysOnlyDevicePartialDescending(uint gtid, uint finalPartSize)
|
||||
{
|
||||
if (e_radixShift == 24)
|
||||
{
|
||||
for (uint i = gtid; i < PART_SIZE; i += D_DIM)
|
||||
{
|
||||
if (i < finalPartSize)
|
||||
WriteKey(DescendingIndex(g_d[ExtractDigit(g_d[i]) + PART_SIZE] + i), i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ScatterKeysOnlyDevicePartialAscending(gtid, finalPartSize);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterKeysOnlyDevicePartial(uint gtid, uint partIndex)
|
||||
{
|
||||
const uint finalPartSize = e_numKeys - partIndex * PART_SIZE;
|
||||
#if defined(SHOULD_ASCEND)
|
||||
ScatterKeysOnlyDevicePartialAscending(gtid, finalPartSize);
|
||||
#else
|
||||
ScatterKeysOnlyDevicePartialDescending(gtid, finalPartSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
//KEY VALUE PAIRS
|
||||
inline void ScatterPairsKeyPhaseAscendingPartial(
|
||||
uint gtid,
|
||||
uint finalPartSize,
|
||||
inout DigitStruct digits)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
|
||||
{
|
||||
if (t < finalPartSize)
|
||||
{
|
||||
digits.d[i] = ExtractDigit(g_d[t]);
|
||||
WriteKey(g_d[digits.d[i] + PART_SIZE] + t, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterPairsKeyPhaseDescendingPartial(
|
||||
uint gtid,
|
||||
uint finalPartSize,
|
||||
inout DigitStruct digits)
|
||||
{
|
||||
if (e_radixShift == 24)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
|
||||
{
|
||||
if (t < finalPartSize)
|
||||
{
|
||||
digits.d[i] = ExtractDigit(g_d[t]);
|
||||
WriteKey(DescendingIndex(g_d[digits.d[i] + PART_SIZE] + t), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ScatterPairsKeyPhaseAscendingPartial(gtid, finalPartSize, digits);
|
||||
}
|
||||
}
|
||||
|
||||
inline void LoadPayloadsPartialWGE16(
|
||||
uint gtid,
|
||||
uint waveSize,
|
||||
uint partIndex,
|
||||
inout KeyStruct payloads)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = DeviceOffsetWGE16(gtid, waveSize, partIndex);
|
||||
i < KEYS_PER_THREAD;
|
||||
++i, t += waveSize)
|
||||
{
|
||||
if (t < e_numKeys)
|
||||
LoadPayload(payloads.k[i], t);
|
||||
}
|
||||
}
|
||||
|
||||
inline void LoadPayloadsPartialWLT16(
|
||||
uint gtid,
|
||||
uint waveSize,
|
||||
uint partIndex,
|
||||
uint serialIterations,
|
||||
inout KeyStruct payloads)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = DeviceOffsetWLT16(gtid, waveSize, partIndex, serialIterations);
|
||||
i < KEYS_PER_THREAD;
|
||||
++i, t += waveSize * serialIterations)
|
||||
{
|
||||
if (t < e_numKeys)
|
||||
LoadPayload(payloads.k[i], t);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterPayloadsAscendingPartial(
|
||||
uint gtid,
|
||||
uint finalPartSize,
|
||||
DigitStruct digits)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
|
||||
{
|
||||
if (t < finalPartSize)
|
||||
WritePayload(g_d[digits.d[i] + PART_SIZE] + t, t);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterPayloadsDescendingPartial(
|
||||
uint gtid,
|
||||
uint finalPartSize,
|
||||
DigitStruct digits)
|
||||
{
|
||||
if (e_radixShift == 24)
|
||||
{
|
||||
[unroll]
|
||||
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
|
||||
{
|
||||
if (t < finalPartSize)
|
||||
WritePayload(DescendingIndex(g_d[digits.d[i] + PART_SIZE] + t), t);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ScatterPayloadsAscendingPartial(gtid, finalPartSize, digits);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ScatterPairsDevicePartial(
|
||||
uint gtid,
|
||||
uint waveSize,
|
||||
uint partIndex,
|
||||
OffsetStruct offsets)
|
||||
{
|
||||
DigitStruct digits;
|
||||
const uint finalPartSize = e_numKeys - partIndex * PART_SIZE;
|
||||
#if defined(SHOULD_ASCEND)
|
||||
ScatterPairsKeyPhaseAscendingPartial(gtid, finalPartSize, digits);
|
||||
#else
|
||||
ScatterPairsKeyPhaseDescendingPartial(gtid, finalPartSize, digits);
|
||||
#endif
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
KeyStruct payloads;
|
||||
if (waveSize >= 16)
|
||||
LoadPayloadsPartialWGE16(gtid, waveSize, partIndex, payloads);
|
||||
else
|
||||
LoadPayloadsPartialWLT16(gtid, waveSize, partIndex, SerialIterations(waveSize), payloads);
|
||||
ScatterPayloadsShared(offsets, payloads);
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
#if defined(SHOULD_ASCEND)
|
||||
ScatterPayloadsAscendingPartial(gtid, finalPartSize, digits);
|
||||
#else
|
||||
ScatterPayloadsDescendingPartial(gtid, finalPartSize, digits);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void ScatterDevicePartial(
|
||||
uint gtid,
|
||||
uint waveSize,
|
||||
uint partIndex,
|
||||
OffsetStruct offsets)
|
||||
{
|
||||
#if defined(SORT_PAIRS)
|
||||
ScatterPairsDevicePartial(
|
||||
gtid,
|
||||
waveSize,
|
||||
partIndex,
|
||||
offsets);
|
||||
#else
|
||||
ScatterKeysOnlyDevicePartial(gtid, partIndex);
|
||||
#endif
|
||||
}
|
||||
2193
MVS/3DGS-D3D12/src/App.cpp
Normal file
2193
MVS/3DGS-D3D12/src/App.cpp
Normal file
File diff suppressed because it is too large
Load Diff
617
MVS/3DGS-D3D12/src/GaussianPlyLoader.cpp
Normal file
617
MVS/3DGS-D3D12/src/GaussianPlyLoader.cpp
Normal file
@@ -0,0 +1,617 @@
|
||||
#include "XC3DGSD3D12/GaussianPlyLoader.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace XC3DGSD3D12 {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr float kSHC0 = 0.2820948f;
|
||||
|
||||
enum class PlyPropertyType {
|
||||
None,
|
||||
Float32,
|
||||
Float64,
|
||||
UInt8,
|
||||
};
|
||||
|
||||
struct PlyProperty {
|
||||
std::string name;
|
||||
PlyPropertyType type = PlyPropertyType::None;
|
||||
uint32_t offset = 0;
|
||||
uint32_t size = 0;
|
||||
};
|
||||
|
||||
struct PlyHeader {
|
||||
uint32_t vertexCount = 0;
|
||||
uint32_t vertexStride = 0;
|
||||
std::vector<PlyProperty> properties;
|
||||
};
|
||||
|
||||
struct Float4 {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
float w = 0.0f;
|
||||
};
|
||||
|
||||
struct RawGaussianSplat {
|
||||
Float3 position = {};
|
||||
Float3 dc0 = {};
|
||||
std::array<Float3, GaussianSplatRuntimeData::kShCoefficientCount> sh = {};
|
||||
float opacity = 0.0f;
|
||||
Float3 scale = {};
|
||||
Float4 rotation = {};
|
||||
};
|
||||
|
||||
struct GaussianPlyPropertyLayout {
|
||||
const PlyProperty* position[3] = {};
|
||||
const PlyProperty* dc0[3] = {};
|
||||
const PlyProperty* opacity = nullptr;
|
||||
const PlyProperty* scale[3] = {};
|
||||
const PlyProperty* rotation[4] = {};
|
||||
std::array<const PlyProperty*, GaussianSplatRuntimeData::kShCoefficientCount * 3> sh = {};
|
||||
};
|
||||
|
||||
std::string TrimTrailingCarriageReturn(std::string line) {
|
||||
if (!line.empty() && line.back() == '\r') {
|
||||
line.pop_back();
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
uint32_t PropertyTypeSize(PlyPropertyType type) {
|
||||
switch (type) {
|
||||
case PlyPropertyType::Float32:
|
||||
return 4;
|
||||
case PlyPropertyType::Float64:
|
||||
return 8;
|
||||
case PlyPropertyType::UInt8:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ParsePropertyType(const std::string& token, PlyPropertyType& outType) {
|
||||
if (token == "float") {
|
||||
outType = PlyPropertyType::Float32;
|
||||
return true;
|
||||
}
|
||||
if (token == "double") {
|
||||
outType = PlyPropertyType::Float64;
|
||||
return true;
|
||||
}
|
||||
if (token == "uchar") {
|
||||
outType = PlyPropertyType::UInt8;
|
||||
return true;
|
||||
}
|
||||
|
||||
outType = PlyPropertyType::None;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParsePlyHeader(std::ifstream& input, PlyHeader& outHeader, std::string& outErrorMessage) {
|
||||
std::string line;
|
||||
if (!std::getline(input, line)) {
|
||||
outErrorMessage = "Failed to read PLY magic line.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TrimTrailingCarriageReturn(line) != "ply") {
|
||||
outErrorMessage = "Input file is not a valid PLY file.";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sawFormat = false;
|
||||
std::string currentElement;
|
||||
|
||||
while (std::getline(input, line)) {
|
||||
line = TrimTrailingCarriageReturn(line);
|
||||
if (line == "end_header") {
|
||||
break;
|
||||
}
|
||||
|
||||
if (line.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::istringstream stream(line);
|
||||
std::string token;
|
||||
stream >> token;
|
||||
|
||||
if (token == "comment") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token == "format") {
|
||||
std::string formatName;
|
||||
std::string version;
|
||||
stream >> formatName >> version;
|
||||
if (formatName != "binary_little_endian") {
|
||||
outErrorMessage = "Only binary_little_endian PLY files are supported.";
|
||||
return false;
|
||||
}
|
||||
sawFormat = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token == "element") {
|
||||
stream >> currentElement;
|
||||
if (currentElement == "vertex") {
|
||||
stream >> outHeader.vertexCount;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token == "property" && currentElement == "vertex") {
|
||||
std::string typeToken;
|
||||
std::string name;
|
||||
stream >> typeToken >> name;
|
||||
|
||||
PlyPropertyType propertyType = PlyPropertyType::None;
|
||||
if (!ParsePropertyType(typeToken, propertyType)) {
|
||||
outErrorMessage = "Unsupported PLY vertex property type: " + typeToken;
|
||||
return false;
|
||||
}
|
||||
|
||||
PlyProperty property;
|
||||
property.name = name;
|
||||
property.type = propertyType;
|
||||
property.offset = outHeader.vertexStride;
|
||||
property.size = PropertyTypeSize(propertyType);
|
||||
outHeader.vertexStride += property.size;
|
||||
outHeader.properties.push_back(property);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sawFormat) {
|
||||
outErrorMessage = "PLY header is missing a valid format declaration.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (outHeader.vertexCount == 0) {
|
||||
outErrorMessage = "PLY file does not contain any vertex data.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (outHeader.vertexStride == 0 || outHeader.properties.empty()) {
|
||||
outErrorMessage = "PLY vertex layout is empty.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadPropertyAsFloat(
|
||||
const std::byte* vertexBytes,
|
||||
const PlyProperty& property,
|
||||
float& outValue) {
|
||||
const std::byte* propertyPtr = vertexBytes + property.offset;
|
||||
switch (property.type) {
|
||||
case PlyPropertyType::Float32: {
|
||||
std::memcpy(&outValue, propertyPtr, sizeof(float));
|
||||
return true;
|
||||
}
|
||||
case PlyPropertyType::Float64: {
|
||||
double value = 0.0;
|
||||
std::memcpy(&value, propertyPtr, sizeof(double));
|
||||
outValue = static_cast<float>(value);
|
||||
return true;
|
||||
}
|
||||
case PlyPropertyType::UInt8: {
|
||||
uint8_t value = 0;
|
||||
std::memcpy(&value, propertyPtr, sizeof(uint8_t));
|
||||
outValue = static_cast<float>(value);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool BuildPropertyMap(
|
||||
const PlyHeader& header,
|
||||
std::unordered_map<std::string_view, const PlyProperty*>& outMap,
|
||||
std::string& outErrorMessage) {
|
||||
outMap.clear();
|
||||
outMap.reserve(header.properties.size());
|
||||
|
||||
for (const PlyProperty& property : header.properties) {
|
||||
const auto [it, inserted] = outMap.emplace(property.name, &property);
|
||||
if (!inserted) {
|
||||
outErrorMessage = "Duplicate PLY vertex property found: " + property.name;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RequireProperty(
|
||||
const std::unordered_map<std::string_view, const PlyProperty*>& propertyMap,
|
||||
std::string_view name,
|
||||
const PlyProperty*& outProperty,
|
||||
std::string& outErrorMessage) {
|
||||
const auto iterator = propertyMap.find(name);
|
||||
if (iterator == propertyMap.end()) {
|
||||
outErrorMessage = "Missing required PLY property: " + std::string(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
outProperty = iterator->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildGaussianPlyPropertyLayout(
|
||||
const std::unordered_map<std::string_view, const PlyProperty*>& propertyMap,
|
||||
GaussianPlyPropertyLayout& outLayout,
|
||||
std::string& outErrorMessage) {
|
||||
outLayout = {};
|
||||
|
||||
if (!RequireProperty(propertyMap, "x", outLayout.position[0], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "y", outLayout.position[1], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "z", outLayout.position[2], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "f_dc_0", outLayout.dc0[0], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "f_dc_1", outLayout.dc0[1], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "f_dc_2", outLayout.dc0[2], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "opacity", outLayout.opacity, outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "scale_0", outLayout.scale[0], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "scale_1", outLayout.scale[1], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "scale_2", outLayout.scale[2], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "rot_0", outLayout.rotation[0], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "rot_1", outLayout.rotation[1], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "rot_2", outLayout.rotation[2], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "rot_3", outLayout.rotation[3], outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t index = 0; index < outLayout.sh.size(); ++index) {
|
||||
const std::string propertyName = "f_rest_" + std::to_string(index);
|
||||
if (!RequireProperty(propertyMap, propertyName, outLayout.sh[index], outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Float3 Min(const Float3& a, const Float3& b) {
|
||||
return {
|
||||
std::min(a.x, b.x),
|
||||
std::min(a.y, b.y),
|
||||
std::min(a.z, b.z),
|
||||
};
|
||||
}
|
||||
|
||||
Float3 Max(const Float3& a, const Float3& b) {
|
||||
return {
|
||||
std::max(a.x, b.x),
|
||||
std::max(a.y, b.y),
|
||||
std::max(a.z, b.z),
|
||||
};
|
||||
}
|
||||
|
||||
float Dot(const Float4& a, const Float4& b) {
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
|
||||
}
|
||||
|
||||
Float4 NormalizeSwizzleRotation(const Float4& wxyz) {
|
||||
const float lengthSquared = Dot(wxyz, wxyz);
|
||||
if (lengthSquared <= std::numeric_limits<float>::epsilon()) {
|
||||
return { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
}
|
||||
|
||||
const float inverseLength = 1.0f / std::sqrt(lengthSquared);
|
||||
return {
|
||||
wxyz.y * inverseLength,
|
||||
wxyz.z * inverseLength,
|
||||
wxyz.w * inverseLength,
|
||||
wxyz.x * inverseLength,
|
||||
};
|
||||
}
|
||||
|
||||
Float4 PackSmallest3Rotation(Float4 rotation) {
|
||||
const Float4 absoluteRotation = {
|
||||
std::fabs(rotation.x),
|
||||
std::fabs(rotation.y),
|
||||
std::fabs(rotation.z),
|
||||
std::fabs(rotation.w),
|
||||
};
|
||||
|
||||
int largestIndex = 0;
|
||||
float largestValue = absoluteRotation.x;
|
||||
if (absoluteRotation.y > largestValue) {
|
||||
largestIndex = 1;
|
||||
largestValue = absoluteRotation.y;
|
||||
}
|
||||
if (absoluteRotation.z > largestValue) {
|
||||
largestIndex = 2;
|
||||
largestValue = absoluteRotation.z;
|
||||
}
|
||||
if (absoluteRotation.w > largestValue) {
|
||||
largestIndex = 3;
|
||||
largestValue = absoluteRotation.w;
|
||||
}
|
||||
|
||||
if (largestIndex == 0) {
|
||||
rotation = { rotation.y, rotation.z, rotation.w, rotation.x };
|
||||
} else if (largestIndex == 1) {
|
||||
rotation = { rotation.x, rotation.z, rotation.w, rotation.y };
|
||||
} else if (largestIndex == 2) {
|
||||
rotation = { rotation.x, rotation.y, rotation.w, rotation.z };
|
||||
}
|
||||
|
||||
const float sign = rotation.w >= 0.0f ? 1.0f : -1.0f;
|
||||
const float invSqrt2 = std::sqrt(2.0f) * 0.5f;
|
||||
const Float3 encoded = {
|
||||
(rotation.x * sign * std::sqrt(2.0f)) * 0.5f + 0.5f,
|
||||
(rotation.y * sign * std::sqrt(2.0f)) * 0.5f + 0.5f,
|
||||
(rotation.z * sign * std::sqrt(2.0f)) * 0.5f + 0.5f,
|
||||
};
|
||||
|
||||
(void)invSqrt2;
|
||||
return { encoded.x, encoded.y, encoded.z, static_cast<float>(largestIndex) / 3.0f };
|
||||
}
|
||||
|
||||
uint32_t EncodeQuatToNorm10(const Float4& packedRotation) {
|
||||
const auto saturate = [](float value) {
|
||||
return std::clamp(value, 0.0f, 1.0f);
|
||||
};
|
||||
|
||||
const uint32_t x = static_cast<uint32_t>(saturate(packedRotation.x) * 1023.5f);
|
||||
const uint32_t y = static_cast<uint32_t>(saturate(packedRotation.y) * 1023.5f);
|
||||
const uint32_t z = static_cast<uint32_t>(saturate(packedRotation.z) * 1023.5f);
|
||||
const uint32_t w = static_cast<uint32_t>(saturate(packedRotation.w) * 3.5f);
|
||||
return x | (y << 10) | (z << 20) | (w << 30);
|
||||
}
|
||||
|
||||
Float3 LinearScale(const Float3& logarithmicScale) {
|
||||
return {
|
||||
std::fabs(std::exp(logarithmicScale.x)),
|
||||
std::fabs(std::exp(logarithmicScale.y)),
|
||||
std::fabs(std::exp(logarithmicScale.z)),
|
||||
};
|
||||
}
|
||||
|
||||
Float3 SH0ToColor(const Float3& dc0) {
|
||||
return {
|
||||
dc0.x * kSHC0 + 0.5f,
|
||||
dc0.y * kSHC0 + 0.5f,
|
||||
dc0.z * kSHC0 + 0.5f,
|
||||
};
|
||||
}
|
||||
|
||||
float Sigmoid(float value) {
|
||||
return 1.0f / (1.0f + std::exp(-value));
|
||||
}
|
||||
|
||||
std::array<uint32_t, 2> DecodeMorton2D16x16(uint32_t value) {
|
||||
value = (value & 0xFFu) | ((value & 0xFEu) << 7u);
|
||||
value &= 0x5555u;
|
||||
value = (value ^ (value >> 1u)) & 0x3333u;
|
||||
value = (value ^ (value >> 2u)) & 0x0F0Fu;
|
||||
return { value & 0xFu, value >> 8u };
|
||||
}
|
||||
|
||||
uint32_t SplatIndexToTextureIndex(uint32_t index) {
|
||||
const std::array<uint32_t, 2> morton = DecodeMorton2D16x16(index);
|
||||
const uint32_t widthInBlocks = GaussianSplatRuntimeData::kColorTextureWidth / 16u;
|
||||
index >>= 8u;
|
||||
const uint32_t x = (index % widthInBlocks) * 16u + morton[0];
|
||||
const uint32_t y = (index / widthInBlocks) * 16u + morton[1];
|
||||
return y * GaussianSplatRuntimeData::kColorTextureWidth + x;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void WriteValue(std::vector<std::byte>& bytes, size_t offset, const T& value) {
|
||||
std::memcpy(bytes.data() + offset, &value, sizeof(T));
|
||||
}
|
||||
|
||||
void WriteFloat3(std::vector<std::byte>& bytes, size_t offset, const Float3& value) {
|
||||
WriteValue(bytes, offset + 0, value.x);
|
||||
WriteValue(bytes, offset + 4, value.y);
|
||||
WriteValue(bytes, offset + 8, value.z);
|
||||
}
|
||||
|
||||
void WriteFloat4(std::vector<std::byte>& bytes, size_t offset, float x, float y, float z, float w) {
|
||||
WriteValue(bytes, offset + 0, x);
|
||||
WriteValue(bytes, offset + 4, y);
|
||||
WriteValue(bytes, offset + 8, z);
|
||||
WriteValue(bytes, offset + 12, w);
|
||||
}
|
||||
|
||||
bool ReadGaussianSplat(
|
||||
const std::byte* vertexBytes,
|
||||
const GaussianPlyPropertyLayout& propertyLayout,
|
||||
RawGaussianSplat& outSplat,
|
||||
std::string& outErrorMessage) {
|
||||
auto readFloat = [&](const PlyProperty* property, float& outValue) -> bool {
|
||||
if (property == nullptr) {
|
||||
outErrorMessage = "Gaussian PLY property layout is incomplete.";
|
||||
return false;
|
||||
}
|
||||
return ReadPropertyAsFloat(vertexBytes, *property, outValue);
|
||||
};
|
||||
|
||||
if (!readFloat(propertyLayout.position[0], outSplat.position.x) ||
|
||||
!readFloat(propertyLayout.position[1], outSplat.position.y) ||
|
||||
!readFloat(propertyLayout.position[2], outSplat.position.z) ||
|
||||
!readFloat(propertyLayout.dc0[0], outSplat.dc0.x) ||
|
||||
!readFloat(propertyLayout.dc0[1], outSplat.dc0.y) ||
|
||||
!readFloat(propertyLayout.dc0[2], outSplat.dc0.z) ||
|
||||
!readFloat(propertyLayout.opacity, outSplat.opacity) ||
|
||||
!readFloat(propertyLayout.scale[0], outSplat.scale.x) ||
|
||||
!readFloat(propertyLayout.scale[1], outSplat.scale.y) ||
|
||||
!readFloat(propertyLayout.scale[2], outSplat.scale.z) ||
|
||||
!readFloat(propertyLayout.rotation[0], outSplat.rotation.x) ||
|
||||
!readFloat(propertyLayout.rotation[1], outSplat.rotation.y) ||
|
||||
!readFloat(propertyLayout.rotation[2], outSplat.rotation.z) ||
|
||||
!readFloat(propertyLayout.rotation[3], outSplat.rotation.w)) {
|
||||
if (outErrorMessage.empty()) {
|
||||
outErrorMessage = "Failed to read required Gaussian splat PLY properties.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::array<float, GaussianSplatRuntimeData::kShCoefficientCount * 3> shRaw = {};
|
||||
for (uint32_t index = 0; index < shRaw.size(); ++index) {
|
||||
if (!readFloat(propertyLayout.sh[index], shRaw[index])) {
|
||||
if (outErrorMessage.empty()) {
|
||||
outErrorMessage = "Failed to read SH rest coefficients from PLY.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t coefficientIndex = 0; coefficientIndex < GaussianSplatRuntimeData::kShCoefficientCount; ++coefficientIndex) {
|
||||
outSplat.sh[coefficientIndex] = {
|
||||
shRaw[coefficientIndex + 0],
|
||||
shRaw[coefficientIndex + GaussianSplatRuntimeData::kShCoefficientCount],
|
||||
shRaw[coefficientIndex + GaussianSplatRuntimeData::kShCoefficientCount * 2],
|
||||
};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LinearizeGaussianSplat(RawGaussianSplat& splat) {
|
||||
const Float4 normalizedQuaternion = NormalizeSwizzleRotation(splat.rotation);
|
||||
const Float4 packedQuaternion = PackSmallest3Rotation(normalizedQuaternion);
|
||||
splat.rotation = packedQuaternion;
|
||||
splat.scale = LinearScale(splat.scale);
|
||||
splat.dc0 = SH0ToColor(splat.dc0);
|
||||
splat.opacity = Sigmoid(splat.opacity);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool LoadGaussianSceneFromPly(
|
||||
const std::filesystem::path& filePath,
|
||||
GaussianSplatRuntimeData& outData,
|
||||
std::string& outErrorMessage) {
|
||||
outData = {};
|
||||
outErrorMessage.clear();
|
||||
|
||||
std::ifstream input(filePath, std::ios::binary);
|
||||
if (!input.is_open()) {
|
||||
outErrorMessage = "Failed to open PLY file: " + filePath.string();
|
||||
return false;
|
||||
}
|
||||
|
||||
PlyHeader header;
|
||||
if (!ParsePlyHeader(input, header, outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string_view, const PlyProperty*> propertyMap;
|
||||
if (!BuildPropertyMap(header, propertyMap, outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GaussianPlyPropertyLayout propertyLayout;
|
||||
if (!BuildGaussianPlyPropertyLayout(propertyMap, propertyLayout, outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outData.splatCount = header.vertexCount;
|
||||
outData.colorTextureWidth = GaussianSplatRuntimeData::kColorTextureWidth;
|
||||
outData.colorTextureHeight =
|
||||
std::max<uint32_t>(1u, (header.vertexCount + outData.colorTextureWidth - 1u) / outData.colorTextureWidth);
|
||||
outData.colorTextureHeight = (outData.colorTextureHeight + 15u) / 16u * 16u;
|
||||
|
||||
outData.positionData.resize(static_cast<size_t>(header.vertexCount) * GaussianSplatRuntimeData::kPositionStride);
|
||||
outData.otherData.resize(static_cast<size_t>(header.vertexCount) * GaussianSplatRuntimeData::kOtherStride);
|
||||
outData.colorData.resize(
|
||||
static_cast<size_t>(outData.colorTextureWidth) *
|
||||
static_cast<size_t>(outData.colorTextureHeight) *
|
||||
GaussianSplatRuntimeData::kColorStride);
|
||||
outData.shData.resize(static_cast<size_t>(header.vertexCount) * GaussianSplatRuntimeData::kShStride);
|
||||
|
||||
outData.boundsMin = {
|
||||
std::numeric_limits<float>::infinity(),
|
||||
std::numeric_limits<float>::infinity(),
|
||||
std::numeric_limits<float>::infinity(),
|
||||
};
|
||||
outData.boundsMax = {
|
||||
-std::numeric_limits<float>::infinity(),
|
||||
-std::numeric_limits<float>::infinity(),
|
||||
-std::numeric_limits<float>::infinity(),
|
||||
};
|
||||
|
||||
std::vector<std::byte> vertexBytes(header.vertexStride);
|
||||
for (uint32_t splatIndex = 0; splatIndex < header.vertexCount; ++splatIndex) {
|
||||
input.read(reinterpret_cast<char*>(vertexBytes.data()), static_cast<std::streamsize>(vertexBytes.size()));
|
||||
if (input.gcount() != static_cast<std::streamsize>(vertexBytes.size())) {
|
||||
outErrorMessage =
|
||||
"Unexpected end of file while reading Gaussian splat vertex " + std::to_string(splatIndex) + ".";
|
||||
return false;
|
||||
}
|
||||
|
||||
RawGaussianSplat splat;
|
||||
if (!ReadGaussianSplat(vertexBytes.data(), propertyLayout, splat, outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LinearizeGaussianSplat(splat);
|
||||
|
||||
outData.boundsMin = Min(outData.boundsMin, splat.position);
|
||||
outData.boundsMax = Max(outData.boundsMax, splat.position);
|
||||
|
||||
const size_t positionOffset = static_cast<size_t>(splatIndex) * GaussianSplatRuntimeData::kPositionStride;
|
||||
WriteFloat3(outData.positionData, positionOffset, splat.position);
|
||||
|
||||
const size_t otherOffset = static_cast<size_t>(splatIndex) * GaussianSplatRuntimeData::kOtherStride;
|
||||
const uint32_t packedRotation = EncodeQuatToNorm10(splat.rotation);
|
||||
WriteValue(outData.otherData, otherOffset, packedRotation);
|
||||
WriteFloat3(outData.otherData, otherOffset + sizeof(uint32_t), splat.scale);
|
||||
|
||||
const size_t shOffset = static_cast<size_t>(splatIndex) * GaussianSplatRuntimeData::kShStride;
|
||||
for (uint32_t coefficientIndex = 0; coefficientIndex < GaussianSplatRuntimeData::kShCoefficientCount; ++coefficientIndex) {
|
||||
const size_t coefficientOffset = shOffset + static_cast<size_t>(coefficientIndex) * sizeof(float) * 3u;
|
||||
WriteFloat3(outData.shData, coefficientOffset, splat.sh[coefficientIndex]);
|
||||
}
|
||||
|
||||
const uint32_t textureIndex = SplatIndexToTextureIndex(splatIndex);
|
||||
const size_t colorOffset = static_cast<size_t>(textureIndex) * GaussianSplatRuntimeData::kColorStride;
|
||||
WriteFloat4(outData.colorData, colorOffset, splat.dc0.x, splat.dc0.y, splat.dc0.z, splat.opacity);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteGaussianSceneSummary(
|
||||
const std::filesystem::path& filePath,
|
||||
const GaussianSplatRuntimeData& data,
|
||||
std::string& outErrorMessage) {
|
||||
outErrorMessage.clear();
|
||||
|
||||
std::ofstream output(filePath, std::ios::binary | std::ios::trunc);
|
||||
if (!output.is_open()) {
|
||||
outErrorMessage = "Failed to open summary output file: " + filePath.string();
|
||||
return false;
|
||||
}
|
||||
|
||||
output << "splat_count=" << data.splatCount << '\n';
|
||||
output << "color_texture_width=" << data.colorTextureWidth << '\n';
|
||||
output << "color_texture_height=" << data.colorTextureHeight << '\n';
|
||||
output << "bounds_min=" << data.boundsMin.x << "," << data.boundsMin.y << "," << data.boundsMin.z << '\n';
|
||||
output << "bounds_max=" << data.boundsMax.x << "," << data.boundsMax.y << "," << data.boundsMax.z << '\n';
|
||||
output << "position_bytes=" << data.positionData.size() << '\n';
|
||||
output << "other_bytes=" << data.otherData.size() << '\n';
|
||||
output << "color_bytes=" << data.colorData.size() << '\n';
|
||||
output << "sh_bytes=" << data.shData.size() << '\n';
|
||||
|
||||
return output.good();
|
||||
}
|
||||
|
||||
} // namespace XC3DGSD3D12
|
||||
42
MVS/3DGS-D3D12/src/main.cpp
Normal file
42
MVS/3DGS-D3D12/src/main.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "XC3DGSD3D12/App.h"
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int showCommand) {
|
||||
XC3DGSD3D12::App app;
|
||||
|
||||
int argumentCount = 0;
|
||||
LPWSTR* arguments = CommandLineToArgvW(GetCommandLineW(), &argumentCount);
|
||||
for (int index = 1; index + 1 < argumentCount; ++index) {
|
||||
if (std::wstring(arguments[index]) == L"--frame-limit") {
|
||||
app.SetFrameLimit(static_cast<unsigned int>(_wtoi(arguments[index + 1])));
|
||||
++index;
|
||||
} else if (std::wstring(arguments[index]) == L"--scene") {
|
||||
app.SetGaussianScenePath(arguments[index + 1]);
|
||||
++index;
|
||||
} else if (std::wstring(arguments[index]) == L"--summary-file") {
|
||||
app.SetSummaryPath(arguments[index + 1]);
|
||||
++index;
|
||||
} else if (std::wstring(arguments[index]) == L"--screenshot-file") {
|
||||
app.SetScreenshotPath(arguments[index + 1]);
|
||||
++index;
|
||||
}
|
||||
}
|
||||
if (arguments != nullptr) {
|
||||
LocalFree(arguments);
|
||||
}
|
||||
|
||||
if (!app.Initialize(instance, showCommand)) {
|
||||
const std::wstring message =
|
||||
app.GetLastErrorMessage().empty()
|
||||
? L"Failed to initialize XC 3DGS D3D12 MVS."
|
||||
: app.GetLastErrorMessage();
|
||||
MessageBoxW(nullptr, message.c_str(), L"Initialization Error", MB_OK | MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return app.Run();
|
||||
}
|
||||
@@ -670,4 +670,4 @@ ID3D12Resource* CreateTexture2D(ID3D12GraphicsCommandList* inCommandList,
|
||||
}
|
||||
ID3D12Device* GetD3DDevice() {
|
||||
return gD3D12Device;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,4 +305,4 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
460
README.md
460
README.md
@@ -1,123 +1,186 @@
|
||||
# XCEngine
|
||||
|
||||
`XCEngine` 是一个 Windows-first、editor-first 的 C++20 游戏引擎工作区。当前主线围绕 `RHI -> Rendering -> Editor -> Asset Pipeline -> Mono Scripting` 演进,目标不是堆 sample,而是把可运行的引擎与编辑器主链持续收口成型。
|
||||
`XCEngine` 是一个 Windows-first、editor-first 的 `C++20` 游戏引擎工作区。当前代码中已经形成 `RHI`、`Rendering`、`Scene`、`Resources`、`Editor`、`Mono C# Scripting` 和 `XCUI` 相关主线;本 README 只描述当前已经实现、已经接入或已经成为正式工作流一部分的能力。
|
||||
|
||||
## 项目定位
|
||||
## 核心特性
|
||||
|
||||
- `engine/` 提供核心静态库 `XCEngine`,包含 `RHI`、`Rendering`、`Resources`、`Scene`、`Input`、`Audio`、`Scripting` 等模块。
|
||||
- `editor/` 是当前正式桌面编辑器,宿主基于 Win32 + D3D12,编辑器 target 名为 `XCEditor`,输出文件名为 `XCEngine.exe`。
|
||||
- `new_editor/` 是基于 `XCUI` 的新编辑器主线,当前仍在并行演进。
|
||||
- `project/` 是随仓库维护的示例工程,已经采用 `Assets + .meta + Library` 布局。
|
||||
- `tests/` 覆盖 Engine、Rendering、RHI、Editor、Scripting、UI 等主线模块。
|
||||
### 渲染
|
||||
|
||||
## 当前能力
|
||||
- 内置跨后端 `RHI` 抽象层,当前支持 `D3D12`、`OpenGL`、`Vulkan`
|
||||
- 当前主渲染链为 `SceneRenderer -> CameraRenderer -> BuiltinForwardPipeline`
|
||||
- 已接入前向渲染主路径、透明路径和 skybox 路径
|
||||
- 已具备方向光阴影通路
|
||||
- 已具备 `object-id` pass,可用于编辑器拾取
|
||||
- 已具备选中描边、最终颜色合成和颜色缩放后处理 pass
|
||||
- 已具备无限网格 pass,可用于 Scene View
|
||||
- 已接入 `NanoVDB` 体积渲染 pass
|
||||
- `RenderSurface` 允许同一条渲染链服务于窗口输出、编辑器视口和离屏目标
|
||||
|
||||
- `RHI` 当前维护 `D3D12 / OpenGL / Vulkan` 三个后端。
|
||||
- `Rendering` 已形成 `SceneRenderer -> CameraRenderer -> RenderPipeline` 主链。
|
||||
- Scene View 已接通 object-id picking、selection outline、grid、overlay 与 gizmo 渲染。
|
||||
- 资源系统已采用 `AssetDatabase + Artifact + Library` 工作流,而不是简单文件直读。
|
||||
- `Material / Shader / Texture / Mesh` 已接入正式资源导入与运行时加载链路。
|
||||
- 编辑器已支持项目加载、Scene/Game viewport、Inspector、Hierarchy、Project 面板等基础闭环。
|
||||
- Mono C# 脚本运行时与项目脚本程序集构建链路已接入当前工作区。
|
||||
- `new_editor/` 正在推进 `XCUI` 宿主、控件与 shell 体系。
|
||||
### 场景与运行时
|
||||
|
||||
## 仓库结构
|
||||
- 采用 `Scene / GameObject / Component` 结构
|
||||
- 已具备场景更新、运行时驱动和场景序列化能力
|
||||
- 内置常用组件,包括:
|
||||
- `TransformComponent`
|
||||
- `CameraComponent`
|
||||
- `LightComponent`
|
||||
- `MeshFilterComponent`
|
||||
- `MeshRendererComponent`
|
||||
- `VolumeRendererComponent`
|
||||
- `AudioSourceComponent`
|
||||
- `AudioListenerComponent`
|
||||
- `ScriptComponent`
|
||||
|
||||
- `engine/`:引擎核心实现与公共头文件。
|
||||
- `editor/`:当前正式编辑器与 viewport 接线。
|
||||
- `new_editor/`:XCUI 新编辑器主线。
|
||||
- `managed/`:`XCEngine.ScriptCore` 与示例托管程序集。
|
||||
- `project/`:示例工程与随仓库维护的资产。
|
||||
- `tests/`:单元测试、集成测试与阶段性回归入口。
|
||||
- `docs/`:架构说明、API 文档、计划与历史归档。
|
||||
- `mvs/`:原型、实验工程与外部参考材料。
|
||||
### 资源系统
|
||||
|
||||
## 环境要求
|
||||
- 资源主线不是简单文件直读,而是 `AssetDatabase + Artifact + Library` 工作流
|
||||
- 已具备项目资产索引、导入、重导入和缓存维护链路
|
||||
- 已接入的资源类型包括:
|
||||
- `Mesh`
|
||||
- `Texture`
|
||||
- `Shader`
|
||||
- `Material`
|
||||
- `AudioClip`
|
||||
- `VolumeField`
|
||||
- `UI Document`
|
||||
- 内置 `builtin://` 资源入口,可直接使用基础 mesh、材质等内置资源
|
||||
|
||||
当前推荐在 Windows 上构建和运行。
|
||||
### 脚本系统
|
||||
|
||||
- 可选启用基于 `Mono` 的 `C#` 脚本运行时
|
||||
- 托管程序集分为:
|
||||
- `XCEngine.ScriptCore`
|
||||
- `GameScripts`
|
||||
- 脚本组件由 `ScriptComponent` 承载
|
||||
- 引擎当前支持脚本类发现、字段元数据读取、默认值读取和字段存储
|
||||
- 支持脚本字段 override 持久化与运行时同步
|
||||
- 编辑器已接入项目脚本程序集重建与脚本运行时重载
|
||||
|
||||
### 编辑器
|
||||
|
||||
- 当前正式编辑器是基于 `Win32 + D3D12 + ImGui` 的桌面编辑器
|
||||
- 当前已具备以下基础工作流:
|
||||
- `Hierarchy`
|
||||
- `Inspector`
|
||||
- `Project`
|
||||
- `Console`
|
||||
- `Scene View`
|
||||
- `Game View`
|
||||
- `Scene View` 已接入:
|
||||
- object-id picking
|
||||
- selection outline
|
||||
- overlay
|
||||
- transform gizmo
|
||||
- infinite grid
|
||||
- `Inspector` 已能处理常规组件检查,也已接入 `ScriptComponent` 与材质资源检查路径
|
||||
- 编辑器能够识别项目目录、加载项目资源、接通 `Library/ScriptAssemblies` 中的脚本程序集
|
||||
|
||||
### UI 与 XCUI
|
||||
|
||||
- 引擎内部包含 retained-mode UI 基础设施
|
||||
- 已具备:
|
||||
- 布局系统
|
||||
- 样式系统
|
||||
- 焦点控制
|
||||
- 输入分发
|
||||
- 快捷键分发
|
||||
- 文本输入编辑
|
||||
- 选择模型
|
||||
- 拖拽交互模型
|
||||
- 运行时 UI 主链包括:
|
||||
- `UIScreenDocumentHost`
|
||||
- `UIScreenPlayer`
|
||||
- `UISystem`
|
||||
- `tests/UI/` 是当前 XCUI `Core / Editor / Runtime` 三层的正式基础层验证入口
|
||||
- `new_editor/` 是未来正式编辑器主线,不再只是临时沙盒;当前已经包含树视图、列表视图、菜单、标签条、属性网格、字段控件、workspace / dock / viewport shell 等基础组件
|
||||
|
||||
### 音频
|
||||
|
||||
- 已具备 `AudioSystem`
|
||||
- 已接入 `AudioSourceComponent` 与 `AudioListenerComponent`
|
||||
- 当前代码中已包含 `AudioMixer` 和多种效果器/分析器实现入口:
|
||||
- `Equalizer`
|
||||
- `FFTFilter`
|
||||
- `Reverbation`
|
||||
- `HRTF`
|
||||
|
||||
### 测试
|
||||
|
||||
- 引擎不是“只靠手工点点看”的状态,当前已具备大规模测试树
|
||||
- 覆盖范围包括:
|
||||
- Engine 基础模块
|
||||
- Rendering
|
||||
- RHI
|
||||
- Editor
|
||||
- Scripting
|
||||
- UI
|
||||
- `RHI` 集成测试使用统一基准图做 golden-image 对比
|
||||
- `XCUI` 当前也有独立的 unit / integration 验证链路
|
||||
|
||||
## 当前实现范围
|
||||
|
||||
- 当前正式编辑器为基于 `Win32 + D3D12 + ImGui` 的桌面编辑器
|
||||
- 当前 `RHI` 后端为 `D3D12`、`OpenGL`、`Vulkan`
|
||||
- 当前项目资产工作流已经接入 `AssetDatabase + Artifact + Library`
|
||||
- 当前 `Mono C#` 脚本程序集与运行时链路已经接入
|
||||
- 当前 `XCUI` 新编辑器路线以 `new_editor/` 为正式主线继续推进
|
||||
|
||||
## 快速开始
|
||||
|
||||
推荐环境:
|
||||
|
||||
- Windows 10/11
|
||||
- Visual Studio 2022 / MSVC v143
|
||||
- CMake 3.15+
|
||||
- Vulkan SDK
|
||||
- .NET SDK
|
||||
- Git LFS
|
||||
|
||||
脚本运行时启用时,还需要:
|
||||
|
||||
- 可用的 Mono 依赖,默认路径来自 `参考/Fermion/Fermion/external/mono`
|
||||
|
||||
补充说明:
|
||||
|
||||
- 当前根 CMake 配置里,`Vulkan SDK` 仍是硬依赖。
|
||||
- NanoVDB 头文件是可选能力,仅影响 `.nvdb` 体积资源支持。
|
||||
- 如果仓库里的大资源依赖 Git LFS,请先执行 `git lfs pull`。
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 配置
|
||||
配置工程:
|
||||
|
||||
```powershell
|
||||
cmake -S . -B build -A x64
|
||||
```
|
||||
|
||||
如果本地暂时没有 Mono 依赖,可以先关闭脚本运行时:
|
||||
如果当前不需要 Mono 脚本运行时:
|
||||
|
||||
```powershell
|
||||
cmake -S . -B build -A x64 -DXCENGINE_ENABLE_MONO_SCRIPTING=OFF
|
||||
```
|
||||
|
||||
### 2. 构建当前编辑器
|
||||
构建当前正式编辑器:
|
||||
|
||||
```powershell
|
||||
cmake --build build --config Debug --target XCEditor
|
||||
```
|
||||
|
||||
编辑器产物路径:
|
||||
|
||||
- `editor/bin/Debug/XCEngine.exe`
|
||||
|
||||
### 3. 运行编辑器
|
||||
运行:
|
||||
|
||||
```powershell
|
||||
.\editor\bin\Debug\XCEngine.exe
|
||||
```
|
||||
|
||||
显式指定工程目录:
|
||||
|
||||
```powershell
|
||||
.\editor\bin\Debug\XCEngine.exe --project D:\Path\To\Project
|
||||
```
|
||||
|
||||
### 4. 构建项目脚本程序集
|
||||
|
||||
如果你要验证 `ScriptComponent`、脚本类发现或 Inspector 字段编辑,先构建:
|
||||
如需构建项目脚本程序集:
|
||||
|
||||
```powershell
|
||||
cmake --build build --config Debug --target xcengine_project_managed_assemblies
|
||||
```
|
||||
|
||||
### 5. 可选构建 XCUI 新编辑器
|
||||
如需构建 XCUI 新编辑器宿主:
|
||||
|
||||
```powershell
|
||||
cmake --build build --config Debug --target XCUIEditorApp
|
||||
```
|
||||
|
||||
产物路径通常为:
|
||||
运行 XCUI 新编辑器宿主:
|
||||
|
||||
- `new_editor/bin/Debug/XCUIEditor.exe`
|
||||
```powershell
|
||||
.\new_editor\bin\Debug\XCUIEditor.exe
|
||||
```
|
||||
|
||||
## 测试
|
||||
|
||||
列出测试:
|
||||
## 测试入口
|
||||
|
||||
```powershell
|
||||
ctest --test-dir build -N -C Debug
|
||||
```
|
||||
|
||||
运行测试:
|
||||
|
||||
```powershell
|
||||
ctest --test-dir build -C Debug --output-on-failure
|
||||
```
|
||||
|
||||
@@ -128,24 +191,253 @@ cmake --build build --config Debug --target editor_tests
|
||||
cmake --build build --config Debug --target rendering_all_tests
|
||||
cmake --build build --config Debug --target rhi_all_tests
|
||||
cmake --build build --config Debug --target scripting_tests
|
||||
cmake --build build --config Debug --target core_ui_all_tests
|
||||
cmake --build build --config Debug --target editor_ui_all_tests
|
||||
cmake --build build --config Debug --target runtime_ui_all_tests
|
||||
```
|
||||
|
||||
更细的测试组织与约定见 [tests/TEST_SPEC.md](tests/TEST_SPEC.md)。
|
||||
## 完整目录结构
|
||||
|
||||
以下目录树按当前工作树整理,保留了真实使用的生成目录与关键子树;省略了 `.git/`、`build/_deps/`、部分重复资源文件,以及 `docs/used/` 中大量历史归档的长尾条目。
|
||||
|
||||
```text
|
||||
XCEngine/
|
||||
|- .gitattributes
|
||||
|- .gitignore
|
||||
|- AGENT.md
|
||||
|- CMakeLists.txt
|
||||
|- README.md
|
||||
|- build/ # 本地 CMake 构建输出
|
||||
|- docs/
|
||||
| |- api/
|
||||
| | |- XCEngine/
|
||||
| | |- _guides/
|
||||
| | |- _meta/
|
||||
| | |- _tools/
|
||||
| | `- main.md
|
||||
| |- issues/
|
||||
| | `- Editor模块_Console面板错误绑定fallback sink导致运行时日志不显示4.3.md
|
||||
| |- plan/
|
||||
| | |- end/
|
||||
| | | |- RHI模块设计与实现/
|
||||
| | | | |- RHIFence.md
|
||||
| | | | `- RHI模块总览.md
|
||||
| | | `- 编辑器与运行时分层架构设计.md
|
||||
| | |- 开题报告和任务书/
|
||||
| | |- 旧版题目/
|
||||
| | |- 3DGS专用PLY导入器与GaussianSplat资源缓存正式化计划_2026-04-10.md
|
||||
| | |- API文档目录结构第二轮并行任务板_2026-04-09.md
|
||||
| | |- API文档目录结构第二轮重构计划_2026-04-09.md
|
||||
| | |- API文档目录结构重大重构并行任务板_2026-04-09.md
|
||||
| | |- API文档目录结构重构并行任务板_2026-04-09_第二轮.md
|
||||
| | |- API文档目录重构计划_2026-04-09.md
|
||||
| | |- C#脚本模块下一阶段计划.md
|
||||
| | |- Editor架构说明.md
|
||||
| | |- Library启动预热与运行时异步加载混合重构计划_2026-04-04.md
|
||||
| | |- Library启动预热与运行时异步加载混合重构计划_进度更新_2026-04-04.md
|
||||
| | |- NanoVDB体积云加载阻塞与Runtime上传修复计划_2026-04-10.md
|
||||
| | |- Unity SRP API参考文档.md
|
||||
| | |- Unity绝区零开发文档还原版.md
|
||||
| | |- Unity风格模型导入与Model资产架构重构计划_2026-04-10.md
|
||||
| | |- XCUI_NewEditor主线重建计划_2026-04-07.md
|
||||
| | `- XCUI完整架构设计与执行计划.md
|
||||
| |- used/ # 历史材料、阶段归档和旧计划背景
|
||||
| | |- API文档实时同步任务池_2026-04-03.md
|
||||
| | |- Library资产导入与缓存系统收口计划_完成归档_2026-04-03.md
|
||||
| | |- NanoVDB稀疏体积渲染后续正式化计划_阶段归档_2026-04-10.md
|
||||
| | |- NanoVDB稀疏体积渲染正式集成计划_第一阶段完成归档_2026-04-09.md
|
||||
| | |- Renderer当前阶段正式收口计划_阶段归档_2026-04-10.md
|
||||
| | |- Renderer剩余收口与体积渲染多后端正式化计划_完成归档_2026-04-10.md
|
||||
| | |- Renderer下一阶段_Unity风格Shader体系正式化计划_完成归档_2026-04-07.md
|
||||
| | |- SceneViewport_Overlay_Gizmo_Rework_Plan_完成归档_2026-04-04.md
|
||||
| | |- Unity式SceneView_Gizmo系统完整审查与正式化重构方案_完成归档_2026-04-06.md
|
||||
| | `- XCUI_Phase_Status_2026-04-05.md
|
||||
| |- api-skill.md
|
||||
| |- blueprint-skill.md
|
||||
| `- blueprint.md
|
||||
|- editor/
|
||||
| |- CMakeLists.txt
|
||||
| |- README.md
|
||||
| |- bin/
|
||||
| |- resources/
|
||||
| | `- Icons/
|
||||
| `- src/
|
||||
| |- Actions/
|
||||
| |- Commands/
|
||||
| |- ComponentEditors/
|
||||
| |- Core/
|
||||
| |- Layers/
|
||||
| |- Layout/
|
||||
| |- Managers/
|
||||
| |- panels/
|
||||
| |- Platform/
|
||||
| |- Scripting/
|
||||
| |- UI/
|
||||
| |- Utils/
|
||||
| |- Viewport/
|
||||
| | |- Passes/
|
||||
| | |- SceneViewportChrome.*
|
||||
| | |- SceneViewportInteractionFrame.h
|
||||
| | |- SceneViewportNavigation.h
|
||||
| | |- SceneViewportOverlayBuilder.*
|
||||
| | |- SceneViewportOverlayFrameCache.*
|
||||
| | |- SceneViewportOverlaySpriteResources.*
|
||||
| | |- SceneViewportPassSpecs.h
|
||||
| | |- SceneViewportPicker.*
|
||||
| | |- SceneViewportResourcePaths.h
|
||||
| | |- SceneViewportTransformGizmoCoordinator.*
|
||||
| | `- ViewportHostService.h
|
||||
| |- Application.cpp
|
||||
| |- Application.h
|
||||
| |- Theme.cpp
|
||||
| `- main.cpp
|
||||
|- engine/
|
||||
| |- CMakeLists.txt
|
||||
| |- include/
|
||||
| | `- XCEngine/
|
||||
| | |- Audio/
|
||||
| | |- Components/
|
||||
| | |- Core/
|
||||
| | |- Debug/
|
||||
| | |- Input/
|
||||
| | |- Memory/
|
||||
| | |- Platform/
|
||||
| | |- Rendering/
|
||||
| | | |- Caches/
|
||||
| | | |- Execution/
|
||||
| | | |- Extraction/
|
||||
| | | |- FrameData/
|
||||
| | | |- Materials/
|
||||
| | | |- Passes/
|
||||
| | | |- Picking/
|
||||
| | | |- Pipelines/
|
||||
| | | `- Planning/
|
||||
| | |- Resources/
|
||||
| | | |- AudioClip/
|
||||
| | | |- Material/
|
||||
| | | |- Mesh/
|
||||
| | | |- Shader/
|
||||
| | | |- Texture/
|
||||
| | | `- Volume/
|
||||
| | |- RHI/
|
||||
| | | |- D3D12/
|
||||
| | | |- OpenGL/
|
||||
| | | `- Vulkan/
|
||||
| | |- Scene/
|
||||
| | |- Scripting/
|
||||
| | |- Threading/
|
||||
| | `- UI/
|
||||
| |- src/
|
||||
| |- third_party/
|
||||
| `- tools/
|
||||
|- managed/
|
||||
| |- CMakeLists.txt
|
||||
| |- GameScripts/
|
||||
| `- XCEngine.ScriptCore/
|
||||
|- mvs/
|
||||
| |- 3DGS-Unity/
|
||||
| |- D3D12/
|
||||
| |- OpenGL/
|
||||
| |- RenderDoc/
|
||||
| |- ui/
|
||||
| `- VolumeRenderer/
|
||||
|- new_editor/
|
||||
| |- app/
|
||||
| | |- Host/
|
||||
| | |- Application.cpp
|
||||
| | |- Application.h
|
||||
| | `- main.cpp
|
||||
| |- bin/
|
||||
| |- include/
|
||||
| | `- XCEditor/
|
||||
| | |- Collections/
|
||||
| | |- Fields/
|
||||
| | |- Foundation/
|
||||
| | |- Shell/
|
||||
| | `- Widgets/
|
||||
| |- src/
|
||||
| | |- Collections/
|
||||
| | |- Fields/
|
||||
| | |- Foundation/
|
||||
| | |- Shell/
|
||||
| | `- Widgets/
|
||||
| |- ui/
|
||||
| | |- themes/
|
||||
| | `- views/
|
||||
| `- CMakeLists.txt
|
||||
|- project/
|
||||
| |- .xceditor/
|
||||
| | |- imgui_layout.ini
|
||||
| | `- thumbs/
|
||||
| |- Assets/
|
||||
| | |- Materials/
|
||||
| | |- Models/
|
||||
| | |- Scenes/
|
||||
| | `- Scripts/
|
||||
| |- Library/
|
||||
| | |- ArtifactDB/
|
||||
| | |- Artifacts/
|
||||
| | |- ScriptAssemblies/
|
||||
| | `- SourceAssetDB/
|
||||
| |- Assets.meta
|
||||
| `- Project.xcproject
|
||||
|- scripts/
|
||||
| `- Run-RendererPhaseRegression.ps1
|
||||
|- tests/
|
||||
| |- CMakeLists.txt
|
||||
| |- TEST_SPEC.md
|
||||
| |- Components/
|
||||
| |- Core/
|
||||
| |- Debug/
|
||||
| |- Editor/
|
||||
| |- Fixtures/
|
||||
| |- Input/
|
||||
| |- Memory/
|
||||
| |- NewEditor/ # 当前为空的预留测试根目录
|
||||
| |- Rendering/
|
||||
| | |- integration/
|
||||
| | | |- alpha_cutout_scene/
|
||||
| | | |- camera_post_process_scene/
|
||||
| | | |- directional_shadow_scene/
|
||||
| | | |- final_color_scene/
|
||||
| | | |- multi_light_scene/
|
||||
| | | |- skybox_scene/
|
||||
| | | |- volume_occlusion_scene/
|
||||
| | | |- volume_scene/
|
||||
| | | `- volume_transform_scene/
|
||||
| | `- unit/
|
||||
| |- Resources/
|
||||
| |- RHI/
|
||||
| |- Scene/
|
||||
| |- Scripting/
|
||||
| |- Threading/
|
||||
| `- UI/
|
||||
| |- Core/
|
||||
| |- Editor/
|
||||
| |- Runtime/
|
||||
| `- TEST_SPEC.md
|
||||
|- 参考/
|
||||
| |- Fermion/
|
||||
| |- TransformGizmo/
|
||||
| |- unity editor/
|
||||
| |- unity-editor-icons/
|
||||
| |- unity-icons/
|
||||
| `- UnityRuntimeSceneGizmo-master/
|
||||
`- .vscode/
|
||||
```
|
||||
|
||||
## 文档入口
|
||||
|
||||
- 编辑器说明:[editor/README.md](editor/README.md)
|
||||
- API 文档入口:[docs/api/main.md](docs/api/main.md)
|
||||
- 架构蓝图:[docs/blueprint.md](docs/blueprint.md)
|
||||
- Editor 架构说明:[docs/plan/Editor架构说明.md](docs/plan/Editor架构说明.md)
|
||||
- 测试规范:[tests/TEST_SPEC.md](tests/TEST_SPEC.md)
|
||||
- 协作约定:[AGENT.md](AGENT.md)
|
||||
|
||||
## 当前状态
|
||||
|
||||
`XCEngine` 仍处于高频迭代阶段,但当前仓库已经不是“零散原型集合”,而是一个以编辑器工作流为中心持续收口的引擎工作区。接口、目录和构建细节仍可能调整,但主线方向已经比较明确:
|
||||
|
||||
- 稳定 `RHI / Rendering / Asset Pipeline / Editor` 主链。
|
||||
- 继续推进 `Mono Scripting` 与项目脚本工作流。
|
||||
- 推进 `XCUI` 新编辑器主线从组件库走向完整宿主。
|
||||
|
||||
- `docs/api/main.md`
|
||||
- `editor/README.md`
|
||||
- `AGENT.md`
|
||||
- `docs/blueprint.md`
|
||||
- `tests/TEST_SPEC.md`
|
||||
- `tests/UI/TEST_SPEC.md`
|
||||
- `docs/plan/Editor架构说明.md`
|
||||
- `docs/plan/Library启动预热与运行时异步加载混合重构计划_2026-04-04.md`
|
||||
- `docs/plan/XCUI_NewEditor主线重建计划_2026-04-07.md`
|
||||
- `docs/plan/XCUI完整架构设计与执行计划.md`
|
||||
- `docs/plan/NanoVDB体积云加载阻塞与Runtime上传修复计划_2026-04-10.md`
|
||||
- `docs/plan/Unity风格模型导入与Model资产架构重构计划_2026-04-10.md`
|
||||
- `docs/plan/3DGS专用PLY导入器与GaussianSplat资源缓存正式化计划_2026-04-10.md`
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# XCEngine API Documentation Skill
|
||||
# XCEngine / XCEditor API Documentation Skill
|
||||
|
||||
|
||||
## 目标
|
||||
|
||||
这份规范面向维护 `XCEngine` API 文档的 coding agent。它的目标不是“批量生成一套看起来完整的文档”,而是持续把当前源码、测试和真实调用链路同步到唯一的 canonical API 文档树里。
|
||||
这份规范面向维护 `XCEngine` / `XCEditor` API 文档的 coding agent。它的目标不是“批量生成一套看起来完整的文档”,而是持续把当前源码、测试和真实调用链路同步到当前活跃的 canonical API 文档树里。
|
||||
|
||||
当前仓库已经进入“增量同步”阶段。重点不再是补骨架,而是:
|
||||
|
||||
@@ -12,11 +13,14 @@
|
||||
|
||||
## 当前范围
|
||||
|
||||
API 文档的正式范围包含两部分:
|
||||
API 文档的正式范围包含三部分:
|
||||
|
||||
1. 引擎 public API
|
||||
- 对齐 `engine/include/XCEngine/**`
|
||||
2. Editor source-backed API
|
||||
2. 新 Editor public API
|
||||
- 对齐 `new_editor/include/XCEditor/**`
|
||||
- canonical 文档入口放在 `docs/api/XCEditor/**`
|
||||
3. Editor source-backed API
|
||||
- 对齐 `editor/src/**`
|
||||
- canonical 文档入口仍放在 `docs/api/XCEngine/Editor/**`
|
||||
|
||||
@@ -28,35 +32,46 @@ API 文档的正式范围包含两部分:
|
||||
- 审计结果、阶段性状态
|
||||
- `docs/api/_tools/**`
|
||||
- 审计、生成、修链脚本
|
||||
- `docs/plan/API文档实时同步任务池_2026-04-03.md`
|
||||
- 当前多任务并行同步池
|
||||
- `docs/plan/API文档目录*.md`
|
||||
- 当前活跃 API 计划、重构计划与并行任务板
|
||||
- `docs/plan/API文档目录结构阶段进度_XCEditor与Model收口_2026-04-10.md`
|
||||
- 最近一轮 `XCEditor / Model / GaussianSplat` 收口记录
|
||||
- `docs/used/API文档实时同步任务池_2026-04-03.md`
|
||||
- 最近一轮已完成的归档基线
|
||||
- `README.md` / `editor/README.md` / `AGENT.md`
|
||||
- 这些不是 canonical API 页,但一旦它们引用 API 模块结构、测试目录或 Editor helper 分层,就属于必须同步的活跃协作文档
|
||||
|
||||
## 硬约束
|
||||
|
||||
1. `docs/api/XCEngine/**` 是唯一 canonical API 树。
|
||||
1. `docs/api/XCEngine/**` 与 `docs/api/XCEditor/**` 是当前两棵 canonical API 树;`docs/api/XCEngine/Editor/**` 继续承载 `editor/src/**` 的 source-backed 文档入口。
|
||||
2. 文档必须以“当前 header + 当前实现 + 当前测试 + 当前真实调用点”为依据,不能按旧文档或命名猜行为。
|
||||
3. 删除的 API 页面要一起删除,相关交叉链接也必须一起清理。
|
||||
4. 方法页优先使用源码中的原始函数名;不要擅自改成 kebab-case 或小写别名。
|
||||
5. 不要把“设计意图”写成“当前实现行为”。
|
||||
6. 不要为已经删除的 API 保留默认兼容入口页,除非任务明确要求。
|
||||
7. `rebuild-status.md` 以审计脚本输出为准;并发场景下,stdout 比旧文件内容更可信。
|
||||
8. 只收口活跃文档;`docs/plan/used/**`、`docs/used/**` 等归档材料默认保留历史写法,不要为了“顺手统一”去重写归档。
|
||||
8. 默认先收口活跃文档;只有当任务明确涉及归档链、入口路径或历史基线说明时,才修改 `docs/used/**`。
|
||||
9. Windows 工作树里的路径大小写按真实目录名写,例如 `tests/Editor/`、`tests/Core/`、`tests/Scripting/`,不要继续传播 `tests/editor/`、`tests/core/` 之类的历史噪音。
|
||||
|
||||
## 工作流
|
||||
|
||||
### 1. 开工前先看两份文件
|
||||
### 1. 开工前先看两类文件
|
||||
|
||||
- 任务池:
|
||||
- `docs/plan/API文档实时同步任务池_2026-04-03.md`
|
||||
- 最新活跃计划:
|
||||
- `docs/plan/API文档目录*.md`
|
||||
- `docs/plan/API文档目录结构阶段进度_XCEditor与Model收口_2026-04-10.md`
|
||||
- 最新审计:
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
|
||||
如果任务池和工作树不一致,以当前源码和重新执行审计后的结果为准。
|
||||
如果活跃计划和工作树不一致,以当前源码和重新执行审计后的结果为准。
|
||||
|
||||
如果 `docs/plan/` 下出现日期更晚的 API 相关计划或归档文件,优先读取更新日期更晚的文件,再判断当前任务池是否已经转入 `docs/plan/used/`。
|
||||
如果当前活跃计划没有覆盖你的问题,再回看:
|
||||
|
||||
- `docs/used/API文档实时同步任务池_2026-04-03.md`
|
||||
|
||||
作为最近一轮完成归档的基线。
|
||||
|
||||
如果 `docs/plan/` 下出现日期更晚的 API 相关计划,优先读取日期更晚的活跃文件;当前仓库里的归档根目录是 `docs/used/**`,不要再假设存在 `docs/plan/used/**`。
|
||||
|
||||
如果工作内容会改到 `README.md`、`editor/README.md` 或 `AGENT.md`:
|
||||
|
||||
@@ -121,10 +136,13 @@ python -B docs/api/_tools/audit_api_docs.py
|
||||
- `docs/api/main.md`
|
||||
- API 根页:
|
||||
- `docs/api/XCEngine/XCEngine.md`
|
||||
- `docs/api/XCEditor/XCEditor.md`
|
||||
- 模块页:
|
||||
- `docs/api/XCEngine/{ModuleName}/{ModuleName}.md`
|
||||
- `docs/api/XCEditor/{ModuleName}/{ModuleName}.md`
|
||||
- 子模块页:
|
||||
- `docs/api/XCEngine/{ModuleName}/{SubmoduleName}/{SubmoduleName}.md`
|
||||
- `docs/api/XCEditor/{ModuleName}/{SubmoduleName}/{SubmoduleName}.md`
|
||||
|
||||
示例:
|
||||
|
||||
@@ -132,6 +150,8 @@ python -B docs/api/_tools/audit_api_docs.py
|
||||
- `docs/api/XCEngine/Core/Asset/Asset.md`
|
||||
- `docs/api/XCEngine/Rendering/Passes/Passes.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- `docs/api/XCEditor/Foundation/Foundation.md`
|
||||
- `docs/api/XCEditor/Shell/Shell.md`
|
||||
|
||||
### 2. Header / source-backed 目录
|
||||
|
||||
@@ -324,7 +344,7 @@ docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/
|
||||
## 推荐命令
|
||||
|
||||
```powershell
|
||||
rg --files docs/api/XCEngine
|
||||
rg --files docs/api/XCEngine docs/api/XCEditor
|
||||
rg --files tests/Editor
|
||||
rg -n "SymbolName" engine/include engine/src editor/src tests docs/api
|
||||
python -B docs/api/_tools/audit_api_docs.py
|
||||
|
||||
47
docs/api/XCEditor/Collections/Collections.md
Normal file
47
docs/api/XCEditor/Collections/Collections.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Collections
|
||||
|
||||
**命名空间**: `XCEngine::UI::Editor::Widgets`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器集合类控件子模块,覆盖列表、树、标签栏、滚动视图及其交互辅助。
|
||||
|
||||
## 概述
|
||||
|
||||
`Collections` 主要提供“多项内容如何排布、命中、滚动与选择”的公共 UI 原语。按当前头文件与实现分工:
|
||||
|
||||
- `UIEditorListView*`
|
||||
- 双行列表项布局、命中测试与交互
|
||||
- `UIEditorTreeView*`
|
||||
- 树节点可见性、展开/折叠与行命中
|
||||
- `UIEditorScrollView*`
|
||||
- 视口、内容范围与滚动条交互
|
||||
- `UIEditorTabStrip*`
|
||||
- 面板标签切换
|
||||
- `UIEditorInlineRenameSession`
|
||||
- 就地重命名会话状态
|
||||
|
||||
这些类型大多位于 `XCEngine::UI::Editor::Widgets` 命名空间下,并且被 `Fields` 与 `Shell` 复用。
|
||||
|
||||
## 公开头文件
|
||||
|
||||
- `UIEditorInlineRenameSession.h`
|
||||
- `UIEditorListView.h`
|
||||
- `UIEditorListViewInteraction.h`
|
||||
- `UIEditorScrollView.h`
|
||||
- `UIEditorScrollViewInteraction.h`
|
||||
- `UIEditorTabStrip.h`
|
||||
- `UIEditorTabStripInteraction.h`
|
||||
- `UIEditorTreeView.h`
|
||||
- `UIEditorTreeViewInteraction.h`
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前这里只建立目录索引页,具体头文件页仍需后续分批补齐。
|
||||
- 该模块依赖 `XCEngine/UI/Widgets` 的选择、展开、输入模型,而不是自行维护通用状态容器。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [XCEditor](../XCEditor.md)
|
||||
- [Fields](../Fields/Fields.md)
|
||||
- [Widgets](../Widgets/Widgets.md)
|
||||
@@ -0,0 +1,36 @@
|
||||
# UIEditorInlineRenameSession
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Collections/UIEditorInlineRenameSession.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Collections` 子目录中的 `UIEditorInlineRenameSession` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorInlineRenameSession.h` 是 `XCEditor/Collections` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorInlineRenameSessionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorInlineRenameSessionRequest` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorInlineRenameSessionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorInlineRenameSessionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `active` | `bool` | 结构体公开字段。 | `false` |
|
||||
| `itemId` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `textFieldSpec` | `Widgets::UIEditorTextFieldSpec` | 结构体公开字段。 | `{}` |
|
||||
| `textFieldInteraction` | `UIEditorTextFieldInteractionState` | 结构体公开字段。 | `{}` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Collections.md) - 返回 `Collections` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,37 @@
|
||||
# UIEditorListView
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Collections/UIEditorListView.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Collections` 子目录中的 `UIEditorListView` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorListView.h` 是 `XCEditor/Collections` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorListViewHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorListViewItem` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorListViewState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorListViewMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorListViewPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorListViewLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorListViewHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Collections.md) - 返回 `Collections` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,36 @@
|
||||
# UIEditorListViewInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Collections/UIEditorListViewInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Collections` 子目录中的 `UIEditorListViewInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorListViewInteraction.h` 是 `XCEditor/Collections` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorListViewInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorListViewInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorListViewInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `listViewState` | `Widgets::UIEditorListViewState` | 结构体公开字段。 | `{}` |
|
||||
| `keyboardNavigation` | `::XCEngine::UI::Widgets::UIKeyboardNavigationModel` | 结构体公开字段。 | `{}` |
|
||||
| `selectionAnchorId` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Collections.md) - 返回 `Collections` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,38 @@
|
||||
# UIEditorScrollView
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Collections/UIEditorScrollView.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Collections` 子目录中的 `UIEditorScrollView` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorScrollView.h` 是 `XCEditor/Collections` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorScrollViewHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorScrollViewState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorScrollViewMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorScrollViewPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorScrollViewLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorScrollViewHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Content` | - | 枚举项。 |
|
||||
| `ScrollbarTrack` | - | 枚举项。 |
|
||||
| `ScrollbarThumb` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Collections.md) - 返回 `Collections` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,36 @@
|
||||
# UIEditorScrollViewInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Collections/UIEditorScrollViewInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Collections` 子目录中的 `UIEditorScrollViewInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorScrollViewInteraction.h` 是 `XCEditor/Collections` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorScrollViewInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorScrollViewInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorScrollViewInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `scrollViewState` | `Widgets::UIEditorScrollViewState` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `thumbDragStartPointerY` | `float` | 结构体公开字段。 | `0.0f` |
|
||||
| `thumbDragStartOffset` | `float` | 结构体公开字段。 | `0.0f` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Collections.md) - 返回 `Collections` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,39 @@
|
||||
# UIEditorTabStrip
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Collections/UIEditorTabStrip.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Collections` 子目录中的 `UIEditorTabStrip` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorTabStrip.h` 是 `XCEditor/Collections` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorTabStripItem` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTabStripState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTabStripMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTabStripPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTabStripLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTabStripHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorTabStripHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `tabId` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `title` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `closable` | `bool` | 结构体公开字段。 | `true` |
|
||||
| `desiredHeaderLabelWidth` | `float` | 结构体公开字段。 | `0.0f` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Collections.md) - 返回 `Collections` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,36 @@
|
||||
# UIEditorTabStripInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Collections/UIEditorTabStripInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Collections` 子目录中的 `UIEditorTabStripInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorTabStripInteraction.h` 是 `XCEditor/Collections` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorTabStripInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTabStripInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTabStripInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `tabStripState` | `Widgets::UIEditorTabStripState` | 结构体公开字段。 | `{}` |
|
||||
| `navigationModel` | `::XCEngine::UI::Widgets::UITabStripModel` | 结构体公开字段。 | `{}` |
|
||||
| `pressedTarget` | `Widgets::UIEditorTabStripHitTarget` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Collections.md) - 返回 `Collections` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,38 @@
|
||||
# UIEditorTreeView
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Collections/UIEditorTreeView.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Collections` 子目录中的 `UIEditorTreeView` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorTreeView.h` 是 `XCEditor/Collections` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorTreeViewHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorTreeViewItem` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTreeViewState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTreeViewMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTreeViewPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTreeViewLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTreeViewHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `Disclosure` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Collections.md) - 返回 `Collections` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,36 @@
|
||||
# UIEditorTreeViewInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Collections/UIEditorTreeViewInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Collections` 子目录中的 `UIEditorTreeViewInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorTreeViewInteraction.h` 是 `XCEditor/Collections` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorTreeViewInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTreeViewInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTreeViewInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `treeViewState` | `Widgets::UIEditorTreeViewState` | 结构体公开字段。 | `{}` |
|
||||
| `keyboardNavigation` | `::XCEngine::UI::Widgets::UIKeyboardNavigationModel` | 结构体公开字段。 | `{}` |
|
||||
| `selectionAnchorId` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Collections.md) - 返回 `Collections` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
68
docs/api/XCEditor/Fields/Fields.md
Normal file
68
docs/api/XCEditor/Fields/Fields.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Fields
|
||||
|
||||
**命名空间**: `XCEngine::UI::Editor::Widgets`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器字段控件子模块,覆盖布尔、数字、文本、颜色、对象、资源与属性网格等值编辑控件。
|
||||
|
||||
## 概述
|
||||
|
||||
`Fields` 面向“属性编辑”场景。当前头文件可以分成两层:
|
||||
|
||||
- 单字段控件
|
||||
- `UIEditorBoolField*`
|
||||
- `UIEditorNumberField*`
|
||||
- `UIEditorTextField*`
|
||||
- `UIEditorEnumField*`
|
||||
- `UIEditorColorField*`
|
||||
- `UIEditorObjectField*`
|
||||
- `UIEditorAssetField*`
|
||||
- `UIEditorVector2/3/4Field*`
|
||||
- 聚合编辑控件
|
||||
- `UIEditorPropertyGrid*`
|
||||
- 把 section、field row、弹窗菜单和颜色字段等组合成统一 inspector 布局
|
||||
|
||||
按当前 `UIEditorPropertyGrid.h`,这一层会复用:
|
||||
|
||||
- `Collections` 中的滚动/列表布局能力
|
||||
- `Shell/UIEditorMenuPopup.h` 提供的弹出菜单能力
|
||||
- `Widgets/UIEditorFieldRowLayout.h` 和 `UIEditorTextLayout.h` 等基础布局工具
|
||||
|
||||
## 公开头文件
|
||||
|
||||
- `UIEditorAssetField.h`
|
||||
- `UIEditorAssetFieldInteraction.h`
|
||||
- `UIEditorBoolField.h`
|
||||
- `UIEditorBoolFieldInteraction.h`
|
||||
- `UIEditorColorField.h`
|
||||
- `UIEditorColorFieldInteraction.h`
|
||||
- `UIEditorEnumField.h`
|
||||
- `UIEditorEnumFieldInteraction.h`
|
||||
- `UIEditorFieldStyle.h`
|
||||
- `UIEditorNumberField.h`
|
||||
- `UIEditorNumberFieldInteraction.h`
|
||||
- `UIEditorObjectField.h`
|
||||
- `UIEditorObjectFieldInteraction.h`
|
||||
- `UIEditorPropertyGrid.h`
|
||||
- `UIEditorPropertyGridInteraction.h`
|
||||
- `UIEditorTextField.h`
|
||||
- `UIEditorTextFieldInteraction.h`
|
||||
- `UIEditorVector2Field.h`
|
||||
- `UIEditorVector2FieldInteraction.h`
|
||||
- `UIEditorVector3Field.h`
|
||||
- `UIEditorVector3FieldInteraction.h`
|
||||
- `UIEditorVector4Field.h`
|
||||
- `UIEditorVector4FieldInteraction.h`
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前这里只建立目录索引页,具体头文件页仍需后续逐个补齐。
|
||||
- 这一层当前偏重 UI 表达与交互状态,不负责真正的资产解析、对象生命周期或命令持久化。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [XCEditor](../XCEditor.md)
|
||||
- [Collections](../Collections/Collections.md)
|
||||
- [Shell](../Shell/Shell.md)
|
||||
- [Widgets](../Widgets/Widgets.md)
|
||||
@@ -0,0 +1,40 @@
|
||||
# UIEditorAssetField
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorAssetField.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorAssetField` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorAssetField.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorAssetFieldHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorAssetFieldSpec` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorAssetFieldState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorAssetFieldMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorAssetFieldPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorAssetFieldLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorAssetFieldHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `ValueBox` | - | 枚举项。 |
|
||||
| `PickerButton` | - | 枚举项。 |
|
||||
| `ClearButton` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,34 @@
|
||||
# UIEditorAssetFieldInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorAssetFieldInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorAssetFieldInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorAssetFieldInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorAssetFieldInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorAssetFieldInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorAssetFieldInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `fieldState` | `Widgets::UIEditorAssetFieldState` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,38 @@
|
||||
# UIEditorBoolField
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorBoolField.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorBoolField` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorBoolField.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorBoolFieldHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorBoolFieldSpec` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorBoolFieldState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorBoolFieldMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorBoolFieldPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorBoolFieldLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorBoolFieldHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `Checkbox` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,34 @@
|
||||
# UIEditorBoolFieldInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorBoolFieldInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorBoolFieldInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorBoolFieldInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorBoolFieldInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorBoolFieldInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorBoolFieldInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `fieldState` | `Widgets::UIEditorBoolFieldState` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,46 @@
|
||||
# UIEditorColorField
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorColorField.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorColorField` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorColorField.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorColorFieldHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorColorFieldSpec` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorColorFieldState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorColorFieldMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorColorFieldPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorColorFieldLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorColorFieldHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `Swatch` | - | 枚举项。 |
|
||||
| `PopupSurface` | - | 枚举项。 |
|
||||
| `PopupCloseButton` | - | 枚举项。 |
|
||||
| `HueWheel` | - | 枚举项。 |
|
||||
| `SaturationValue` | - | 枚举项。 |
|
||||
| `RedChannel` | - | 枚举项。 |
|
||||
| `GreenChannel` | - | 枚举项。 |
|
||||
| `BlueChannel` | - | 枚举项。 |
|
||||
| `AlphaChannel` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,34 @@
|
||||
# UIEditorColorFieldInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorColorFieldInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorColorFieldInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorColorFieldInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorColorFieldInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorColorFieldInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorColorFieldInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `colorFieldState` | `Widgets::UIEditorColorFieldState` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,39 @@
|
||||
# UIEditorEnumField
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorEnumField.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorEnumField` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorEnumField.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorEnumFieldHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorEnumFieldSpec` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorEnumFieldState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorEnumFieldMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorEnumFieldPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorEnumFieldLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorEnumFieldHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `ValueBox` | - | 枚举项。 |
|
||||
| `DropdownArrow` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,37 @@
|
||||
# UIEditorEnumFieldInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorEnumFieldInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorEnumFieldInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorEnumFieldInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorEnumFieldInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorEnumFieldInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorEnumFieldInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `fieldState` | `Widgets::UIEditorEnumFieldState` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `highlightedIndex` | `std::size_t` | 结构体公开字段。 | `Widgets::UIEditorMenuPopupInvalidIndex` |
|
||||
| `pressedPopupIndex` | `std::size_t` | 结构体公开字段。 | `Widgets::UIEditorMenuPopupInvalidIndex` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
| `popupOpen` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,18 @@
|
||||
# UIEditorFieldStyle
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `header`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorFieldStyle.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorFieldStyle` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorFieldStyle.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,38 @@
|
||||
# UIEditorNumberField
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorNumberField.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorNumberField` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorNumberField.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorNumberFieldHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorNumberFieldSpec` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorNumberFieldState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorNumberFieldMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorNumberFieldPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorNumberFieldLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorNumberFieldHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `ValueBox` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,36 @@
|
||||
# UIEditorNumberFieldInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorNumberFieldInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorNumberFieldInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorNumberFieldInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorNumberFieldInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorNumberFieldInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorNumberFieldInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `numberFieldState` | `Widgets::UIEditorNumberFieldState` | 结构体公开字段。 | `{}` |
|
||||
| `textInputState` | `::XCEngine::UI::Text::UITextInputState` | 结构体公开字段。 | `{}` |
|
||||
| `editModel` | `::XCEngine::UI::Widgets::UIPropertyEditModel` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,40 @@
|
||||
# UIEditorObjectField
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorObjectField.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorObjectField` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorObjectField.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorObjectFieldHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorObjectFieldSpec` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorObjectFieldState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorObjectFieldMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorObjectFieldPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorObjectFieldLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorObjectFieldHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `ValueBox` | - | 枚举项。 |
|
||||
| `ClearButton` | - | 枚举项。 |
|
||||
| `PickerButton` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,34 @@
|
||||
# UIEditorObjectFieldInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorObjectFieldInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorObjectFieldInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorObjectFieldInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorObjectFieldInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorObjectFieldInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorObjectFieldInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `fieldState` | `Widgets::UIEditorObjectFieldState` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,53 @@
|
||||
# UIEditorPropertyGrid
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorPropertyGrid.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorPropertyGrid` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorPropertyGrid.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorPropertyGridFieldKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridFieldLocation` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridNumberFieldValue` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridEnumFieldValue` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridColorFieldValue` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridVector2FieldValue` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridVector3FieldValue` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridVector4FieldValue` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridField` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridSection` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridColorFieldVisualState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `Text` | `0` | 枚举项。 |
|
||||
| `Bool` | - | 枚举项。 |
|
||||
| `Number` | - | 枚举项。 |
|
||||
| `Enum` | - | 枚举项。 |
|
||||
| `Color` | - | 枚举项。 |
|
||||
| `Vector2` | - | 枚举项。 |
|
||||
| `Vector3` | - | 枚举项。 |
|
||||
| `Vector4` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,37 @@
|
||||
# UIEditorPropertyGridInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorPropertyGridInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorPropertyGridInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorPropertyGridInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorPropertyGridInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorPropertyGridInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `propertyGridState` | `Widgets::UIEditorPropertyGridState` | 结构体公开字段。 | `{}` |
|
||||
| `keyboardNavigation` | `::XCEngine::UI::Widgets::UIKeyboardNavigationModel` | 结构体公开字段。 | `{}` |
|
||||
| `textInputState` | `::XCEngine::UI::Text::UITextInputState` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `pressedPopupIndex` | `std::size_t` | 结构体公开字段。 | `Widgets::UIEditorPropertyGridInvalidIndex` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,38 @@
|
||||
# UIEditorTextField
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorTextField.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorTextField` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorTextField.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorTextFieldHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorTextFieldSpec` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTextFieldState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTextFieldMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTextFieldPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTextFieldLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTextFieldHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `ValueBox` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,36 @@
|
||||
# UIEditorTextFieldInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorTextFieldInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorTextFieldInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorTextFieldInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorTextFieldInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTextFieldInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorTextFieldInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `textFieldState` | `Widgets::UIEditorTextFieldState` | 结构体公开字段。 | `{}` |
|
||||
| `textInputState` | `::XCEngine::UI::Text::UITextInputState` | 结构体公开字段。 | `{}` |
|
||||
| `editModel` | `::XCEngine::UI::Widgets::UIPropertyEditModel` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,38 @@
|
||||
# UIEditorVector2Field
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorVector2Field.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorVector2Field` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorVector2Field.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorVector2FieldHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector2FieldSpec` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector2FieldState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector2FieldMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector2FieldPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector2FieldLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector2FieldHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `Component` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,36 @@
|
||||
# UIEditorVector2FieldInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorVector2FieldInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorVector2FieldInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorVector2FieldInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorVector2FieldInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector2FieldInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector2FieldInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `vector2FieldState` | `Widgets::UIEditorVector2FieldState` | 结构体公开字段。 | `{}` |
|
||||
| `textInputState` | `::XCEngine::UI::Text::UITextInputState` | 结构体公开字段。 | `{}` |
|
||||
| `editModel` | `::XCEngine::UI::Widgets::UIPropertyEditModel` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,38 @@
|
||||
# UIEditorVector3Field
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorVector3Field.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorVector3Field` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorVector3Field.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorVector3FieldHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector3FieldSpec` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector3FieldState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector3FieldMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector3FieldPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector3FieldLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector3FieldHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `Component` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,36 @@
|
||||
# UIEditorVector3FieldInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorVector3FieldInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorVector3FieldInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorVector3FieldInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorVector3FieldInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector3FieldInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector3FieldInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `vector3FieldState` | `Widgets::UIEditorVector3FieldState` | 结构体公开字段。 | `{}` |
|
||||
| `textInputState` | `::XCEngine::UI::Text::UITextInputState` | 结构体公开字段。 | `{}` |
|
||||
| `editModel` | `::XCEngine::UI::Widgets::UIPropertyEditModel` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,38 @@
|
||||
# UIEditorVector4Field
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorVector4Field.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorVector4Field` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorVector4Field.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorVector4FieldHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector4FieldSpec` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector4FieldState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector4FieldMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector4FieldPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector4FieldLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector4FieldHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `Row` | - | 枚举项。 |
|
||||
| `Component` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,36 @@
|
||||
# UIEditorVector4FieldInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Fields/UIEditorVector4FieldInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Fields` 子目录中的 `UIEditorVector4FieldInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorVector4FieldInteraction.h` 是 `XCEditor/Fields` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorVector4FieldInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector4FieldInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorVector4FieldInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `vector4FieldState` | `Widgets::UIEditorVector4FieldState` | 结构体公开字段。 | `{}` |
|
||||
| `textInputState` | `::XCEngine::UI::Text::UITextInputState` | 结构体公开字段。 | `{}` |
|
||||
| `editModel` | `::XCEngine::UI::Widgets::UIPropertyEditModel` | 结构体公开字段。 | `{}` |
|
||||
| `pointerPosition` | `::XCEngine::UI::UIPoint` | 结构体公开字段。 | `{}` |
|
||||
| `hasPointerPosition` | `bool` | 结构体公开字段。 | `false` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Fields.md) - 返回 `Fields` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
50
docs/api/XCEditor/Foundation/Foundation.md
Normal file
50
docs/api/XCEditor/Foundation/Foundation.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Foundation
|
||||
|
||||
**命名空间**: `XCEngine::UI::Editor`
|
||||
|
||||
**类型**: `module`
|
||||
|
||||
**描述**: `XCEditor` 的基础协议层,覆盖命令注册、命令派发、快捷键管理以及主题度量解析入口。
|
||||
|
||||
## 概览
|
||||
|
||||
`Foundation` 解决的是“shell 和控件真正运行前,需要先有一套什么样的 editor 级基础协议”。
|
||||
|
||||
按当前代码,职责主要分成四块:
|
||||
|
||||
- `UIEditorCommandRegistry.h`
|
||||
- 定义 editor 命令描述、workspace 命令描述以及注册表校验规则。
|
||||
- `UIEditorCommandDispatcher.h`
|
||||
- 把 `commandId` 解析为 workspace command 或 host command,并执行 preview / dispatch。
|
||||
- `UIEditorShortcutManager.h`
|
||||
- 复用 `XCEngine::UI::UIShortcutRegistry` 完成快捷键绑定、冲突校验与调度。
|
||||
- `UIEditorTheme.h`
|
||||
- 为 `Collections / Fields / Shell` 汇总默认 metrics / palette 解析入口。
|
||||
|
||||
这层不直接渲染 widget,也不直接拥有 workspace 状态;它更像 `XCEditor` 的“命令 + 输入 + 主题”底座。
|
||||
|
||||
## 当前调用链
|
||||
|
||||
- `new_editor/src/Shell/UIEditorShellAsset.cpp` 会从 shell asset 构造命令注册表和快捷键管理器。
|
||||
- `new_editor/src/Shell/UIEditorMenuModel.cpp` 通过命令注册表、命令派发器和快捷键管理器生成 menu item 的启用态与 shortcut 文案。
|
||||
- 多组 `tests/UI/Editor/unit/**` 与 `tests/UI/Editor/integration/**` 当前直接把这层当作 editor shell 的最小可验证基础设施。
|
||||
|
||||
## 公开头文件
|
||||
|
||||
- [UIEditorCommandRegistry](UIEditorCommandRegistry/UIEditorCommandRegistry.md) - editor 命令描述与注册表校验规则。
|
||||
- [UIEditorCommandDispatcher](UIEditorCommandDispatcher/UIEditorCommandDispatcher.md) - `commandId -> workspace/host dispatch` 入口。
|
||||
- [UIEditorShortcutManager](UIEditorShortcutManager/UIEditorShortcutManager.md) - editor 快捷键绑定、校验和调度入口。
|
||||
- [UIEditorTheme](UIEditorTheme/UIEditorTheme.md) - 默认 metrics / palette 解析入口。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 该模块不直接渲染 UI,而是为 `Shell`、`Collections` 和 `Fields` 提供命令、快捷键和主题基础能力。
|
||||
- 当前主题解析函数统一返回静态默认值,还没有引入动态主题切换或 style 覆盖链。
|
||||
- host command 仍然通过 `UIEditorHostCommandHandler` 抽象对外,不把宿主实现细节泄漏回 public header。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [XCEditor](../XCEditor.md)
|
||||
- [Shell](../Shell/Shell.md)
|
||||
- [Collections](../Collections/Collections.md)
|
||||
- [Fields](../Fields/Fields.md)
|
||||
@@ -0,0 +1,41 @@
|
||||
# UIEditorCommandDispatcher::UIEditorCommandDispatcher()
|
||||
|
||||
构造对象。
|
||||
|
||||
该方法在 `XCEditor/Foundation/UIEditorCommandDispatcher.h` 中提供了 2 个重载,当前页面统一汇总这些公开声明。
|
||||
|
||||
## 重载 1: 声明
|
||||
|
||||
```cpp
|
||||
UIEditorCommandDispatcher() = default;
|
||||
```
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
|
||||
## 重载 2: 声明
|
||||
|
||||
```cpp
|
||||
explicit UIEditorCommandDispatcher(UIEditorCommandRegistry commandRegistry);
|
||||
```
|
||||
|
||||
**参数:**
|
||||
- `commandRegistry` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorCommandDispatcher.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorCommandDispatcher object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorCommandDispatcher.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,32 @@
|
||||
# UIEditorCommandDispatcher::Dispatch
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorCommandDispatchResult Dispatch( std::string_view commandId, UIEditorWorkspaceController& controller) const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorCommandDispatcher.h`,当前页面用于固定 `UIEditorCommandDispatcher` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `commandId` - 参数语义详见头文件声明。
|
||||
- `controller` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `UIEditorCommandDispatchResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorCommandDispatcher.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorCommandDispatcher object;
|
||||
// 根据上下文补齐参数后调用 UIEditorCommandDispatcher::Dispatch(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorCommandDispatcher.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,32 @@
|
||||
# UIEditorCommandDispatcher::Evaluate
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorCommandEvaluationResult Evaluate( std::string_view commandId, const UIEditorWorkspaceController& controller) const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorCommandDispatcher.h`,当前页面用于固定 `UIEditorCommandDispatcher` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `commandId` - 参数语义详见头文件声明。
|
||||
- `controller` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `UIEditorCommandEvaluationResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorCommandDispatcher.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorCommandDispatcher object;
|
||||
// 根据上下文补齐参数后调用 UIEditorCommandDispatcher::Evaluate(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorCommandDispatcher.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorCommandDispatcher::GetCommandRegistry
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
const UIEditorCommandRegistry& GetCommandRegistry() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorCommandDispatcher.h`,当前页面用于固定 `UIEditorCommandDispatcher` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `const UIEditorCommandRegistry&` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorCommandDispatcher.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorCommandDispatcher object;
|
||||
// 根据上下文补齐参数后调用 UIEditorCommandDispatcher::GetCommandRegistry(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorCommandDispatcher.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorCommandDispatcher::GetHostCommandHandler
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
UIEditorHostCommandHandler* GetHostCommandHandler() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorCommandDispatcher.h`,当前页面用于固定 `UIEditorCommandDispatcher` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `UIEditorHostCommandHandler*` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorCommandDispatcher.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorCommandDispatcher object;
|
||||
// 根据上下文补齐参数后调用 UIEditorCommandDispatcher::GetHostCommandHandler(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorCommandDispatcher.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# UIEditorCommandDispatcher::SetHostCommandHandler
|
||||
|
||||
设置相关状态或配置。
|
||||
|
||||
```cpp
|
||||
void SetHostCommandHandler(UIEditorHostCommandHandler* handler);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorCommandDispatcher.h`,当前页面用于固定 `UIEditorCommandDispatcher` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `handler` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorCommandDispatcher.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorCommandDispatcher object;
|
||||
// 根据上下文补齐参数后调用 UIEditorCommandDispatcher::SetHostCommandHandler(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorCommandDispatcher.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,60 @@
|
||||
# UIEditorCommandDispatcher
|
||||
|
||||
**命名空间**: `XCEngine::UI::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**头文件**: `XCEditor/Foundation/UIEditorCommandDispatcher.h`
|
||||
|
||||
**描述**: editor 命令执行入口,负责把 `commandId` 解析为 workspace command 或 host command,并执行 preview / dispatch。
|
||||
|
||||
## 概览
|
||||
|
||||
`UIEditorCommandDispatcher` 位于命令描述层和 shell 工作区控制器之间。它当前做两步:
|
||||
|
||||
1. `Evaluate(...)`
|
||||
- 校验注册表,查找 `commandId`,把 `ActivePanel` / `FixedPanelId` 等静态描述解析成当前可执行的具体命令。
|
||||
2. `Dispatch(...)`
|
||||
- 在 `Evaluate(...)` 成功后,把 workspace 命令交给 `UIEditorWorkspaceController`,或者把 host 命令交给 `UIEditorHostCommandHandler`。
|
||||
|
||||
这让 menu、shortcut 和 shell interaction 都可以共享同一套命令求值与分发逻辑。
|
||||
|
||||
## 主要声明
|
||||
|
||||
| 声明 | 角色 |
|
||||
|------|------|
|
||||
| `UIEditorHostCommandHandler` | 宿主命令执行抽象,允许 shell 外部接管 host 命令。 |
|
||||
| `UIEditorCommandEvaluationCode` | 命令求值失败或成功的细分原因。 |
|
||||
| `UIEditorCommandEvaluationResult` | `Evaluate(...)` 的结果,包含解析出的 workspace command 与 preview 结果。 |
|
||||
| `UIEditorCommandDispatchStatus` | 最终 dispatch 状态。 |
|
||||
| `UIEditorCommandDispatchResult` | `Dispatch(...)` 的结果。 |
|
||||
| `UIEditorCommandDispatcher` | 命令求值与分发器本体。 |
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- `ValidateConfiguration()` 直接复用 `ValidateUIEditorCommandRegistry(...)`。
|
||||
- `Evaluate(...)` 当前会:
|
||||
- 在注册表无效时返回 `InvalidCommandRegistry`
|
||||
- 在命令不存在时返回 `UnknownCommandId`
|
||||
- 对 `Host` 命令转发给 `UIEditorHostCommandHandler::EvaluateHostCommand(...)`
|
||||
- 对 `Workspace` 命令解析 `panelSource`
|
||||
- 在 `ActivePanel` 但当前 workspace 没有 active panel 时返回 `MissingActivePanel`
|
||||
- 复制一份 controller 做 preview dispatch,用 `previewResult` 预测命令是否会被拒绝
|
||||
- `Dispatch(...)` 当前先调用 `Evaluate(...)`,只有可执行时才真正分发。
|
||||
- host 命令和 workspace 命令共享统一结果结构,但最终执行路径不同。
|
||||
|
||||
## 测试与调用链
|
||||
|
||||
- `tests/UI/Editor/unit/test_ui_editor_command_dispatcher.cpp`
|
||||
- 当前覆盖 active panel 解析、缺少 active panel 的拒绝路径,以及 dispatch 后 workspace 状态变更。
|
||||
- `tests/UI/Editor/unit/test_ui_editor_shell_interaction.cpp`
|
||||
- 当前通过 shell interaction 间接消费命令派发器。
|
||||
- `tests/UI/Editor/integration/shell/menu_bar_basic/main.cpp`
|
||||
- 当前把命令派发器挂进 menu bar / context menu 的真实交互路径。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Foundation](../Foundation.md)
|
||||
- [UIEditorCommandRegistry](../UIEditorCommandRegistry/UIEditorCommandRegistry.md)
|
||||
- [UIEditorShortcutManager](../UIEditorShortcutManager/UIEditorShortcutManager.md)
|
||||
- [UIEditorWorkspaceController](../../Shell/UIEditorWorkspaceController/UIEditorWorkspaceController.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorCommandDispatcher::ValidateConfiguration
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorCommandRegistryValidationResult ValidateConfiguration() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorCommandDispatcher.h`,当前页面用于固定 `UIEditorCommandDispatcher` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `UIEditorCommandRegistryValidationResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorCommandDispatcher.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorCommandDispatcher object;
|
||||
// 根据上下文补齐参数后调用 UIEditorCommandDispatcher::ValidateConfiguration(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorCommandDispatcher.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,59 @@
|
||||
# UIEditorCommandRegistry
|
||||
|
||||
**命名空间**: `XCEngine::UI::Editor`
|
||||
|
||||
**类型**: `enums + structs + functions`
|
||||
|
||||
**头文件**: `XCEditor/Foundation/UIEditorCommandRegistry.h`
|
||||
|
||||
**描述**: editor 命令描述协议与注册表校验入口,负责定义 workspace/host 命令的静态声明格式。
|
||||
|
||||
## 概览
|
||||
|
||||
`UIEditorCommandRegistry.h` 是 `XCEditor` 命令系统的静态描述层。它不执行命令,而是先回答这些问题:
|
||||
|
||||
- 一个 editor 命令的 `commandId`、`displayName` 和命令种类是什么。
|
||||
- 这个命令对应的是 workspace command 还是 host command。
|
||||
- 如果是 workspace command,它的 panel 路由来自固定 panel、当前 active panel,还是根本不需要 panel。
|
||||
- 当前整张命令表是否合法,是否存在重复 id、空 displayName 或错误的 panel source 组合。
|
||||
|
||||
## 主要声明
|
||||
|
||||
| 声明 | 角色 |
|
||||
|------|------|
|
||||
| `UIEditorCommandKind` | 区分 `Workspace` 与 `Host` 命令。 |
|
||||
| `UIEditorCommandPanelSource` | 描述 panel 路由来自 `None / FixedPanelId / ActivePanel`。 |
|
||||
| `UIEditorWorkspaceCommandDescriptor` | 把高层命令映射到 `UIEditorWorkspaceCommandKind + panel routing`。 |
|
||||
| `UIEditorCommandDescriptor` | 单个 editor 命令的完整静态描述。 |
|
||||
| `UIEditorCommandRegistry` | 命令描述表。 |
|
||||
| `UIEditorCommandRegistryValidationCode` | 注册表校验失败原因。 |
|
||||
| `FindUIEditorCommandDescriptor(...)` | 通过 `commandId` 查找描述。 |
|
||||
| `ValidateUIEditorCommandRegistry(...)` | 校验命令表的完整性与路由合法性。 |
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- `ValidateUIEditorCommandRegistry(...)` 会拒绝:
|
||||
- 空 `commandId`
|
||||
- 空 `displayName`
|
||||
- 重复 `commandId`
|
||||
- host 命令错误携带 workspace panel routing
|
||||
- 需要 panel 的 workspace 命令却没有 panel source
|
||||
- 不需要 panel 的命令却错误携带 `FixedPanelId` / `ActivePanel`
|
||||
- `FindUIEditorCommandDescriptor(...)` 当前按线性遍历 `registry.commands` 查找。
|
||||
- `CommandKindRequiresPanelId(...)` 当前把 `OpenPanel / ClosePanel / ShowPanel / HidePanel / ActivatePanel` 视为需要 panel 路由;`ResetWorkspace` 不需要。
|
||||
|
||||
## 测试与调用链
|
||||
|
||||
- `tests/UI/Editor/unit/test_ui_editor_command_registry.cpp`
|
||||
- 当前覆盖 descriptor 查找、重复 id、空 displayName 和 panel source 校验。
|
||||
- `new_editor/src/Foundation/UIEditorCommandDispatcher.cpp`
|
||||
- 直接依赖这份注册表做命令解析和配置校验。
|
||||
- `new_editor/src/Shell/UIEditorMenuModel.cpp`
|
||||
- 当前用它决定 menu item 的 command 元数据与启用态来源。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Foundation](../Foundation.md)
|
||||
- [UIEditorCommandDispatcher](../UIEditorCommandDispatcher/UIEditorCommandDispatcher.md)
|
||||
- [UIEditorShortcutManager](../UIEditorShortcutManager/UIEditorShortcutManager.md)
|
||||
- [UIEditorWorkspaceController](../../Shell/UIEditorWorkspaceController/UIEditorWorkspaceController.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorShortcutManager::ClearBindings
|
||||
|
||||
清空内部数据。
|
||||
|
||||
```cpp
|
||||
void ClearBindings();
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::ClearBindings(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,41 @@
|
||||
# UIEditorShortcutManager::UIEditorShortcutManager()
|
||||
|
||||
构造对象。
|
||||
|
||||
该方法在 `XCEditor/Foundation/UIEditorShortcutManager.h` 中提供了 2 个重载,当前页面统一汇总这些公开声明。
|
||||
|
||||
## 重载 1: 声明
|
||||
|
||||
```cpp
|
||||
UIEditorShortcutManager() = default;
|
||||
```
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
|
||||
## 重载 2: 声明
|
||||
|
||||
```cpp
|
||||
explicit UIEditorShortcutManager(UIEditorCommandRegistry commandRegistry);
|
||||
```
|
||||
|
||||
**参数:**
|
||||
- `commandRegistry` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,33 @@
|
||||
# UIEditorShortcutManager::Dispatch
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorShortcutDispatchResult Dispatch( const XCEngine::UI::UIInputEvent& event, const XCEngine::UI::UIShortcutContext& shortcutContext, UIEditorWorkspaceController& controller) const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `event` - 参数语义详见头文件声明。
|
||||
- `shortcutContext` - 参数语义详见头文件声明。
|
||||
- `controller` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `UIEditorShortcutDispatchResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::Dispatch(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorShortcutManager::GetCommandDispatcher
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
const UIEditorCommandDispatcher& GetCommandDispatcher() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `const UIEditorCommandDispatcher&` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::GetCommandDispatcher(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorShortcutManager::GetCommandRegistry
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
const UIEditorCommandRegistry& GetCommandRegistry() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `const UIEditorCommandRegistry&` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::GetCommandRegistry(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorShortcutManager::GetHostCommandHandler
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
UIEditorHostCommandHandler* GetHostCommandHandler() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `UIEditorHostCommandHandler*` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::GetHostCommandHandler(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# UIEditorShortcutManager::GetPreferredShortcutText
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
std::string GetPreferredShortcutText(std::string_view commandId) const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `commandId` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `std::string` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::GetPreferredShortcutText(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorShortcutManager::GetShortcutRegistry
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
const XCEngine::UI::UIShortcutRegistry& GetShortcutRegistry() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `const XCEngine::UI::UIShortcutRegistry&` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::GetShortcutRegistry(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# UIEditorShortcutManager::RegisterBinding
|
||||
|
||||
注册对象、回调或映射。
|
||||
|
||||
```cpp
|
||||
std::uint64_t RegisterBinding(const XCEngine::UI::UIShortcutBinding& binding);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `binding` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `std::uint64_t` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::RegisterBinding(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# UIEditorShortcutManager::SetHostCommandHandler
|
||||
|
||||
设置相关状态或配置。
|
||||
|
||||
```cpp
|
||||
void SetHostCommandHandler(UIEditorHostCommandHandler* handler);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `handler` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::SetHostCommandHandler(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,64 @@
|
||||
# UIEditorShortcutManager
|
||||
|
||||
**命名空间**: `XCEngine::UI::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**头文件**: `XCEditor/Foundation/UIEditorShortcutManager.h`
|
||||
|
||||
**描述**: editor 快捷键绑定与调度入口,负责把 `UIShortcutRegistry` 的匹配结果连接到 editor 命令系统。
|
||||
|
||||
## 概览
|
||||
|
||||
`UIEditorShortcutManager` 在 `UIShortcutRegistry` 和 `UIEditorCommandDispatcher` 之间增加了一层 editor 语义:
|
||||
|
||||
- 先校验 command registry 和 shortcut binding 是否自洽
|
||||
- 再根据输入事件和 `UIShortcutContext` 找到最佳匹配 binding
|
||||
- 最后把匹配结果转换成 editor command dispatch
|
||||
|
||||
它同时还承担 shortcut 文案格式化,所以 menu bar / context menu 可以直接显示“当前推荐快捷键文本”。
|
||||
|
||||
## 主要声明
|
||||
|
||||
| 声明 | 角色 |
|
||||
|------|------|
|
||||
| `UIEditorShortcutManagerValidationCode` | 快捷键配置校验失败原因。 |
|
||||
| `UIEditorShortcutManagerValidationResult` | 快捷键配置校验结果。 |
|
||||
| `UIEditorShortcutDispatchStatus` | `NoMatch / Suppressed / Dispatched / Rejected` 四类结果。 |
|
||||
| `UIEditorShortcutDispatchResult` | dispatch 后返回的命令 id、scope、owner 和 workspace command 结果。 |
|
||||
| `UIEditorShortcutManager` | 快捷键绑定、校验和调度器本体。 |
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- `ValidateConfiguration()` 当前会拒绝:
|
||||
- 无效 command registry
|
||||
- binding 缺少 `commandId`
|
||||
- binding 指向未知命令
|
||||
- `keyCode == 0`
|
||||
- 非 `Global` scope 却没有 `ownerId`
|
||||
- chord/scope/owner 完全冲突的重复 binding
|
||||
- `GetPreferredShortcutText(...)` 会按 `Widget > Panel > Window > Global` 的展示优先级挑选 binding,并把 chord 格式化成 `Ctrl+H` 这类文本。
|
||||
- `Dispatch(...)` 当前流程是:
|
||||
- 配置校验
|
||||
- `m_shortcutRegistry.Match(...)`
|
||||
- 若 `textInputActive == true`,返回 `Suppressed`
|
||||
- 调用 `m_commandDispatcher.Dispatch(...)`
|
||||
- 把匹配到的 scope / owner 和 command result 一并回填到结果结构
|
||||
|
||||
## 测试与调用链
|
||||
|
||||
- `tests/UI/Editor/unit/test_ui_editor_shortcut_manager.cpp`
|
||||
- 当前覆盖未知命令、冲突 chord、active-panel 路由、panel scope 优先于 global,以及 text-input suppression。
|
||||
- `tests/UI/Editor/integration/state/shortcut_dispatch/main.cpp`
|
||||
- 当前验证 shortcut manager 在 editor shell 状态路径上的实际行为。
|
||||
- `new_editor/src/Shell/UIEditorShellAsset.cpp`
|
||||
- 当前用 asset 中的 command registry + bindings 构建 editor 快捷键管理器。
|
||||
- `new_editor/src/Shell/UIEditorMenuModel.cpp`
|
||||
- 当前通过它读取 shortcut 文案并参与 menu item 启用态生成。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Foundation](../Foundation.md)
|
||||
- [UIEditorCommandRegistry](../UIEditorCommandRegistry/UIEditorCommandRegistry.md)
|
||||
- [UIEditorCommandDispatcher](../UIEditorCommandDispatcher/UIEditorCommandDispatcher.md)
|
||||
- [UIShortcutRegistry](../../../XCEngine/UI/Input/UIShortcutRegistry/UIShortcutRegistry.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# UIEditorShortcutManager::UnregisterBinding
|
||||
|
||||
取消注册对象、回调或映射。
|
||||
|
||||
```cpp
|
||||
bool UnregisterBinding(std::uint64_t bindingId);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `bindingId` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `bool` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::UnregisterBinding(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorShortcutManager::ValidateConfiguration
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorShortcutManagerValidationResult ValidateConfiguration() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Foundation/UIEditorShortcutManager.h`,当前页面用于固定 `UIEditorShortcutManager` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `UIEditorShortcutManagerValidationResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Foundation/UIEditorShortcutManager.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorShortcutManager object;
|
||||
// 根据上下文补齐参数后调用 UIEditorShortcutManager::ValidateConfiguration(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorShortcutManager.md)
|
||||
- [返回模块目录](../Foundation.md)
|
||||
44
docs/api/XCEditor/Foundation/UIEditorTheme/UIEditorTheme.md
Normal file
44
docs/api/XCEditor/Foundation/UIEditorTheme/UIEditorTheme.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# UIEditorTheme
|
||||
|
||||
**命名空间**: `XCEngine::UI::Editor`
|
||||
|
||||
**类型**: `theme-accessor header`
|
||||
|
||||
**头文件**: `XCEditor/Foundation/UIEditorTheme.h`
|
||||
|
||||
**描述**: `XCEditor` 默认主题解析入口,向 `Collections / Fields / Shell` 各类控件暴露统一的 metrics 与 palette 访问函数。
|
||||
|
||||
## 概览
|
||||
|
||||
`UIEditorTheme.h` 当前不是“主题对象 + 可编辑主题树”,而是一组默认值解析函数。
|
||||
|
||||
这组函数把下游控件需要的 theme 数据集中暴露出来,包括:
|
||||
|
||||
- `Fields`
|
||||
- bool / number / text / vector / enum / color / object / asset / property-grid
|
||||
- `Collections`
|
||||
- list-view / tree-view / scroll-view / tab-strip
|
||||
- `Shell`
|
||||
- menu-bar / menu-popup / status-bar / panel-frame / dock-host / viewport-slot / shell-compose / shell-interaction
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- `new_editor/src/Foundation/UIEditorTheme.cpp` 通过 `GetDefaultValue<T>()` + 一组宏生成所有 `ResolveUIEditor*` 默认访问器。
|
||||
- 每个访问器当前都返回静态默认构造值,生命周期稳定,可安全被多处重复读取。
|
||||
- 当前还没有:
|
||||
- 主题资源加载
|
||||
- runtime 主题切换
|
||||
- 层叠式 style override
|
||||
- 按 workspace / panel 定制局部 palette
|
||||
|
||||
## 当前调用链
|
||||
|
||||
- 多组 `tests/UI/Editor/integration/shell/*/main.cpp` 当前直接依赖这些默认 theme 访问器来构造演示场景。
|
||||
- `Collections`、`Fields` 和 `Shell` 的控件页当前都把这里视为默认 metrics / palette 的公共来源。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Foundation](../Foundation.md)
|
||||
- [Fields](../../Fields/Fields.md)
|
||||
- [Collections](../../Collections/Collections.md)
|
||||
- [Shell](../../Shell/Shell.md)
|
||||
74
docs/api/XCEditor/Shell/Shell.md
Normal file
74
docs/api/XCEditor/Shell/Shell.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Shell
|
||||
|
||||
**命名空间**: `XCEngine::UI::Editor`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器壳层子模块,覆盖 menu、dock、workspace、viewport slot、panel registry 以及整套 shell compose / interaction 流程。
|
||||
|
||||
## 概述
|
||||
|
||||
`Shell` 是当前新编辑器 public headers 中最靠近应用层的一层。按 `new_editor/app/Application.cpp` 当前启动链:
|
||||
|
||||
1. 先构造 `EditorShellAsset`
|
||||
2. 用 `ValidateEditorShellAsset(...)` 校验 panel / workspace / shortcut 配置
|
||||
3. 创建 `UIEditorWorkspaceController`
|
||||
4. 在每帧中调用 `UpdateUIEditorShellInteraction(...)`
|
||||
5. 再调用 `AppendUIEditorShellInteraction(...)` 输出绘制数据
|
||||
|
||||
因此这个子模块既包含纯数据模型,也包含布局与交互协议:
|
||||
|
||||
- shell 资产与配置
|
||||
- `UIEditorShellAsset.h`
|
||||
- `UIEditorPanelRegistry.h`
|
||||
- `UIEditorWorkspaceModel.h`
|
||||
- `UIEditorWorkspaceSession.h`
|
||||
- 壳层布局与交互
|
||||
- `UIEditorShellCompose.h`
|
||||
- `UIEditorShellInteraction.h`
|
||||
- `UIEditorWorkspaceCompose.h`
|
||||
- `UIEditorWorkspaceInteraction.h`
|
||||
- 具体面板宿主与框架控件
|
||||
- `UIEditorDockHost*`
|
||||
- `UIEditorMenu*`
|
||||
- `UIEditorStatusBar.h`
|
||||
- `UIEditorViewportSlot.h`
|
||||
- `UIEditorViewportShell.h`
|
||||
|
||||
## 公开头文件
|
||||
|
||||
- `UIEditorDockHost.h`
|
||||
- `UIEditorDockHostInteraction.h`
|
||||
- `UIEditorMenuBar.h`
|
||||
- `UIEditorMenuModel.h`
|
||||
- `UIEditorMenuPopup.h`
|
||||
- `UIEditorMenuSession.h`
|
||||
- `UIEditorPanelContentHost.h`
|
||||
- `UIEditorPanelFrame.h`
|
||||
- `UIEditorPanelHostLifecycle.h`
|
||||
- `UIEditorPanelRegistry.h`
|
||||
- `UIEditorShellAsset.h`
|
||||
- `UIEditorShellCompose.h`
|
||||
- `UIEditorShellInteraction.h`
|
||||
- `UIEditorStatusBar.h`
|
||||
- `UIEditorStructuredShell.h`
|
||||
- `UIEditorViewportInputBridge.h`
|
||||
- `UIEditorViewportShell.h`
|
||||
- `UIEditorViewportSlot.h`
|
||||
- `UIEditorWorkspaceCompose.h`
|
||||
- `UIEditorWorkspaceController.h`
|
||||
- `UIEditorWorkspaceInteraction.h`
|
||||
- `UIEditorWorkspaceLayoutPersistence.h`
|
||||
- `UIEditorWorkspaceModel.h`
|
||||
- `UIEditorWorkspaceSession.h`
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前这里只建立目录索引页,具体头文件页仍需后续分批补齐。
|
||||
- 这层 public API 面向新编辑器宿主;旧版 `editor/src/Viewport/**` 的 source-backed helper 不属于这里。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [XCEditor](../XCEditor.md)
|
||||
- [Foundation](../Foundation/Foundation.md)
|
||||
- [Fields](../Fields/Fields.md)
|
||||
49
docs/api/XCEditor/Shell/UIEditorDockHost/UIEditorDockHost.md
Normal file
49
docs/api/XCEditor/Shell/UIEditorDockHost/UIEditorDockHost.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# UIEditorDockHost
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**头文件**: `XCEditor/Shell/UIEditorDockHost.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Shell` 子目录中的 `UIEditorDockHost` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorDockHost.h` 是 `XCEditor/Shell` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorDockHostHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostTabStripVisualState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostTabItemLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostSplitterLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostPanelLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostTabStackLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostForegroundOptions` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 枚举值
|
||||
|
||||
| 枚举值 | 数值 | 描述 |
|
||||
|--------|------|------|
|
||||
| `None` | `0` | 枚举项。 |
|
||||
| `SplitterHandle` | - | 枚举项。 |
|
||||
| `TabStripBackground` | - | 枚举项。 |
|
||||
| `Tab` | - | 枚举项。 |
|
||||
| `TabCloseButton` | - | 枚举项。 |
|
||||
| `PanelHeader` | - | 枚举项。 |
|
||||
| `PanelBody` | - | 枚举项。 |
|
||||
| `PanelFooter` | - | 枚举项。 |
|
||||
| `PanelCloseButton` | - | 枚举项。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Shell.md) - 返回 `Shell` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,34 @@
|
||||
# UIEditorDockHostInteraction
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Shell/UIEditorDockHostInteraction.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Shell` 子目录中的 `UIEditorDockHostInteraction` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorDockHostInteraction.h` 是 `XCEditor/Shell` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorDockHostTabStripInteractionEntry` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostInteractionState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostInteractionResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorDockHostInteractionFrame` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `nodeId` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `state` | `UIEditorTabStripInteractionState` | 结构体公开字段。 | `{}` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Shell.md) - 返回 `Shell` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
39
docs/api/XCEditor/Shell/UIEditorMenuBar/UIEditorMenuBar.md
Normal file
39
docs/api/XCEditor/Shell/UIEditorMenuBar/UIEditorMenuBar.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# UIEditorMenuBar
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Shell/UIEditorMenuBar.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Shell` 子目录中的 `UIEditorMenuBar` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorMenuBar.h` 是 `XCEditor/Shell` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorMenuBarItem` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuBarState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuBarMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuBarPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuBarLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuBarHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuBarHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `menuId` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `label` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `enabled` | `bool` | 结构体公开字段。 | `true` |
|
||||
| `desiredLabelWidth` | `float` | 结构体公开字段。 | `0.0f` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Shell.md) - 返回 `Shell` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,40 @@
|
||||
# UIEditorMenuModel
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Shell/UIEditorMenuModel.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Shell` 子目录中的 `UIEditorMenuModel` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorMenuModel.h` 是 `XCEditor/Shell` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorMenuItemKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuCheckedStateSource` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuCheckedStateBinding` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuItemDescriptor` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuDescriptor` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuModel` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuModelValidationCode` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuModelValidationResult` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorResolvedMenuItem` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorResolvedMenuDescriptor` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorResolvedMenuModel` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `menus` | `std::vector<UIEditorMenuDescriptor>` | 结构体公开字段。 | `{}` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Shell.md) - 返回 `Shell` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
@@ -0,0 +1,44 @@
|
||||
# UIEditorMenuPopup
|
||||
|
||||
**命名空间**: `XCEngine`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEditor/Shell/UIEditorMenuPopup.h`
|
||||
|
||||
**描述**: 定义 `XCEditor/Shell` 子目录中的 `UIEditorMenuPopup` public API。
|
||||
|
||||
## 概述
|
||||
|
||||
`UIEditorMenuPopup.h` 是 `XCEditor/Shell` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
|
||||
## 声明概览
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `UIEditorMenuPopupItem` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuPopupState` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuPopupMetrics` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuPopupPalette` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuPopupLayout` | `struct` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuPopupHitTargetKind` | `enum class` | 头文件中的公开声明。 |
|
||||
| `UIEditorMenuPopupHitTarget` | `struct` | 头文件中的公开声明。 |
|
||||
|
||||
## 结构体成员
|
||||
|
||||
| 成员 | 类型 | 描述 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `itemId` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `kind` | `::XCEngine::UI::Editor::UIEditorMenuItemKind` | 结构体公开字段。 | `::XCEngine::UI::Editor::UIEditorMenuItemKind::Command` |
|
||||
| `label` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `shortcutText` | `std::string` | 结构体公开字段。 | `{}` |
|
||||
| `enabled` | `bool` | 结构体公开字段。 | `true` |
|
||||
| `checked` | `bool` | 结构体公开字段。 | `false` |
|
||||
| `hasSubmenu` | `bool` | 结构体公开字段。 | `false` |
|
||||
| `desiredLabelWidth` | `float` | 结构体公开字段。 | `0.0f` |
|
||||
| `desiredShortcutWidth` | `float` | 结构体公开字段。 | `0.0f` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Shell.md) - 返回 `Shell` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
31
docs/api/XCEditor/Shell/UIEditorMenuSession/CloseAll.md
Normal file
31
docs/api/XCEditor/Shell/UIEditorMenuSession/CloseAll.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# UIEditorMenuSession::CloseAll
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorMenuSessionMutationResult CloseAll( ::XCEngine::UI::Widgets::UIPopupDismissReason dismissReason = ::XCEngine::UI::Widgets::UIPopupDismissReason::Programmatic);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `dismissReason` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `UIEditorMenuSessionMutationResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::CloseAll(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorMenuSession::DismissFromEscape
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorMenuSessionMutationResult DismissFromEscape();
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `UIEditorMenuSessionMutationResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::DismissFromEscape(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# UIEditorMenuSession::DismissFromFocusLoss
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorMenuSessionMutationResult DismissFromFocusLoss( const UIInputPath& focusedPath);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `focusedPath` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `UIEditorMenuSessionMutationResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::DismissFromFocusLoss(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# UIEditorMenuSession::DismissFromPointerDown
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorMenuSessionMutationResult DismissFromPointerDown( const UIInputPath& hitPath);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `hitPath` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `UIEditorMenuSessionMutationResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::DismissFromPointerDown(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# UIEditorMenuSession::FindPopupState
|
||||
|
||||
查找并返回匹配对象。
|
||||
|
||||
```cpp
|
||||
const UIEditorMenuPopupState* FindPopupState(std::string_view popupId) const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `popupId` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `const UIEditorMenuPopupState*` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::FindPopupState(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorMenuSession::GetOpenRootMenuId
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
std::string_view GetOpenRootMenuId() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `std::string_view` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::GetOpenRootMenuId(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorMenuSession::GetOpenSubmenuItemIds
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
const std::vector<std::string>& GetOpenSubmenuItemIds() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `const std::vector<std::string>&` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::GetOpenSubmenuItemIds(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorMenuSession::GetPopupOverlayModel
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
const ::XCEngine::UI::Widgets::UIPopupOverlayModel& GetPopupOverlayModel() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `const ::XCEngine::UI::Widgets::UIPopupOverlayModel&` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::GetPopupOverlayModel(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# UIEditorMenuSession::GetPopupStates
|
||||
|
||||
获取相关状态或对象。
|
||||
|
||||
```cpp
|
||||
const std::vector<UIEditorMenuPopupState>& GetPopupStates() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `const std::vector<UIEditorMenuPopupState>&` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::GetPopupStates(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
30
docs/api/XCEditor/Shell/UIEditorMenuSession/HasOpenMenu.md
Normal file
30
docs/api/XCEditor/Shell/UIEditorMenuSession/HasOpenMenu.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# UIEditorMenuSession::HasOpenMenu
|
||||
|
||||
判断是否具备指定状态或能力。
|
||||
|
||||
```cpp
|
||||
[[nodiscard]] bool HasOpenMenu() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `[[nodiscard]] bool` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::HasOpenMenu(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
@@ -0,0 +1,32 @@
|
||||
# UIEditorMenuSession::HoverMenuBarRoot
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorMenuSessionMutationResult HoverMenuBarRoot( std::string_view menuId, ::XCEngine::UI::Widgets::UIPopupOverlayEntry entry);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `menuId` - 参数语义详见头文件声明。
|
||||
- `entry` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `UIEditorMenuSessionMutationResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::HoverMenuBarRoot(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
32
docs/api/XCEditor/Shell/UIEditorMenuSession/HoverSubmenu.md
Normal file
32
docs/api/XCEditor/Shell/UIEditorMenuSession/HoverSubmenu.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# UIEditorMenuSession::HoverSubmenu
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorMenuSessionMutationResult HoverSubmenu( std::string_view itemId, ::XCEngine::UI::Widgets::UIPopupOverlayEntry entry);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `itemId` - 参数语义详见头文件声明。
|
||||
- `entry` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `UIEditorMenuSessionMutationResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::HoverSubmenu(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
31
docs/api/XCEditor/Shell/UIEditorMenuSession/IsMenuOpen.md
Normal file
31
docs/api/XCEditor/Shell/UIEditorMenuSession/IsMenuOpen.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# UIEditorMenuSession::IsMenuOpen
|
||||
|
||||
查询当前状态。
|
||||
|
||||
```cpp
|
||||
[[nodiscard]] bool IsMenuOpen(std::string_view menuId) const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `menuId` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `[[nodiscard]] bool` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::IsMenuOpen(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
31
docs/api/XCEditor/Shell/UIEditorMenuSession/IsPopupOpen.md
Normal file
31
docs/api/XCEditor/Shell/UIEditorMenuSession/IsPopupOpen.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# UIEditorMenuSession::IsPopupOpen
|
||||
|
||||
查询当前状态。
|
||||
|
||||
```cpp
|
||||
[[nodiscard]] bool IsPopupOpen(std::string_view popupId) const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `popupId` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `[[nodiscard]] bool` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::IsPopupOpen(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
@@ -0,0 +1,32 @@
|
||||
# UIEditorMenuSession::OpenMenuBarRoot
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
```cpp
|
||||
UIEditorMenuSessionMutationResult OpenMenuBarRoot( std::string_view menuId, ::XCEngine::UI::Widgets::UIPopupOverlayEntry entry);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEditor/Shell/UIEditorMenuSession.h`,当前页面用于固定 `UIEditorMenuSession` 类目录下的方法级 canonical 路径。
|
||||
|
||||
**参数:**
|
||||
- `menuId` - 参数语义详见头文件声明。
|
||||
- `entry` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `UIEditorMenuSessionMutationResult` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
|
||||
```cpp
|
||||
#include <XCEditor/Shell/UIEditorMenuSession.h>
|
||||
|
||||
void Example() {
|
||||
XCEngine::UIEditorMenuSession object;
|
||||
// 根据上下文补齐参数后调用 UIEditorMenuSession::OpenMenuBarRoot(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](UIEditorMenuSession.md)
|
||||
- [返回模块目录](../Shell.md)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user