feat(models): 发布 v0.2.0 —— GLB/VRM 主力格式、自动缩略图与分析、模型审核与骨骼预览
需求 1:系统确定以 GLB / VRM 为模型主力格式
- 服务端新增支持库:
- model-inspector.ts:解析 GLB/VRM 的面数、顶点、材质、贴图、形变目标、
**骨骼树(名称/层级/是否蒙皮/humanoid 映射/子节点数)**、humanoid 覆盖率与可驱动性
- model-thumbnail.ts:**纯 TS 软件光栅化**(z-buffer + Lambert + 完整蒙皮矩阵)
生成 512×512 PNG 缩略图,零原生依赖、不装 headless-gl
- vrm-writer.ts:GLB → VRM 1.0(写入 VRMC_vrm 扩展与 humanoid 映射)
- gltf-packer.ts:glTF(.gltf + .bin + 贴图)→ 单文件 GLB
- humanoid 候选表与 Godot 客户端 humanoid_map.gd **逐字对齐**,并有单测断言两边一致
(服务端判定的"可驱动" = 客户端实际能否驱动)
需求 2:模型管理
- .glb / .vrm / .gltf **直接导入**(不重编码,GLB 含 VRM 扩展会自动识别为 VRM)
- .pmx / .fbx 服务端转换:assimp → .glb →(失败)→ .gltf 后自行打包成 GLB
→(MODEL_CONVERT_FORMAT=vrm 时)补 VRMC_vrm 产出 VRM 1.0;每步 assimp info 回读校验
- .zip **自动搜索包内可用模型**:.vrm → .glb → .gltf(直接导入)优先,
其次 .pmx → .fbx(转换);同优先级内按"指名字 → 目录最浅 → 文件最大"
- 入库后自动分析(models.stats)与生成缩略图(models.thumbnail_asset_id),
失败均不阻断入库;管理端列表显示小缩略图、预览放开到 vrm/glb/gltf
需求 3:审核功能
- 上传的模型状态**一律 pending**(不再自动发布、不再自动设默认)
- 审核界面新增模型面板:体积、面数、顶点、材质、贴图、骨骼、形变目标等指标,
humanoid 覆盖进度、可驱动性结论(缺哪些必需骨骼)、warnings,以及
**骨骼详细预览**(层级缩进、蒙皮/Humanoid 徽章、子节点数、搜索保留祖先链、
仅看蒙皮、限高滚动 + 只渲染前 400 行)
- 审核通过可带 setPrimary=true 一并设为默认模型(此时才写源码种子);
POST /api/models/:id/primary 仅允许 published(否则 409)
- scripts/import-default-model.mjs 改为"上传 → 审核通过 + 设默认"流程
其它:
- models 新增 stats 列(迁移 AddModelStats1789460000000,已在真实库执行)
- 契约升至 rest-api/data-models/model-formats 0.4.0、database 0.3.0(另两库已同步)
- 版本号 0.1.0 → 0.2.0(package.json ×2 + lockfile + project.yaml)
- 文档:README.txt / DSH.md / project.yaml / tasks 005·007·010 全面更新;
顶层开发书更新为 v1.4
验证:168 项单测通过(10 文件);契约 6 项与 29 条路由一致;typecheck/build 通过;
真实端到端:MMD 压缩包 → GLB + 分析(面数 9071/骨骼 238/humanoid 0-22) + 缩略图(15KB PNG);
GLB 直接导入 sha256 与源文件一致;审核通过后 defaultModelId 由 VRM 变为该模型
This commit is contained in:
+22
-3
@@ -178,8 +178,19 @@ install.sh 检测到缺 deploy/.env
|
||||
`ReadWritePaths=/var/lib/opendance`,进程只能写自己的存储目录
|
||||
- **上传上限两侧一致**:后端 `UPLOAD_MAX_BYTES=536870912`(512 MiB),
|
||||
反代侧 `client_max_body_size` / `maxAllowedContentLength` 必须不小于此值
|
||||
- **模型转换配置**(`deploy/.env.example` 已写入):
|
||||
- `ASSIMP_BIN=assimp`:上传 `.zip` 模型包或 `.pmx`/`.fbx` 单文件时**必须**能调用到,
|
||||
否则转换失败 **422**
|
||||
- `MODEL_CONVERT_FORMAT=glb`(默认)|`vrm`:只影响需要转换的 PMX/FBX 的交付格式。
|
||||
`glb` 通用,两个客户端都原生加载;`vrm` 在 GLB 之上补 `VRMC_vrm` 扩展
|
||||
(humanoid 骨骼 / 表情语义),**humanoid 骨骼名映射不全时自动回退交付 GLB**
|
||||
并写进 `models.conversion_note`。产物一律 `assimp info` 回读校验
|
||||
- `MODEL_CONVERT_PMX` / `MODEL_CONVERT_TIMEOUT_MS` 语义见 README §四
|
||||
- **迁移用编译产物**:`web-server/scripts/migrate.mjs` 检测到 `dist/` 时走
|
||||
`typeorm -d dist/db/data-source.js`,无需在服务器上装 devDependencies
|
||||
`typeorm -d dist/db/data-source.js`,无需在服务器上装 devDependencies;
|
||||
本版本迁移共 3 个:`InitSchema1789382903060`、
|
||||
`AddModelConversionFields1789450000000`、**`AddModelStats1789460000000`**
|
||||
(新增 `models.stats TEXT`,存模型分析结果,已在真实库执行)
|
||||
- **依赖安装显式带 dev**:安装脚本先 `set -a; . deploy/.env` 导出了
|
||||
`NODE_ENV=production`,会让 npm 跳过 devDependencies 导致 `tsc: not found`;
|
||||
故用 `env -u NODE_ENV npm ci --include=dev`
|
||||
@@ -202,7 +213,8 @@ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3001/ # 期望 200
|
||||
|---|---|
|
||||
| `deploy/install.sh` 脚本语法与幂等性 | ✅ `bash -n` 通过;重复执行会覆盖程序文件、保留 `.env` |
|
||||
| 连接现有 MySQL 成功 | ✅ 已用真实实例验证(`/health` 200,`database.connected=true`) |
|
||||
| TypeORM migration 执行成功 | ✅ 5 张业务表已创建并验证 |
|
||||
| TypeORM migration 执行成功 | ✅ 5 张业务表已创建并验证;v0.2.0 的 `AddModelStats1789460000000`(`models.stats TEXT`)已在真实库执行 |
|
||||
| 模型转换配置 | ✅ `deploy/.env.example` 写入 `ASSIMP_BIN` / `MODEL_CONVERT_FORMAT=glb|vrm` / `MODEL_CONVERT_PMX` / `MODEL_CONVERT_TIMEOUT_MS`;不合规输入转换失败 422 |
|
||||
| `curl http://<host>:3000/health` 通过 | ✅ 直连后端端口已验证 |
|
||||
| 软件 API 端口 `/` 返回 404 | ✅ `PORT=3000` 上 `/`、`/songs` 均 404(有意设计,无管理页面) |
|
||||
| 管理端端口 `/` 返回 200 | ✅ `ADMIN_PORT=3001` 上 `/`、`/songs`、`/models` 均返回同一份 HTML(200) |
|
||||
@@ -236,7 +248,7 @@ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3001/ # 期望 200
|
||||
|
||||
```bash
|
||||
./scripts/package-release.sh
|
||||
# → dist-release/opendance-web-v0.1.0.tar.gz
|
||||
# → dist-release/opendance-web-v0.2.0.tar.gz
|
||||
```
|
||||
|
||||
内容:`web-server/`(源码 + dist)、`admin/`(构建产物)、`deploy/`
|
||||
@@ -244,3 +256,10 @@ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3001/ # 期望 200
|
||||
打包脚本会对产物做硬校验:`src/**/*.ts` 必须都有对应 `dist/*.js`,
|
||||
关键文件(`dist/main.js`、`dist/storage/storage.module.js`、`admin/index.html`、
|
||||
`deploy/proxy/*`)必须齐全,且不得含真实 `.env` 与 Docker/nginx 安装配置。
|
||||
v0.2.0 起校验清单追加模型新模块:`dist/models/model-inspector.js`、
|
||||
`dist/models/model-thumbnail.js`、`dist/models/vrm-writer.js`、
|
||||
`dist/models/gltf-packer.js`、`dist/migrations/1789460000000-AddModelStats.js`。
|
||||
|
||||
> **发布包名变更**:`opendance-web-v0.1.0.tar.gz` → **`opendance-web-v0.2.0.tar.gz`**
|
||||
> (`scripts/package-release.sh` 的 `VERSION` 默认值已改为 `0.2.0`,
|
||||
> 与 `project.yaml` 的 `version: 0.2.0`、`web-server/package.json` 一致)。
|
||||
|
||||
Reference in New Issue
Block a user