VFP Reader、缓存与可信边界
这页回答一个容易被混淆的问题:“文件能被打开/预览”究竟说明了什么? 快速预览适合让用户尽快看见作品;但当产品需要编辑、发布、去重、签名或把资产当成可信源时,必须知道预览缓存、容器完整性和权威体素数据是三个不同层次。
先记住三句话
VoxelViewer能看到模型,说明预览链路可用;不等于完整VOX0已被验证。VfpPackageReader.validate()成功,说明 Header/Footer/DIR0 和每个存储态区段 CRC 完整;不等于 source hash 已重算。- 只有恢复权威
PAL0 + VOX0 + gridSize、验证 source hash 并按业务规则检查后,才能称为“权威数据已验证”。当前 HarmonyOS HAR 未公开这条完整语义验证 API。
权威数据模型
VFP 1.3 的权威来源是 PAL0 + VOX0 + gridSize。它们共同定义线性体素缓冲和 source hash。以下内容全部是可删除、可重建的派生缓存或预览:
MSH0 / VBUF / PMSH / RND0 / ANM0 / PRVW / THMB
这意味着:
- 有
PRVW不代表模型体素正确;它仅表示存在一个可提取 GLB 预览。 - 有
THMB不代表模型可预览或体素正确;它只是一张可提取的文件列表 PNG。 - 有
PMSH不代表其和VOX0一致;它只是加快首帧的候选缓存。 - 缓存缺失不代表模型坏了;合格查看器/编辑器可以由
VOX0重建。 - 当前 HAR 的
VfpPackageReader.validate()只验证存储态区段 CRC,不恢复 VOX0,也不重算 source hash。
为什么缓存要和源数据分开看
PMSH 或 PRVW 的目的,是让预览器少做计算、更快出首帧;它们可以在源数据不变的前提下被删掉、重建或替换。反过来,VOX0 才是未来编辑器可以恢复每个体素的来源。
因此,一个只有缓存问题的文件可能仍可由完整工具从 VOX0 修复;一个只是 PRVW 看起来正确的文件,也可能不能被安全编辑。这是“缓存命中”不能作为用户作品真实性或可发布性的依据的原因。
当前 HAR 的 VFP 预览策略
| 输入 | 预览行为 | 可信结论 |
|---|---|---|
| JSON | 解析源文本,TaskPool 生成体素表面。 | 输入 JSON 的结构被检查;没有 VFP source hash。 |
| VFP 1.2 | 进入现有 VFP 恢复/预览路径。 | 仅能说明当前预览过程成功。 |
| VFP 1.3 URI | 选择性读取 Header/Footer/DIR0/META/PAL0/PMSH 等预览所需数据。 | 不读取完整 VOX0,因此不应宣传为权威验证。 |
VfpPackageReader.validate() | 校验目录和所有已存储区段 CRC。 | 容器存储完整性通过,不等于 source hash 验证。 |
容器校验、语义校验与业务信任的对照
| 检查层 | 当前可用 API/流程 | 能发现 | 不能发现 |
|---|---|---|---|
| 文件可读 | parse() / parseUri() | Header/Footer/DIR0、版本、目录范围、目录 CRC、目录条目约束 | 所有 payload 是否没有损坏;VOX0 内容是否正确 |
| 存储完整性 | validate() / validateUri() | 每个已存储 payload 的 CRC 损坏 | RLE 解码错误、PAL0/VOX0 语义、source hash 是否对应 |
| 预览可用 | VoxelViewer.load*() | 当前预览缓存/JSON 能否形成可见场景 | 编辑源是否恢复完整、资产是否可发布 |
| 权威语义 | 独立完整 Reader/Compiler | PAL0/VOX0、RLE、gridSize、source hash、可选缓存绑定 | 业务授权、版权、内容安全、签名等产品事实 |
| 业务信任 | 你的服务端/编辑器规则 | 用户权限、资产归属、审核、签名、版本策略 | 不应由格式 Reader 替代 |
不要把上一层的成功文案升级为下一层的承诺。例如 UI 可以写“VFP 容器校验通过”,但不应写“模型内容真实有效”。
推荐资产状态机
selected:已选择↓previewable:Viewer 可预览 / container_valid:容器 CRC 有效↓authoritatively_verified:外部完整 Reader 或 Compiler 验证 VOX0
| 状态 | 可以做什么 | 不可以做什么 |
|---|---|---|
selected | 保存 URI、展示文件名和体积。 | 显示“已验证”。 |
previewable | 用户只读查看。 | 将缓存命中当作内容真实性。 |
container_valid | 显示 META、目录和提取 PRVW / THMB。 | 进入正式编辑/发布流。 |
authoritatively_verified | 编辑、导出、发布、去重。 | 当前 HAR 单独无法给出该状态。 |
rejected | 显示错误并请求重新导出/上传。 | 用 PMSH/PRVW/THMB 继续替代权威内容。 |
推荐的产品文案
| 实际状态 | 建议说法 | 避免说法 |
|---|---|---|
parse() 成功 | “已读取 VFP 文件信息” | “文件已验证” |
validate() 成功 | “文件完整性检查通过” | “体素内容已验证” |
| Viewer 载入成功 | “预览已就绪” | “可编辑/可发布” |
| 完整工具完成 source hash 检查 | “权威体素数据已验证” | “绝对安全” |
服务或编辑器接入建议
当产品需要编辑或资产发布时,使用独立的完整 VFP 工具链完成:
读取 VFP → 目录/CRC 检查 → 读取 PAL0 与全部 VOX0 → RLE 解码
→ 重算 source hash → 验证缓存绑定(可选) → 复制进编辑文档
→ 修改 → Writer/Compiler 生成新 VFP → 再验证新文件
不要把当前 HAR 的私有 Vfp13Reader 或预览面计划提升为业务验证 API;这些实现只为 ArkGraphics 首帧优化,可能随性能优化改变。
给 HarmonyOS 宿主的分流建议
- 纯查看页:可以直接使用
loadUri();失败时显示导入失败,成功后显示预览。 - 文件详情页:先
reader.parseUri()或readUri()+parse()展示版本、generation、区段,再由用户点击预览。 - 离线完整性提示:用
readUri()+validate(),并显示“存储完整性检查通过”。 - 编辑/发布入口:将文件交给具备 VOX0/PAL0 恢复、RLE 解码和 source hash 验证的完整格式工具;当前 HAR 不应被包装成这种能力。
VFP 坐标与缓存
- 源坐标固定为 Z-up,范围
0..gridSize-1。 - 线性 offset 为
((z * gridSize) + y) * gridSize + x。 - VFP 1.3 互操作
gridSize为1..255;当前 HarmonyOS 预览 JSON 和编辑能力仍限制 128。 - 预览器在内部适配 ArkGraphics Y-up;不得为“修正画面”改写源 JSON 或 VFP 坐标。
VFP ABI、Footer 代际、目录项、codec、CRC 与 Source Hash 算法见 VFP 技术标准。
发现缓存问题时如何处理
| 现象 | 查看页能做什么 | 完整工具应做什么 |
|---|---|---|
PRVW 缺失或不是 GLB 2.0 | 隐藏“提取预览”功能;不要影响整体 VFP 信息读取 | 由 VOX0 重建预览缓存(如产品需要) |
THMB 缺失、损坏或不支持 | 显示默认封面或不显示封面;不要影响整体 VFP 信息读取/模型预览 | 如产品需要缩略图,由 Writer/资产服务重新生成并写入;不能从缩略图恢复体素 |
| PMSH 不匹配/预览失败 | 提示预览不可用;不要私自替换权威数据 | 验证源数据后重建派生缓存 |
| 单一区段 CRC 失败 | validate() 拒绝,避免提取它 | 根据 VOX0/可靠源重新导出文件 |
| source hash 不匹配 | 当前 HAR 不宣称判断结果 | 拒绝作为权威编辑源,或重新编译整个包 |
缓存修复、Writer 写回和重新编译会改变文件内容与业务版本,必须由具备写权限的独立工具/服务完成。