Example #1
0
def parse_amc(file_path, joints, skel):
    with open(file_path) as f:
        content = f.read().splitlines()

    for idx, line in enumerate(content):
        if line == ":DEGREES":
            content = content[idx + 1:]
            break

    motion = motion_class.Motion(skel=skel)
    frames = []
    idx = 0
    line, idx = read_line(content, idx)
    assert line[0].isnumeric(), line
    EOF = False
    frame = 0
    translation_data = []
    while not EOF:
        # joint_degree = {}
        while True:
            line, idx = read_line(content, idx)
            if line is None:
                EOF = True
                break
            if line[0].isnumeric():
                break
            line_idx = 1
            if "root" in line[0]:
                degree = np.array([float(line[i]) for i in range(4, 7)])
                joints[line[0]].coordinate = np.array(
                    [float(line[i]) for i in range(1, 4)])
            else:
                degree = []
                for lm in joints[line[0]].limits:
                    if lm[0] != lm[1]:
                        degree.append(float(line[line_idx]))
                        line_idx += 1
                    else:
                        degree.append(0)
            joints[line[0]].degree = np.deg2rad(np.array(degree).squeeze())
        pose_data = []
        set_rotation(joints["root"])
        for key in joints.keys():
            if joints[key].matrix is None:
                pose_data.append(constants.eye_T())
            else:
                pose_data.append(
                    conversions.Rp2T(
                        joints[key].matrix.squeeze(),
                        joints[key].coordinate.squeeze(),
                    ))

        fps = 60
        motion.add_one_frame(frame / fps, pose_data)
        frame += 1
    return motion
Example #2
0
def create_motion_from_amass_data(filename, bm, override_betas=None):
    bdata = np.load(filename)

    if override_betas is not None:
        betas = torch.Tensor(override_betas[:10][np.newaxis]).to("cpu")
    else:
        betas = torch.Tensor(bdata["betas"][:10][np.newaxis]).to("cpu")

    skel = create_skeleton_from_amass_bodymodel(
        bm,
        betas,
        len(joint_names),
        joint_names,
    )

    fps = float(bdata["mocap_framerate"])
    root_orient = bdata["poses"][:, :3]  # controls the global root orientation
    pose_body = bdata["poses"][:, 3:66]  # controls body joint angles
    trans = bdata["trans"][:, :3]  # controls the finger articulation

    motion = motion_class.Motion(skel=skel, fps=fps)

    num_joints = skel.num_joints()
    parents = bm.kintree_table[0].long()[:num_joints]

    for frame in range(pose_body.shape[0]):
        pose_body_frame = pose_body[frame]
        root_orient_frame = root_orient[frame]
        root_trans_frame = trans[frame]
        pose_data = []
        for j in range(num_joints):
            if j == 0:
                T = conversions.Rp2T(conversions.A2R(root_orient_frame),
                                     root_trans_frame)
            else:
                T = conversions.R2T(
                    conversions.A2R(pose_body_frame[(j - 1) * 3:(j - 1) * 3 +
                                                    3]))
            pose_data.append(T)
        motion.add_one_frame(pose_data)

    return motion
