feat(scene): 场景选择与物理落地 + 整包发布(T-WIN-012/013/014)

T-WIN-013:API 升级与场景选择
- 契约快照同步到 rest-api 0.5.0 / data-models 0.7.0 / database 0.4.0
- catalog_types.gd 新增 SceneConfig(物理/环境/出生点/相机)与 Scene;
  CatalogBundle 增加 scenes[];from_dict 按契约 7.1 再收敛一次
  (缺项默认、越界夹紧、非法枚举回退),与服务端 normalizeSceneConfig 同规则
- 新增 src/scene/scene_runtime.gd:GLB 载入 -> 碰撞体(mesh 三角网 /
  auto 命名约定 *_col、*_colonly / none 不兜底)-> 场景级重力(Area3D
  SPACE_OVERRIDE_REPLACE,不改全局 ProjectSettings)-> 风(每物理帧
  apply_central_force,阵风正弦叠加,支持 local 坐标系)-> 环境光与雾
  -> 出生点与相机(follow/fixed/orbit);无碰撞体时兜底地面
- CatalogStore 增加 scenes/default_scene/find_scene/ensure_scene_cached/
  fetch_thumbnail(场景缓存带 sha256 指纹,避免换包后仍用旧 GLB)
- 主界面改为 2x2 四个选择器(曲目/动作/模型/场景)+ 场景参数面板
  (缩略图 + 重力/摩擦/弹性/碰撞体/风摘要)
- 游戏界面载入场景并落地物理,角色落在出生点;场景缺失/下载失败/
  解析失败一律回退内置空场景并提示,不阻塞开始跟练

T-WIN-012:「关于」清单展示当前版本号
- 版本唯一来源为 project.godot 的 application/config/version(v0.2.0)
- about_manifest() 输出版本/引擎/契约/协议/地址/隐私清单;
  无头测试无 autoload,读取 AppConfig 走 get_node_or_null 容错
- Credits 的单个 CONTRACT_VERSION 常量改为 CONTRACT_VERSIONS 字典
  (六项契约各自独立递增),并双向核对 contracts/VERSION

T-WIN-014:发布必须是单个完整包
- build/package-release.sh 重写:只产出单个 zip + SHA256SUMS,
  清理历史 .partN,超限时告警而非回退分卷;新增源产物与解压后完整性
  自检(PE 头 MZ / pck 魔数 GDPC / exe+pck 同目录同名)与体积-上限对比
- deploy/proxy 相关的 Gitea IIS 256MB 上限说明见 opendance-web

