Spaces:
Paused
Paused
| import numpy as np | |
| from scipy.spatial.transform import Rotation as R | |
| from vid2rig.rig_io import to_glb | |
| from vid2rig.retarget.bonemap import canonical, validate_target | |
| from vid2rig.retarget.rig import TargetRig | |
| from vid2rig.retarget.config import RetargetCfg | |
| from vid2rig.retarget.retarget import retarget | |
| from vid2rig.motion import MotionClip | |
| def test_canonical_collapses_separators(): | |
| assert canonical("mixamorig:Hips") == "mixamorigHips" | |
| assert canonical("mixamorig_Hips") == "mixamorigHips" | |
| assert canonical("mixamorigHips") == "mixamorigHips" | |
| def test_validate_target_separator_insensitive(): | |
| m = {"pelvis": "mixamorigHips"} | |
| assert validate_target(m, {"mixamorig:Hips"}) == [] # colon variant counts as present | |
| def test_to_glb_passthrough(tmp_path): | |
| p = tmp_path / "x.glb"; p.write_bytes(b"glTF") | |
| assert to_glb(str(p)) == str(p) | |
| def test_retarget_matches_colon_bone_names(): | |
| names = ["mixamorig:Hips", "mixamorig:Spine"]; parents = [-1, 0] | |
| offsets = np.array([[0, 0, 0], [0, 1, 0.0]]) | |
| rng = np.random.default_rng(1); F = 3 | |
| rots = np.stack([[R.from_rotvec(rng.normal(0, 0.3, 3)).as_quat() for _ in range(2)] for _ in range(F)]) | |
| clip = MotionClip(fps=30, num_frames=F, source="smpl", joint_names=["pelvis", "spine1"], | |
| local_rotations=rots, root_translation=np.zeros((F, 3)), root_rotation=rots[:, 0], | |
| rest_offsets=offsets, parents=parents, source_height_m=1.7) | |
| rig = TargetRig(node_index={n: i for i, n in enumerate(names)}, bone_names=names, parents=parents, | |
| bind_local_rot=np.tile([0, 0, 0, 1.0], (2, 1)), bind_local_trans=offsets, | |
| root_node_world_rot=np.array([0, 0, 0, 1.0]), height_m=1.7) | |
| anim = retarget(clip, rig, {"pelvis": "mixamorigHips", "spine1": "mixamorigSpine"}, RetargetCfg()) | |
| # rotations keyed by the RAW node name (so the baker finds the node), identity invariant holds | |
| assert "mixamorig:Spine" in anim.rotations | |
| for f in range(F): | |
| assert np.allclose(np.abs(anim.rotations["mixamorig:Spine"][f]), np.abs(rots[f, 1]), atol=1e-6) | |