Example #3
0
def load(
    file,
    motion=None,
    scale=1.0,
    load_skel=True,
    load_motion=True,
    v_up_skel=np.array([0.0, 1.0, 0.0]),
    v_face_skel=np.array([0.0, 0.0, 1.0]),
    v_up_env=np.array([0.0, 1.0, 0.0]),
):
    if not motion:
        motion = motion_class.Motion(fps=60)

    if load_skel:
        skel = motion_class.Skeleton(
            v_up=v_up_skel, v_face=v_face_skel, v_up_env=v_up_env,
        )
        smpl_offsets = np.zeros([24, 3])
        smpl_offsets[0] = OFFSETS[0]
        for idx, pid in enumerate(SMPL_PARENTS[1:]):
            smpl_offsets[idx + 1] = OFFSETS[idx + 1] - OFFSETS[pid]
        for joint_name, parent_joint, offset in zip(
            SMPL_JOINTS, SMPL_PARENTS, smpl_offsets
        ):
            joint = motion_class.Joint(name=joint_name)
            if parent_joint == -1:
                parent_joint_name = None
                joint.info["dof"] = 6  # root joint is free
                offset -= offset
            else:
                parent_joint_name = SMPL_JOINTS[parent_joint]
            offset = offset / np.linalg.norm(smpl_offsets[4])
            T1 = conversions.p2T(scale * offset)
            joint.xform_from_parent_joint = T1
            skel.add_joint(joint, parent_joint_name)
        motion.skel = skel
    else:
        assert motion.skel is not None

    if load_motion:
        assert motion.skel is not None
        # Assume 60fps
        motion.fps = 60.0
        dt = float(1 / motion.fps)
        with open(file, "rb") as f:
            data = pkl.load(f, encoding="latin1")
            poses = np.array(data["poses"])  # shape (seq_length, 135)
            assert len(poses) > 0, "file is empty"
            poses = poses.reshape((-1, len(SMPL_MAJOR_JOINTS), 3, 3))

            for pose_id, pose in enumerate(poses):
                pose_data = [
                    constants.eye_T() for _ in range(len(SMPL_JOINTS))
                ]
                major_joint_id = 0
                for joint_id, joint_name in enumerate(SMPL_JOINTS):
                    if joint_id in SMPL_MAJOR_JOINTS:
                        pose_data[
                            motion.skel.get_index_joint(joint_name)
                        ] = conversions.R2T(pose[major_joint_id])
                        major_joint_id += 1
                motion.add_one_frame(pose_id * dt, pose_data)

    return motion