测试:tests/test_scene_config.gd(12 例)+ tests/test_about.gd(4 例);
无头测试 687 通过 / 0 失败(10 个套件),verify.sh 全部通过
This commit is contained in:
2026-09-17 00:45:23 +08:00
parent 47e11af7d0
commit 5581cbe05d
27 changed files with 2031 additions and 85 deletions
+52 -18
View File
@@ -1,5 +1,5 @@
================================================================
OpenDance Studio -- Windows 客户端 v0.1.0 使用说明
OpenDance Studio -- Windows 客户端 v0.2.0 使用说明
================================================================
摄像头跳舞评分系统的核心体验端:接收 Android 辅助 App 通过 WebSocket
@@ -16,8 +16,9 @@ OpenDance Studio -- Windows 客户端 v0.1.0 使用说明
OpenDance.exe 主程序
OpenDance.pck 资源包(必须与 exe 同目录)
README.txt 本文件
README.md 同内容 Markdown 版
THIRD_PARTY.md 开源声明
contracts/ 契约快照
contracts/ 契约快照(只读;客户端不直连数据库)
2. 先启动 Web 管理服务端(opendance-web),确保能访问其 API。
@@ -26,13 +27,15 @@ OpenDance Studio -- Windows 客户端 v0.1.0 使用说明
4. 在主界面确认「服务端地址」(默认 http://127.0.0.1:3000),
点击「保存并测试」;顶部应显示「服务端正常 | DB...」。
5. 点击「刷新目录」,左侧会出现已发布的曲目、动作与模型。
5. 点击「刷新目录」,左侧会出现已发布的曲目、动作、模型与场景。
6. 在 Android 手机上启动「OpenDance 辅助 App」,填入本机显示在
主界面上的接收地址(形如 ws://<本机局域网地址>:8765/pose)并连接。
连接成功后主界面会提示「已连接 N 台设备」。
7. 依次选择曲目 -> 动作 -> 模型,点击「开始跟练」。
7. 依次选择曲目 -> 动作 -> 模型 -> 场景,点击「开始跟练」。
场景可以留空不选:服务端没有可用场景时会自动回退到内置空场景,
界面会提示但不影响开始跟练。
--
二、初次部署(从零跑起来)
@@ -98,19 +101,29 @@ OpenDance.exe 的用户看第一节即可。
+ OpenDance.pck(约 107 KB,必须与 exe 同目录);可能附带
OpenDance.console.exe。
打成发布包(可选):
打成发布包:
bash build/package-release.sh 0.1.0
bash build/package-release.sh 0.2.0
得到 dist-release/opendance-windows-v0.1.0.zip,内含 OpenDance.exe、
OpenDance.pck、THIRD_PARTY.md、README.txt、contracts/。
得到 dist-release/ 下两个资产:
opendance-windows-v0.2.0.zip <- 单个完整包,禁止 .partN 分卷
SHA256SUMS <- 裸文件名,可直接 sha256sum -c
包里含 OpenDance.exe、OpenDance.pck、THIRD_PARTY.md、README.txt、
README.md、contracts/。打包脚本会解压自检(exe + pck 必须同目录、
exe 的 PE 头为 MZ、pck 魔数为 GDPC)并打印包体与上传上限的对比。
注意:本项目 Gitea 前置 IIS 的默认上传上限是 30,000,000 字节
(约 28.6 MiB),超过会返回 HTTP 413。这时不要改成分卷,
请让运维放宽上限(做法见 opendance-web/deploy/proxy/README.md)。
7. 自检清单
1) 一键验证:GODOT_BIN=/path/to/godot bash build/verify.sh
预期末行「验证全部通过」。
2) 无头测试:$GODOT --headless --path . --script res://tests/run_tests.gd
预期「== 结果:580 通过 / 0 失败 ==」与「全部通过」(缺 VRM 素材或
预期「== 结果:687 通过 / 0 失败 ==」与「全部通过」(缺 VRM 素材或
服务端不可达时相关用例跳过,数字会减少)。
3) 启动冒烟:$GODOT --headless --path . --quit-after 180
预期无 SCRIPT ERROR / ERROR:,退出码 0。
@@ -142,22 +155,33 @@ OpenDance.exe 的用户看第一节即可。
--
主界面
- 三栏选择:曲目 / 动作(仅列出已完成预处理的动作)/ 模型(VRM 优先)
- 四个选择器(2x2 栅格):曲目 / 动作(仅列出已完成预处理的动作)/
模型(VRM 优先)/ 场景(GLB + 物理参数)
- 服务端地址:可修改并即时测试
- 接收地址:Android 端要连接的 WebSocket 地址
- 「刷新目录」重新拉取已发布资源
- 底部展示所选动作的**来源信息**(来源类型、名称、作者、许可、链接)
- 「刷新目录」重新拉取已发布资源(含场景)
- 底部左侧展示所选动作的来源信息(来源类型、名称、作者、许可、链接)
- 底部中间展示所选场景的缩略图与物理参数摘要
(重力 / 摩擦 / 弹性 / 碰撞体来源 / 风);未选场景时说明将使用内置空场景
游戏界面
- 左侧 3D 视图:VRM 角色跟随关键点实时动作,相机自动框住模型
- 右侧 HUD:实时得分、等级、连击、动作进度、连接状态、来源信息
- 左侧 3D 视图:VRM 角色落在场景出生点并跟随关键点实时动作,
相机按场景配置取景(follow 跟随 / fixed 固定 / orbit 环绕)
- 场景物理在本端落地:重力(Area3D 覆盖,不改全局 ProjectSettings)、
风(每物理帧施加风力,阵风按正弦叠加)、地面摩擦与弹性、
GLB 碰撞体(mesh 三角网 / auto 命名约定 *_col、*_colonly)、环境光与雾
- 右侧 HUD:实时得分、等级、连击、动作进度、连接状态、来源信息、场景参数
结算界面
- 等级(S/A/B/C/D)、平均分与最终分、动作完成度、最高单帧、最长连击
- 「再来一次」/「返回主菜单」/「开源声明」
关于页面
- 版本与契约版本、隐私说明、完整可滚动的第三方开源项目声明
- 「清单」逐行显示:客户端版本(vX.Y.Z)/ 运行引擎 / 契约版本 /
接收协议 / 接收地址 / 服务端地址 / 隐私说明
- 版本号唯一来源是 project.godot 的 application/config/version,与
project.yaml、导出产物名、Git tag、界面展示完全一致
- 完整可滚动的第三方开源项目声明
--
四、配置文件
@@ -230,15 +254,16 @@ OpenDance.exe 的用户看第一节即可。
export_presets.cfg 导出预设(必须在项目根目录)
project.yaml 任务清单与状态
DSH.md 本项目 DSH 执行约束
tasks/ 单任务说明书(T-WIN-001 ~ 011)
contracts/ 只读契约快照(来源 opendance-web v0.1.0)
tasks/ 单任务说明书(T-WIN-001 ~ 014)
contracts/ 只读契约快照(来源 opendance-web;六项契约各自独立版本)
scenes/main.tscn 根节点
src/autoload/ AppConfig / CatalogStore / PoseReceiver / ScoreService
src/net/ 239 字节编解码、WebSocket 服务、REST 客户端
src/model/ VRM 加载、humanoid 骨骼映射
src/anim/ 关键点 -> 骨骼重定向
src/scene/ 场景实例化与物理落地(重力/风/碰撞/环境/机位)
src/score/ 特征提取、DTW、评分规则
src/ui/ 主界面 / 游戏界面 / 结算 / 关于 / 来源展示
src/ui/ 主界面 / 游戏界面 / 结算 / 关于 / 来源展示 / 场景参数
tests/ 无头测试框架与用例
build/ 导出脚本
@@ -260,6 +285,15 @@ A: 游戏界面会显示「人形覆盖率」。低于 60% 说明模型的骨骼
Q: 连上了手机但分数一直是 0
A: 确认手机端已开始推流;主界面的「查看接收状态」会显示累计帧数与丢帧数。
Q: 选场景时提示「场景缺少 GLB 文件」或「已回退内置空场景」
A: 服务端该场景没有可下载的 GLB(转换失败或未发布)。这不影响开始跟练,
会使用内置空场景与默认物理参数;请让管理员在管理端「场景管理」重新上传。
Q: 场景里的角色一直往下掉
A: 场景没有可用碰撞体且配置为 colliders=auto/mesh。本端会自动生成兜底地面
(日志会记录「已生成兜底地面」);若场景显式配置 colliders=none,则按场景
作者意图不生成任何碰撞体,此时角色不会被地面接住。
Q: 关于页面的开源声明
A: 与 THIRD_PARTY.md、contracts/open-source-credits.md 三处保持一致。