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
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
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
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