Example #4
0
def load(
        file,
        motion=None,
        scale=1.0,
        load_skel=True,
        load_motion=True,
        v_up_skel=np.array([0.0, 1.0, 0.0]),
        v_face_skel=np.array([0.0, 0.0, 1.0]),
        v_up_env=np.array([0.0, 1.0, 0.0]),
):
    if not motion:
        motion = motion_classes.Motion()
    words = None
    with open(file, "rb") as f:
        words = [word.decode() for line in f for word in line.split()]
        f.close()
    assert words is not None and len(words) > 0
    cnt = 0
    total_depth = 0
    joint_stack = [None, None]
    joint_list = []
    parent_joint_list = []

    if load_skel:
        assert motion.skel is None
        motion.skel = motion_classes.Skeleton(
            v_up=v_up_skel,
            v_face=v_face_skel,
            v_up_env=v_up_env,
        )

    if load_skel:
        while cnt < len(words):
            # joint_prev = joint_stack[-2]
            joint_cur = joint_stack[-1]
            word = words[cnt].lower()
            if word == "root" or word == "joint":
                parent_joint_list.append(joint_cur)
                name = words[cnt + 1]
                joint = motion_classes.Joint(name=name)
                joint_stack.append(joint)
                joint_list.append(joint)
                cnt += 2
            elif word == "offset":
                x, y, z = (
                    float(words[cnt + 1]),
                    float(words[cnt + 2]),
                    float(words[cnt + 3]),
                )
                T1 = conversions.p2T(scale * np.array([x, y, z]))
                joint_cur.xform_from_parent_joint = T1
                cnt += 4
            elif word == "channels":
                ndofs = int(words[cnt + 1])
                if ndofs == 6:
                    joint_cur.info["type"] = "free"
                elif ndofs == 3:
                    joint_cur.info["type"] = "ball"
                elif ndofs == 1:
                    joint_cur.info["type"] = "revolute"
                else:
                    raise Exception("Undefined")
                joint_cur.info["dof"] = ndofs
                joint_cur.info["bvh_channels"] = []
                for i in range(ndofs):
                    joint_cur.info["bvh_channels"].append(words[cnt + 2 +
                                                                i].lower())
                cnt += ndofs + 2
            elif word == "end":
                joint_dummy = motion_classes.Joint(name="END")
                joint_stack.append(joint_dummy)
                cnt += 2
            elif word == "{":
                total_depth += 1
                cnt += 1
            elif word == "}":
                joint_stack.pop()
                total_depth -= 1
                cnt += 1
                if total_depth == 0:
                    for i in range(len(joint_list)):
                        motion.skel.add_joint(
                            joint_list[i],
                            parent_joint_list[i],
                        )
                    break
            elif word == "hierarchy":
                cnt += 1
            else:
                raise Exception(f"Unknown Token {word} at token {cnt}")

    if load_motion:
        assert motion.skel is not None
        assert np.allclose(motion.skel.v_up, v_up_skel)
        assert np.allclose(motion.skel.v_face, v_face_skel)
        assert np.allclose(motion.skel.v_up_env, v_up_env)
        while cnt < len(words):
            word = words[cnt].lower()
            if word == "motion":
                num_frames = int(words[cnt + 2])
                dt = float(words[cnt + 5])
                motion.set_fps(round(1 / dt))
                cnt += 6
                t = 0.0
                range_num_dofs = range(motion.skel.num_dofs)
                positions = np.zeros(
                    (num_frames, motion.skel.num_joints(), 3, 3))
                rotations = np.zeros((num_frames, motion.skel.num_joints(), 3))
                T = np.zeros((num_frames, motion.skel.num_joints(), 4, 4))
                T[...] = constants.eye_T()
                position_channels = {
                    "xposition": 0,
                    "yposition": 1,
                    "zposition": 2,
                }
                rotation_channels = {
                    "xrotation": 0,
                    "yrotation": 1,
                    "zrotation": 2,
                }
                for frame_idx in range(num_frames):
                    # if frame_idx == 1:
                    #     break
                    raw_values = [
                        float(words[cnt + j]) for j in range_num_dofs
                    ]
                    cnt += motion.skel.num_dofs
                    cnt_channel = 0
                    for joint_idx, joint in enumerate(motion.skel.joints):
                        for channel in joint.info["bvh_channels"]:
                            value = raw_values[cnt_channel]
                            if channel in position_channels:
                                value = scale * value
                                positions[frame_idx][joint_idx][
                                    position_channels[channel]][
                                        position_channels[channel]] = value
                            elif channel in rotation_channels:
                                value = conversions.deg2rad(value)
                                rotations[frame_idx][joint_idx][
                                    rotation_channels[channel]] = value
                            else:
                                raise Exception("Unknown Channel")
                            cnt_channel += 1

                for joint_idx, joint in enumerate(motion.skel.joints):
                    for channel in joint.info["bvh_channels"]:
                        if channel in position_channels:
                            T[:,
                              joint_idx] = T[:, joint_idx] @ conversions.p2T(
                                  positions[:, joint_idx,
                                            position_channels[channel], :, ])
                        elif channel == "xrotation":
                            T[:,
                              joint_idx] = T[:, joint_idx] @ conversions.R2T(
                                  conversions.Ax2R(
                                      rotations[:, joint_idx,
                                                rotation_channels[channel], ]))
                        elif channel == "yrotation":
                            T[:,
                              joint_idx] = T[:, joint_idx] @ conversions.R2T(
                                  conversions.Ay2R(
                                      rotations[:, joint_idx,
                                                rotation_channels[channel], ]))
                        elif channel == "zrotation":
                            T[:,
                              joint_idx] = T[:, joint_idx] @ conversions.R2T(
                                  conversions.Az2R(
                                      rotations[:, joint_idx,
                                                rotation_channels[channel], ]))

                for i in range(num_frames):
                    motion.add_one_frame(list(T[i]))
                    t += dt
            else:
                cnt += 1
        assert motion.num_frames() > 0
    return motion