Articraft 无损资产适配 — Y-up 修复

洗衣机"半截入土"根因定位 + 修复 + 与官方 HSSD 无损 parity 验证 · 2026-06-17 · e区

一句话:我们 Articraft 网格是 Z-up,而 SceneBenchmark 资产 payload 约定 glTF 标准 Y-up。 Blender 导入时的 Y-up→Z-up 自动转换把我们的 Z-up 内容额外转倒 90° → 物体躺倒、几何中心落到地面、 底面沉入地下 0.30m("半截入土")。修复 = 在适配器源头施加逆旋转 Rx(-90°)(Z-up→Y-up), 之后与官方 HSSD 资产逐项同构、无损导入

修复前 / 修复后(同一相机,demo 双洗衣机场景)

before
BEFORE · Z-up洗衣机躺倒成一块扁板、机身沉入地面(底在 z=−0.30)。 从该机位只见一块平板 = 躺倒症状。
after
AFTER · Y-up两台洗衣机直立坐地(底在 z=0、高 0.85), 前装滚筒的圆门正确朝前露出。
before hires
BEFORE(高清)原始发布 bundle 渲染:两台机身偏低,开启的门退化成一块水平薄板, 而非正确的立面圆门 —— 朝向被转倒的连带表现。

无损 parity 验证(三方同走 Blender glTF 导入)

资产Blender 导入后 ext (x,y,z)高轴底面 zmin判定
官方 HSSD wardrobe(金标准)[1.21, 0.58, 2.00]Z 站立−0.00 坐地✓ 正确
我们 Articraft 原始 Z-up[0.64, 0.85, 0.60]Y 躺倒−0.30 下沉✗ 入土
我们 Articraft 修正 Y-up[0.64, 0.60, 0.85]Z 站立−0.00 坐地✓ 与官方同构

修正后高轴=Z、底 z≈0,与官方 HSSD 逐项一致 → 经 finalize_imported_authored_object 路径无损落位。

根因链(真实代码路径锤实,非推测)

修复(已固化为可复用适配器)

适配器 converter/datasets/articraft_yup_adapter.py,源头施加 Rx(-90°)(官方 bake 的逆)把 Z-up 内容转成标准 Y-up + 底贴原点:

from datasets.articraft_yup_adapter import normalize_articraft_mesh_to_yup, local_bounds_zup
normalize_articraft_mesh_to_yup("in_zup.glb", "out_yup.glb")  # Z-up -> 标准 Y-up + 底贴原点
lb = local_bounds_zup("out_yup.glb")                          # 统一场景(Z-up)系 local_bounds

已集成进 yz-week25 分支(基于同学 week/25 主线)并推送 origin/yz: 含 schema 扩展(articulation/clearance 可选字段)+ 关节/净空标注两种挂载模式。 回归全绿:week25 test_asset_annotation_rendering 13 passed、test_demo_scene_regressions 10 passed。