Viser 时序可视化接口¶
交互播放器与业务数据加载已经解耦。所有 reconstruction、physics rollout
或其他时序结果,都应先适配成
pipeline.utils.viser_timeline.TimelineScene,再交给统一的
render_timeline() / ViserTimelineViewer。
核心数据类型¶
| 类型 | 数据 | 每帧更新 | 典型用途 |
|---|---|---|---|
MeshTrack(deformable) |
vertices=(T,V,3)、faces=(F,3) |
handle.vertices |
SMPL-X、布料、软体 |
MeshTrack(rigid) |
vertices=(V,3)、faces=(F,3) |
不更新 mesh | object link、physics rigid body |
TransformTrack |
transforms=(T,4,4) |
position + quaternion | articulated links、刚体骨架 |
CameraTrack |
K、T_c2w、可选 RGB 帧 |
frustum | 输入相机或 simulator camera |
TimelineGroup |
key、显示名称 | visibility | human/object/contact 等分组 |
所有同帧的 deformable vertices、rigid transforms、颜色和透明度更新都由
播放器统一放进一次 server.atomic();adapter 不应直接操作 Viser handle。
Reconstruction adapter¶
pipeline.utils.viser_utils.build_hoi_result_timeline() 当前完成:
- SMPL-X body / left hand / right hand → 三条 deformable
MeshTrack; - target hand 逐帧颜色与透明度 →
frame_colors/frame_opacities; - articulated object link → 一条
TransformTrack加若干静态MeshTrack; - object contact region → 同一 link 下的红色静态
MeshTrack; - result camera、ground、joint qpos 文本 →
CameraTrack和 frame info。
原有 render_result() 仍然兼容,但内部已经调用标准播放器。
Physics rollout adapter¶
pipeline.physics.vis.rollout.load_physics_rollout_timeline() 直接接受
common_rollout.npz、case JSON + result.pt 和共享 humanoid XML。
其中只有 common rollout 提供逐帧状态;这和任意方法数量的 comparison 使用同一条
数据接口:
- 读取 case-specific
humanoid.xml,把其中的 box/capsule body 转成 link-local 静态MeshTrack;不再反解或显示光滑 SMPL-X skin。 human_body_state[..., :3]+human_body_state[..., 3:7]直接生成TransformTrack。各刚体 mesh 只初始化一次,播放时只更新 scene-node pose。- Humanoid 使用既有 Isaac Gym replay 的亮绿色
(0.2, 0.95, 0.2); object 继续使用统一的橙色,contact-region 继续使用红色。 object_root_state (T,13)+object_joint_qpos (T,J):通过现有 articulated FK 得到 object link 的(T,4,4),继续复用 object 静态 mesh 与 contact-region mesh。- 各方法的 state、坐标系、时间轴、joint order 已在 common contract 中统一; renderer 不读取原生 pkl,也不写第二份 human/object 动态播放文件。
- Object scale 在由 case/result 重建的共享 URDF 中一次性 bake;common rollout 不重复保存几何 scale。
- MP4 renderer 可直接传入
camera.views[].eye/look_at与horizontal_fov_deg;缺省使用共享自动 full-body/hand-object 取景,且永不回读result.pt以外的原生文件。Viser 使用自由视角。 - 水平地面从
result.world.ground_offset直接得到;桌面等静态几何只从冻结case JSON.world.static_boxes读取。CoDA nativeobj.table_pos仅用于与这个 shared table 的中心做 parity 校验,不是 renderer 输入,也不写进动态 rollout。 - Common rollout 始终保存 canonical \(T\) 和
valid_frame_count。单方法 renderer/Viser 只播放有效前缀;comparison 在某方法终止后隐藏该方法并标记 fail,不显示冻结尾帧。
最小调用形式:
from pipeline.physics.vis.rollout import render_physics_rollout
viewer = render_physics_rollout(
"output/runs/<case>/<method>/common_rollout.npz",
method="ours",
case_json_path="output/runs/<case>/runtime/case.json",
result_path="output/runs/<case>/recon/output/result.pt",
humanoid_xml="output/runs/<case>/<method>/reference/humanoid.xml",
host="0.0.0.0",
port=8921,
autoplay=True,
)
viewer.run_forever()
命令行入口为 scripts/visualization/serve_physics_rollout_viser.py,传入
--common-rollout、--case-json、--result 和 --humanoid-xml。Physics
adapter 只负责读取 common rollout、坐标/四元数约定
转换和构造 tracks;
播放控制、自由视角、材质、同步更新与性能策略全部复用通用层。
Physics 方法对比¶
scripts/visualization/serve_physics_method_comparison.py 按 manifest 的有序
methods 列表,把各方法 render state 放进同一个 TimelineScene。所有列共享一个播放
时间轴;viewer 内的 Case 下拉框会原地替换 scene,不会启动多个需要额外同步的播放器。
右侧指标直接读取统一 evaluator 的 evaluation.json。
每个 case 的 runs 必须与 methods 一致。PHC-X 是 diagnostic,可在 diagnostic
manifest 中出现,不是主 comparison 的固定必选列。每列只写该次运行的
run_record.json;viewer 从 outputs.common_rollout、静态 renderer 输入和
outputs.evaluation 读取结果,不重复填写派生路径:
{
"methods": [
{"name": "coda", "label": "CoDA"},
{"name": "intermimic", "label": "InterMimic"},
{"name": "repho", "label": "RePHO"},
{"name": "ours", "label": "Ours"}
],
"cases": [
{
"name": "b005-0113_cad10347",
"runs": {
"coda": "/abs/case/physics/coda/run_record.json",
"intermimic": "/abs/case/physics/intermimic/run_record.json",
"repho": "/abs/case/physics/repho/run_record.json",
"ours": "/abs/case/physics/ours/run_record.json"
}
}
]
}
启动命令: