Files
opendance-web/tasks/006-keypoint-preprocess.md
T

68 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# T-WEB-006 BVH/FBX → 关键点序列预处理
- **状态**:done
- **依赖**:T-WEB-004
## 目标
把上传的 3D 动作数据转换为与 Android 端输出**同构**的 MediaPipe 33 点关键点序列,
使 Windows 端 DTW 引擎只有一条输入通路。
## load
```
DSH.md
contracts/model-formats.md # 锚点:§2 动作格式、§2.1 预处理产物、§2.2 关节名映射
contracts/skeleton-topology.md # 锚点:§1 33 点、§3 父节点表、§5 关节角
web-server/src/preprocess/*
```
## 端点
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | `/api/motions/:id/preprocess` | 执行预处理,返回更新后的 Motion |
| GET | `/api/motions/:id/keypoints` | 下载 NDJSON 关键点序列 |
## 实现分层
| 文件 | 职责 |
|---|---|
| `bvh-parser.ts` | 纯 TS BVH 词法/语法解析 + 逐帧前向运动学(FK) |
| `math3d.ts` | 向量/矩阵工具、旋转合成、关节角余弦 |
| `joint-map.ts` | BVH 关节名 → MediaPipe 点索引的默认映射表 |
| `retarget.ts` | 单帧解算 35 项(33 点 + neck/pelvis 虚拟关节)→ 骨盆归零 → 自适应缩放 → 投影 |
| `keypoint-codec.ts` | 239 字节二进制帧编解码、NDJSON 序列化/解析、关键点 JSON 校验 |
| `assimp.ts` | 可选外部 Assimp 调用(FBX/glTF → BVH) |
| `preprocess.service.ts` | 编排、落盘、状态与错误记录 |
## 拓扑与缩放(契约冻结)
- 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`,
`s = 0.35 / max(|x|,|y|,|z|)`(按整段动作自适应,保证不出画)。
- 置信度分层:直接映射 **1.0**、按层级推算 **0.5**、无法推算 **0.0**。
## 格式支持
| 格式 | 处理 |
|---|---|
| `.bvh` | 内置解析器,无外部依赖 |
| `.json` | 直通校验与规范化(须符合 `mediapipe33@0.1.0`) |
| `.fbx` `.gltf` `.glb` | 调用可选 Assimp 转 BVH;未安装 Assimp 时写入可读错误并置 `preprocessState=failed` |
## 验收
```bash
npm run test # 25 例:解析 / FK / 重定向 / 编解码 / 拓扑 / 契约版本
npm run test:smoke # 冒烟 [3] 段落
```
覆盖:60 帧样例经预处理后 **60 帧 × 33 点 × 9 关节角**、坐标落在
MediaPipe 归一化范围、置信度分层、时间戳按帧率推进、序列随时间变化、
NDJSON 往返、解码器拒绝错误长度与 magic。
样例数据由 `test/fixtures/generate-sample-bvh.mjs` 生成(60 帧挥手 + 深蹲,
21 关节 / 63 通道),可复现。