docs: 其余易混淆字符改 ASCII(× − ≥ ≤ ≈ ✓ 等),消除 Gitea 告警

实测确认 Gitea 的「模棱两可 Unicode」检测覆盖:— – … § → × − ≥ ≤ ≈ ✓。
三库 .md/.txt 全部替换为 x - >= <= ~ OK;contracts 三库同源保持一致。
重新打包 v0.2.0。
This commit is contained in:
2026-09-15 21:35:10 +08:00
parent 5de0891706
commit 6913e181b5
7 changed files with 22 additions and 22 deletions
+7 -7
View File
@@ -35,7 +35,7 @@ opendance-web ←── 本仓库
| 模型检查 / 缩略图 | `models/model-inspector.ts`(面数 / 顶点 / 贴图 / **骨骼树** / humanoid 覆盖 / 可驱动性)、`models/model-thumbnail.ts`(纯 TS 光栅化 PNG,零原生依赖) |
| 模型压缩包 | 纯 TS ZIP 读取器(`common/zip-reader.ts`)+ 自动搜索包内模型 + 外部 Assimp 转换(`models/model-convert.ts`);GLB 打包 `models/gltf-packer.ts`、贴图内嵌 `models/glb-textures.ts`、GLB->VRM 封装 `models/vrm-writer.ts` |
| 默认模型种子 | `web-server/src/config/default-model.ts`(服务端/CLI 写入,运行期只读) |
| 认证 | **本版本不含认证**(内网部署);上线前须补 ≥ T-WEB-011 |
| 认证 | **本版本不含认证**(内网部署);上线前须补 >= T-WEB-011 |
## 3. 单次会话加载范围
@@ -58,9 +58,9 @@ opendance-web ←── 本仓库
| 项 | 建议值 |
|--|--|
| 单任务文件数 | ≤ 6 |
| 单任务代码行数 | ≤ 1500 |
| 单任务 Token | ≤ 12K |
| 单任务文件数 | <= 6 |
| 单任务代码行数 | <= 1500 |
| 单任务 Token | <= 12K |
| 契约引用 | 只引用锚点,不加载全文 |
## 5. 目录结构
@@ -88,7 +88,7 @@ opendance-web/
│ │ │ ├── glb-textures.ts # 把外部贴图内嵌进 GLB 的 BIN chunk
│ │ │ ├── vrm-writer.ts # GLB -> VRM 1.0(写 VRMC_vrm 扩展)
│ │ │ ├── model-inspector.ts # 面数 / 顶点 / 骨骼树 / humanoid 覆盖 / 可驱动性
│ │ │ ├── model-thumbnail.ts # 纯 TS 光栅化 512×512 PNG(含蒙皮,零原生依赖)
│ │ │ ├── model-thumbnail.ts # 纯 TS 光栅化 512x512 PNG(含蒙皮,零原生依赖)
│ │ │ ├── default-model-source.ts # 渲染 / 写入 src/config/default-model.ts
│ │ │ └── vrm-inspector.ts
│ │ ├── config/default-model.ts # 默认模型种子(由审核 / CLI 写入,运行期只读)
@@ -270,7 +270,7 @@ POST /api/models ─┬─.glb /.vrm /.gltf ─▶ importModelFile() 直接导
不做任何几何/材质损失。
- `models/model-inspector.ts`:解析 GLB/VRM,算面数 / 顶点 / 贴图 / **骨骼树** /
humanoid 覆盖 / 可驱动性(缺哪些必需骨骼)/ warnings。
- `models/model-thumbnail.ts`:纯 TS 软件光栅化 512×512 PNG(含蒙皮),零原生依赖。
- `models/model-thumbnail.ts`:纯 TS 软件光栅化 512x512 PNG(含蒙皮),零原生依赖。
- `models/default-model-source.ts`:渲染 / 写入 `src/config/default-model.ts`。
- `config/default-model.ts`:默认模型种子(审核 / CLI 写入,运行期只读)。
- **压缩包自动搜索**:优先级 `.vrm` -> `.glb` -> `.gltf` -> `.pmx` -> `.fbx`;同一优先级内
@@ -329,7 +329,7 @@ POST /api/models ─┬─.glb /.vrm /.gltf ─▶ importModelFile() 直接导
maxBoneDepth=23`,`missingRequiredBones` 为全部 16 根(日文 MMD 骨名无法映射)。
- 直接上传 `.glb`:**HTTP 201 / 0.36s**、`conversionNote=直接导入(GLB,未做重编码)`,
入库文件 sha256 与源文件**一致**。
- 缩略图:512×512 PNG / 15,043 字节,纯 TS 光栅化(含蒙皮),目视确认为居中的
- 缩略图:512x512 PNG / 15,043 字节,纯 TS 光栅化(含蒙皮),目视确认为居中的
T-pose 角色图;真实 10MB VRM(83 关节、5307 顶点)单张耗时 60-121ms(中位 79ms)。
- 管理端 3D 预览放开到 `vrm/glb/gltf`(`fbx` 仍提示"仅归档,请先转换为 GLB/VRM");
列表页显示 40px 缩略图。
+5 -5
View File
@@ -54,9 +54,9 @@ rejected 已驳回
| 字段 | 类型 | 必填 | 说明 |
|--|--|--|--|
| `id` | number | 读 | |
| `title` | string | ✅ | 曲名,≤200 |
| `artist` | string | ✅ | 演唱者,≤200 |
| `album` | string | | 专辑,≤200 |
| `title` | string | ✅ | 曲名,<=200 |
| `artist` | string | ✅ | 演唱者,<=200 |
| `album` | string | | 专辑,<=200 |
| `language` | string | | `zh` / `en` / `ja` / `ko` / `instrumental` |
| `durationMs` | number | | 时长毫秒 |
| `bpm` | number | | 节拍 |
@@ -74,7 +74,7 @@ rejected 已驳回
|--|--|--|--|
| `id` | number | 读 | |
| `songId` | number\|null | | 关联曲目 |
| `name` | string | ✅ | 动作名称,≤200 |
| `name` | string | ✅ | 动作名称,<=200 |
| `format` | enum | ✅ | `bvh` / `vmd` / `fbx` / `gltf` / `glb` / `keypoints-json` |
| `fileUrl` | string | 读 | 原始动作文件 |
| `fileSize` | number | 读 | 字节 |
@@ -95,7 +95,7 @@ rejected 已驳回
| 字段 | 类型 | 必填 | 说明 |
|--|--|--|--|
| `id` | number | 读 | |
| `name` | string | ✅ | 模型名称,≤200 |
| `name` | string | ✅ | 模型名称,<=200 |
| `format` | enum | ✅ | `glb` / `vrm`(主力)/ `gltf` / `fbx`(历史数据)。上传的 PMX/FBX 会被服务端转换成 glb 或 vrm 再入库,见 model-formats.md 1.1 |
| `vrmVersion` | string\|null | 读 | `0.x` / `1.0`,非 VRM 为 null |
| `isPrimary` | boolean | | 全局默认模型;**同一时刻全库至多一个 `true`** |
+2 -2
View File
@@ -126,7 +126,7 @@ VRM 版本识别:读取 GLB 的 JSON chunk,检查 `extensions.VRM`(0.x)
VMD 是二进制格式:文件头 `Vocaloid Motion Data 0002`(30 字节)+ 模型名(20 字节,
Shift-JIS)+ 骨骼关键帧数组(每条 **111 字节**:15 字节骨骼名、uint32 帧号、
float32×3 位移、float32×4 旋转四元数、64 字节贝塞尔插值参数)+ morph / 相机 /
float32x3 位移、float32x4 旋转四元数、64 字节贝塞尔插值参数)+ morph / 相机 /
灯光 / 自阴影 / IK / 可见性段落。**VMD 不含骨骼长度**,只有旋转(少数骨骼带位移),
因此服务端必须自带一套标准 MMD 骨架才能做 FK。
@@ -161,7 +161,7 @@ FK 旋转)。两份示例文件分别命中两种路径。
**标准骨架数值来源**:解析参考模型的 PMX 骨骼段实测得到(而非凭经验估计),
再去掉模型自身原点偏移并抹平左右不对称。关键比例:足首 1.43 / ひざ 6.57 /
髋 11.50 / センター 10.88 / 首 16.21 / 頭 17.16(总高约 19.4,髋高比约 59%);
大腿 4.94 + 小腿 5.15 ≈ 腿长 10.07。
大腿 4.94 + 小腿 5.15 ~ 腿长 10.07。
## 3. 上传限制
+1 -1
View File
@@ -121,5 +121,5 @@ spine = angle(neck, pelvis, midpoint(left_ankle, right_ankle))
`angle(a, b, c)` = 向量 `ba` 与 `bc` 的夹角余弦,即
`dot(normalize(a-b), normalize(c-b))`,落在 `[-1, 1]`。
**DTW 序列结构(冻结)**:每帧 = `[33 × (x, y, z), 9 个关节角余弦] = 108 维`。
**DTW 序列结构(冻结)**:每帧 = `[33 x (x, y, z), 9 个关节角余弦] = 108 维`。
低置信度点(`visibility < 0.5`)在插值阶段由相邻帧线性补全,不参与代价计算。
+1 -1
View File
@@ -27,7 +27,7 @@ ws://<windows-host>:8765/pose
bit2 = 上半身模式(仅 0..22 有效)
bit3-7 保留,必须为 0
4 4 frame_id u32 LE 单调递增,从 0 开始
8 231 keypoints 33 × 7B 见下
8 231 keypoints 33 x 7B 见下
--
合计 239
```
+4 -4
View File
@@ -89,7 +89,7 @@ web-server/scripts/import-default-model.mjs
| 项 | 实现 | 说明 |
|--|--|--|
| 分析 | `model-inspector.ts` -> `models.stats` | 面数 / 顶点 / 网格 / 材质 / 贴图 / 节点 / 形变目标 / 动画 / 蒙皮骨骼数 / **骨骼树** / humanoid 覆盖 / **可驱动性(缺哪些必需骨骼)** / warnings;迁移 `AddModelStats1789460000000` 新增 `models.stats TEXT` |
| 缩略图 | `model-thumbnail.ts` -> `models.thumbnail_asset_id` | 纯 TS 软件光栅化 512×512 PNG(读 GLB/glTF -> 节点层级与蒙皮 -> 包围盒构图 -> 透视投影 -> z-buffer 平面着色 -> 手写 PNG),**零原生依赖**;失败或非 glTF 容器留空,前端退化为格式占位图 |
| 缩略图 | `model-thumbnail.ts` -> `models.thumbnail_asset_id` | 纯 TS 软件光栅化 512x512 PNG(读 GLB/glTF -> 节点层级与蒙皮 -> 包围盒构图 -> 透视投影 -> z-buffer 平面着色 -> 手写 PNG),**零原生依赖**;失败或非 glTF 容器留空,前端退化为格式占位图 |
## 状态与默认模型(硬性)
@@ -129,7 +129,7 @@ web-server/scripts/import-default-model.mjs
`missingRequiredBones` 为**全部 16 根**(日文 MMD 骨名无法映射到 humanoid)。
- 直接上传 `.glb` -> **HTTP 201 / 0.36s**、`conversionNote=直接导入(GLB,未做重编码)`,
入库文件 sha256 与源文件**一致**(不重编码)。
- 缩略图:512×512 PNG / 15,043 字节,服务端纯 TS 光栅化(含蒙皮),目视确认为居中的
- 缩略图:512x512 PNG / 15,043 字节,服务端纯 TS 光栅化(含蒙皮),目视确认为居中的
T-pose 角色图;真实 10MB VRM(83 关节、5307 顶点)单张耗时 60-121ms(中位 79ms)。
- 审核:`POST /api/reviews/model/22/approve` 带 `setPrimary:true` -> 200,
模型 `status=published`、`isPrimary=true`,源码种子写入 `sourceSha256=72eb6882...`;
@@ -172,7 +172,7 @@ npm run test:smoke # 冒烟 [4] 段落
| GLB 失败回退 glTF->GLB 打包 | ✅ GLB 直出失败时 `gltf-packer.ts` 自行打包;每步 `assimp info` 回读校验 |
| `MODEL_CONVERT_FORMAT=vrm` 封装 | ✅ `vrm-writer.ts` 补 `VRMC_vrm`;humanoid 不全回退 GLB |
| 自动分析写入 `models.stats` | ✅ 实测 `triangles=9071 bones=238 humanoidMapped=0/22 drivable=false` |
| 缩略图生成且不影响入库 | ✅ 512×512 / 15,043 B;失败只告警 |
| 缩略图生成且不影响入库 | ✅ 512x512 / 15,043 B;失败只告警 |
| 上传一律 pending、不自动设默认 | ✅ `create()` 固定 `PublishStatus.Pending` + `isPrimary=false` |
| `setPrimary` 审核通过时生效 | ✅ `POST /api/reviews/model/22/approve` + `setPrimary:true` -> 200、`isPrimary=true` |
| 非 published 设默认 | ✅ `POST /api/models/:id/primary` -> 409 |
@@ -199,7 +199,7 @@ node scripts/reanalyze-models.mjs --url http://127.0.0.1:3000 --dry-run # 只列
```
实测(真实 21MB VRM,290 骨骼):回填出面数 53552 / 顶点 44662 / 骨骼 290 /
humanoid 7/22,并重建 512×512 缩略图。
humanoid 7/22,并重建 512x512 缩略图。
文件在存储中丢失时返回 **409** 并说明原因,不会用全 0 结果覆盖既有分析数据。
另外 `StorageService.persistBuffer` 在 sha256 去重命中但文件不存在时会**自愈补写**,
避免换过 `STORAGE_DIR` 或只恢复数据库后出现"静默全 0 分析"。
+2 -2
View File
@@ -43,7 +43,7 @@ web-server/src/preprocess/*
- 33 点顺序与父节点表来自 `contracts/skeleton-topology.md`,虚拟关节
`neck=33`、`pelvis=34` 只参与关节角计算,**不进入输出序列**。
- 投影:`x_img = 0.5 + x·s`,`y_img = 0.5 − y·s`,`z_img = −z·s`,
- 投影:`x_img = 0.5 + x s`,`y_img = 0.5 - y s`,`z_img = -z s`,
`s = 0.35 / max(|x|,|y|,|z|)`(按整段动作自适应,保证不出画)。
- 置信度分层:直接映射 **1.0**、按层级推算 **0.5**、无法推算 **0.0**。
@@ -84,7 +84,7 @@ npm run test # 85 例(含 31 例 VMD):解析 / FK / 重定向 /
npm run test:smoke # 冒烟 [3] 段落
```
覆盖:60 帧样例经预处理后 **60 帧 × 33 点 × 9 关节角**、坐标落在
覆盖:60 帧样例经预处理后 **60 帧 x 33 点 x 9 关节角**、坐标落在
MediaPipe 归一化范围、置信度分层、时间戳按帧率推进、序列随时间变化、
NDJSON 往返、解码器拒绝错误长度与 magic。