def __init__(self, scene_object, name, data, color=(0, 0, 1)): LegacySkeletonAnimationController.__init__(self, scene_object) self.motion_primitive = MotionStateGraphNode(None) self.skeleton = SkeletonBuilder().load_from_json_data(data["skeleton"]) self.frameTime = self.skeleton.frame_time self._visualizations = [] self.samples = [] self.algorithm_config = DEFAULT_ALGORITHM_CONFIG self.color = color self.motion_primitive._initialize_from_json(convert_to_mgrd_skeleton(self.skeleton), data) print("loaded motion primitive") print("spatial", self.motion_primitive.get_n_spatial_components()) print("time", self.motion_primitive.get_n_time_components()) self.motion_primitive.cluster_tree = None self.training_data = None #print("n gmm", len(self.motion_primitive.get_gaussian_mixture_model().weights)) self.name = name self._regenerate = True self.type = CONTROLLER_TYPE_MP set_log_mode(LOG_MODE_DEBUG) self.start_pose = {"position": [0, 0, 0], "orientation": [0, 0, 0]} self.mock_graph = MockGraph(self.skeleton) self.label_color_map = dict()
def load_motion(path, skeleton_type=None): bvh = BVHReader(path) mv = MotionVector() mv.from_bvh_reader(bvh) skeleton = SkeletonBuilder().load_from_bvh(bvh) skeleton.skeleton_model = load_skeleton_model(skeleton_type) return skeleton, mv
def load_skeleton_from_db(db_url, skeleton_name, session=None): skeleton_data = get_skeleton_from_remote_db(db_url, skeleton_name, session) if skeleton_data is not None: skeleton = SkeletonBuilder().load_from_custom_unity_format(skeleton_data) skeleton_model = get_skeleton_model_from_remote_db(db_url, skeleton_name, session) skeleton.skeleton_model = skeleton_model return skeleton
def load_asf_file(builder, filename): scene_object = SceneObject() scene_object.scene = builder._scene asf_data = parse_asf_file(filename) skeleton = SkeletonBuilder().load_from_asf_data(asf_data) color = get_random_color() builder.create_component("skeleton_vis", scene_object, skeleton, color) motion_vector = MotionVector() motion_vector.frames = [skeleton.get_reduced_reference_frame()] motion_vector.n_frames = 1 scene_object = SceneObject() vis = builder.create_component("skeleton_vis", scene_object, skeleton, color=get_random_color()) animation_controller = SkeletonAnimationController(scene_object) animation_controller.name = filename.split("/")[-1] animation_controller.set_motion(motion_vector) animation_controller.frameTime = 1 animation_controller.set_visualization(vis) scene_object.name = animation_controller.name scene_object.add_component("animation_controller", animation_controller) builder._scene.addAnimationController(scene_object, "animation_controller") return scene_object
def load_skeleton_from_json(builder, file_path, scale=1.0): data = load_json_file(file_path) if "skeleton" in data: data = data["skeleton"] #skeleton = SkeletonBuilder().load_from_custom_unity_format(data) skeleton = SkeletonBuilder().load_from_json_data(data) skeleton.scale(scale) motion_vector = MotionVector() motion_vector.frames = [skeleton.get_reduced_reference_frame()] motion_vector.n_frames = 1 scene_object = SceneObject() vis = builder.create_component("skeleton_vis", scene_object, skeleton, color=get_random_color()) animation_controller = SkeletonAnimationController(scene_object) animation_controller.name = file_path.split("/")[-1] animation_controller.set_motion(motion_vector) animation_controller.frameTime = 1 animation_controller.set_visualization(vis) scene_object.name = animation_controller.name scene_object.add_component("animation_controller", animation_controller) print("load mg json from", file_path) if scene_object is not None: builder._scene.addAnimationController(scene_object, "animation_controller") return scene_object
def load_motion_from_json(builder, skeleton_data, motion_data, name, collection_id, motion_id, meta_data_str="", skeleton_model=None, is_processed=False, draw_mode=2, visualize=True, color=None, visible=True): if color is None: color = get_random_color() skeleton = SkeletonBuilder().load_from_custom_unity_format(skeleton_data) skeleton.skeleton_model = skeleton_model motion_vector = MotionVector() motion_vector.from_custom_db_format(motion_data) motion_vector.skeleton = skeleton skeleton.frame_time = motion_vector.frame_time #motion_vector.scale_root(scale) o = builder.create_object("animation_controller", name, skeleton, motion_vector, motion_vector.frame_time, draw_mode, visualize, color) o.visible = visible if "data_base_ids" not in builder._scene.internal_vars: builder._scene.internal_vars["data_base_ids"] = dict() builder._scene.internal_vars["data_base_ids"][o.node_id] = (collection_id, motion_id, is_processed) if meta_data_str != "": c = o._components["animation_controller"] meta_data = json.loads(meta_data_str) if "sections" in meta_data: sections = meta_data["sections"] print("sections", sections) sections = meta_data["sections"] if type(sections) == list: semantic_annotation = create_annotation_from_sections_list( sections, motion_vector.n_frames) else: semantic_annotation = create_annotation_from_sections_dict( sections, motion_vector.n_frames) color_map = dict() for key in semantic_annotation.keys(): color_map[key] = get_random_color() c.set_color_annotation(semantic_annotation, color_map) if "time_function" in meta_data: print("set time_function") time_function = meta_data["time_function"] print(meta_data["time_function"]) c.set_time_function(time_function) else: print("meta_data", meta_data) return o
def load_skeleton(file_path, joint_filter=None, scale=1.0): target_bvh = BVHReader(file_path) bvh_joints = list(target_bvh.get_animated_joints()) if joint_filter is not None: animated_joints = [j for j in bvh_joints if j in joint_filter] else: print("set default joints") animated_joints = bvh_joints skeleton = SkeletonBuilder().load_from_bvh(target_bvh, animated_joints) skeleton.scale(scale) return skeleton
def slot_load_asf_str(self): filename = QFileDialog.getOpenFileName(self, 'Open File', '.')[0] filename = str(filename) if os.path.isfile(filename): try: asf_data = parse_asf_file(filename) skeleton = SkeletonBuilder().load_from_asf_data(asf_data) self.data = skeleton.to_unity_format() print("loaded asf string from", filename) except Exception as e: self.data = None print("Could not read file", e.args, filename)
def main(): global context, pool port = 8888 target_skeleton_file = MODEL_DATA_DIR + os.sep + "iclone_female4.bvh" skeleton_model = "iclone" target_skeleton_file = None parser = argparse.ArgumentParser( description="Start the MorphableGraphs REST-interface") parser.add_argument( "-set", nargs='+', default=[], help="JSONPath expression, e.g. -set $.model_data=path/to/data") parser.add_argument("-config_file", nargs='?', default=SERVICE_CONFIG_FILE, help="Path to default config file") parser.add_argument("-target_skeleton", nargs='?', default=target_skeleton_file, help="Path to target skeleton file") parser.add_argument("-skeleton_scale", nargs='?', default=1.0, help="Scale applied to the target skeleton offsets") args = parser.parse_args() if os.path.isfile(args.config_file): service_config = load_json_file(args.config_file) algorithm_config_file = "config" + os.sep + service_config[ "algorithm_settings"] + "_algorithm.config" algorithm_config = load_json_file(algorithm_config_file) port = service_config["port"] if args.target_skeleton is not None: # TODO use custom json file instead bvh_reader = BVHReader(args.target_skeleton) animated_joints = list(bvh_reader.get_animated_joints()) target_skeleton = SkeletonBuilder().load_from_bvh( bvh_reader, animated_joints=animated_joints) target_skeleton.skeleton_model = SKELETON_MODELS[skeleton_model] else: target_skeleton = None context = Context(service_config, algorithm_config, target_skeleton) count = cpu_count() print("run {} processes on port {}".format(count, port)) pool = ProcessPoolExecutor(max_workers=count) # configure tornado to work with the asynchio loop tornado.platform.asyncio.AsyncIOMainLoop().install() app.listen(port) asyncio.get_event_loop().run_forever() pool.shutdown()
def slot_load_bvh_str(self): filename = QFileDialog.getOpenFileName(self, 'Open File', '.')[0] filename = str(filename) if os.path.isfile(filename): try: bvh = BVHReader(filename) skeleton = SkeletonBuilder().load_from_bvh( bvh, list(bvh.get_animated_joints())) self.data = skeleton.to_unity_format() print("loaded bvh string from", filename) except Exception as e: self.data = None print("Could not read file", e.args, filename)
def __init__(self, bvhreader): self.skeleton = SkeletonBuilder().load_from_bvh(bvhreader) self.bvhreader = bvhreader self.quat_frames = [] self.euler_frames = bvhreader.frames self.n_frames = len(self.euler_frames) self.body_plane = None
def __init__(self, elementary_action, motion_primitive, data_repo, functional_motion_data, npc, skeleton_json, knots, n_joints): """ :param functional_motion_data (numpy.array<3d> n_samples * n_coeffs * n_dims): each dimension of motion data is represented as a function, the dimension of motion data is: first three channels are Hips' translation, four channels for the orientation of each joint :return: """ self.functional_motion_data = functional_motion_data self.motion_primitive = motion_primitive self.elementary_action = elementary_action self.cartesian_motion_data = convert_quat_functional_data_to_cartesian_functional_data(elementary_action, motion_primitive, data_repo, skeleton_json, functional_motion_data, knots) self.npc = npc self.knots = knots skeleton_bvh = os.path.join(os.path.dirname(__file__), r'../../../skeleton.bvh') bvhreader = BVHReader(skeleton_bvh) self.skeleton = SkeletonBuilder().load_from_bvh(bvhreader) self.skeleton_json = skeleton_json self.data_repo = data_repo self.n_joints = n_joints self.len_weights = self.n_joints + LEN_CARTESIAN self.pca = PCA(n_components=self.npc)
def get_distgrid(self, ref_motion, test_motion): skeleton = SkeletonBuilder().load_from_bvh(self.ref_bvhreader) n_ref_frames = len(ref_motion['frames']) n_test_frames = len(test_motion['frames']) distgrid = np.zeros([n_test_frames, n_ref_frames]) for i in range(n_test_frames): for j in range(n_ref_frames): distgrid[i, j] = calculate_frame_distance( skeleton, ref_motion['frames'][j], test_motion['frames'][i]) if self.verbose: res = MotionDynamicTimeWarping.calculate_path(distgrid) ref_indices = res[0] test_indices = res[1] shape = (n_test_frames, n_ref_frames) path = self.get_warping_index(test_indices, ref_indices, shape) distgrid = distgrid.T plt.figure() plt.imshow(distgrid) plt.plot(list(range(len(path))), path, color='red') plt.ylabel(ref_motion['filename']) plt.ylim(0, n_ref_frames) plt.xlim(0, n_test_frames) plt.xlabel(test_motion['filename']) plt.title('similarity grid with path') plt.show() return distgrid
def load_bvh_file(builder, path, scale=1.0, draw_mode=2, offset=None, reference_frame=None, skeleton_model=None, use_clip=False, color=None, visualize=True): bvh_reader = BVHReader(path) bvh_reader.scale(scale) animated_joints = [ key for key in list(bvh_reader.node_names.keys()) if not key.endswith("EndSite") ] o = None if bvh_reader.frames is not None: skeleton = SkeletonBuilder().load_from_bvh( bvh_reader, animated_joints, reference_frame=reference_frame, skeleton_model=skeleton_model) motion_vector = MotionVector() motion_vector.from_bvh_reader(bvh_reader, False) motion_vector.skeleton = skeleton if offset is not None: motion_vector.translate_root(offset) name = path.split("/")[-1] o = builder.create_object("animation_controller", name, skeleton, motion_vector, bvh_reader.frame_time, draw_mode, visualize, color) return o
def load_motion_from_bvh(filename): bvh_reader = BVHReader(filename) motion_vector = MotionVector() motion_vector.from_bvh_reader(bvh_reader, False) animated_joints = list(bvh_reader.get_animated_joints()) motion_vector.skeleton = SkeletonBuilder().load_from_bvh( bvh_reader, animated_joints=animated_joints) return motion_vector
def load_file(self, filename): bvh_reader = BVHReader(str(self.folder_path) + os.sep + filename) mv = MotionVector() mv.from_bvh_reader(bvh_reader, False) animated_joints = list(bvh_reader.get_animated_joints()) mv.skeleton = SkeletonBuilder().load_from_bvh( bvh_reader, animated_joints=animated_joints) self.motion_cache[filename] = mv
def create_animated_mesh(builder, name, model_data, scale=1, visualize=True): scene_object = SceneObject() scene_object.name = name skeleton_data = model_data["skeleton"] skeleton = SkeletonBuilder().load_from_fbx_data(skeleton_data) skeleton.skeleton_model = dict() skeleton.scale(scale) vis = None if visualize: vis = builder.create_component("skeleton_vis", scene_object, skeleton, color=(0, 1, 0), width_scale=0.1) #vis.box_scale = 0.1 animation_controller = SkeletonAnimationController(scene_object) anim_key = None if "animations" in model_data and len(model_data["animations"]) > 0: for k in model_data["animations"]: if len(model_data["animations"][k]["curves"].keys()) > 0: anim_key = k break anim = model_data["animations"][anim_key]["curves"] clip = create_clip_from_animation(skeleton, anim) clip.scale_root(scale) if anim_key is None: clip = create_clip_from_reference_frame(skeleton) clip.scale_root(scale) animation_controller.name = scene_object.name animation_controller.set_motion(clip) animation_controller.set_visualization(vis, 1) animation_controller.frameTime = skeleton.frame_time scene_object.name = animation_controller.name scene_object.add_component("animation_controller", animation_controller) if visualize: if len(model_data["mesh_list"]) > 0 and len( model_data["mesh_list"][0]["vertices"]) > 0: builder.create_component("animated_mesh", scene_object, model_data, "animation_controller", scale) return scene_object
def create_motion_vector_from_bvh(bvh_str, animated_joints=None): bvh_reader = get_bvh_from_str(bvh_str) print("loaded motion", bvh_reader.frames.shape) if animated_joints is None: animated_joints = [key for key in list(bvh_reader.node_names.keys()) if not key.endswith("EndSite")] skeleton = SkeletonBuilder().load_from_bvh(bvh_reader, animated_joints) motion_vector = MotionVector() motion_vector.from_bvh_reader(bvh_reader, False, animated_joints) motion_vector.skeleton = skeleton return motion_vector
def load_data_for_normalization(self, data_folder): if not data_folder.endswith(os.sep): data_folder += os.sep bvh_files = glob.glob(data_folder + '*.bvh') self.ref_bvh = bvh_files[0] self.ref_bvhreader = BVHReader(self.ref_bvh) self.skeleton = SkeletonBuilder().load_from_bvh(self.ref_bvhreader) for bvh_file_path in bvh_files: bvhreader = BVHReader(bvh_file_path) filename = os.path.split(bvh_file_path)[-1] self.aligned_motions[filename] = bvhreader.frames
def create_animation_controller_from_fbx(builder, name, skeleton_data): skeleton = SkeletonBuilder().load_from_fbx_data(skeleton_data) scene_object = SceneObject() vis = builder.create_component("skeleton_vis", scene_object, skeleton, color=(0, 1, 0)) animation_controller = SkeletonAnimationController(scene_object) animation_controller.name = name animation_controller.currentFrameNumber = 0 animation_controller.frameTime = 0.011333 clip = create_clip_from_reference_frame(skeleton) animation_controller.set_motion(clip) skeleton.reference_frame = clip.frames[0] animation_controller.set_visualization(vis, 2) scene_object.name = animation_controller.name scene_object.add_component("animation_controller", animation_controller) return scene_object
def load_target_skeleton(file_path, scale_factor=1.0): skeleton = None target_bvh = BVHReader(file_path) animated_joints = list(target_bvh.get_animated_joints()) skeleton = SkeletonBuilder().load_from_bvh(target_bvh, animated_joints, add_tool_joints=False) for node in list(skeleton.nodes.values()): node.offset[0] *= scale_factor node.offset[1] *= scale_factor node.offset[2] *= scale_factor return skeleton
def load_custom_unity_format_file(builder, filename, draw_mode=2): data = load_json_file(filename) if data is not None: frame_time = data["frameTime"] motion_vector = MotionVector() motion_vector.from_custom_unity_format(data) skeleton = SkeletonBuilder().load_from_json_data(data) o = builder.create_object("animation_controller", filename.split("/")[-1], skeleton, motion_vector, motion_vector.frame_time, draw_mode, visualize, color) return o
def create_cluster_tree_from_model(model_data, n_samples, n_subdivisions_per_level = 4, session=None): skeleton = SkeletonBuilder().load_from_json_data(model_data["skeleton"]) CLUSTERING_METHOD_KMEANS = 0 mp = MotionPrimitiveModelWrapper() mp.cluster_tree = None mp._initialize_from_json(convert_to_mgrd_skeleton(skeleton), model_data) data = mp.sample_low_dimensional_vectors(n_samples) n_spatial = mp.get_n_spatial_components() features = data[:, :n_spatial] options = {"n_subdivisions": n_subdivisions_per_level, "clustering_method": CLUSTERING_METHOD_KMEANS, "use_feature_mean": False} return FeatureClusterTree(features, data, None, options, [])
def load_motion_from_str(builder, bvh_str, name, node_key, motion_id, meta_info_str="", draw_mode=2, visualize=True, color=None): if color is None: color = get_random_color() bvh_reader = get_bvh_from_str(bvh_str) print("loaded motion", bvh_reader.frames.shape) animated_joints = [ key for key in list(bvh_reader.node_names.keys()) if not key.endswith("EndSite") ] skeleton = SkeletonBuilder().load_from_bvh(bvh_reader, animated_joints) motion_vector = MotionVector() motion_vector.from_bvh_reader(bvh_reader, False) motion_vector.skeleton = skeleton motion_vector.scale_root(0.01) o = builder.create_object("animation_controller", name, skeleton, motion_vector, bvh_reader.frame_time, draw_mode, visualize, color) if "data_base_ids" not in builder._scene.internal_vars: builder._scene.internal_vars["data_base_ids"] = dict() builder._scene.internal_vars["data_base_ids"][o.node_id] = (node_key, motion_id) if meta_info_str != "": c = o._components["animation_controller"] meta_info = json.loads(meta_info_str) if "sections" in meta_info: sections = meta_info["sections"] if type(sections) == list: semantic_annotation = create_annotation_from_sections_list( sections, motion_vector.n_frames) else: semantic_annotation = create_annotation_from_sections_dict( sections, motion_vector.n_frames) color_map = dict() for key in semantic_annotation.keys(): color_map[key] = get_random_color() c.set_color_annotation(semantic_annotation, color_map) return o
def get_joint_speed(bvhreader, feature_joints): skeleton = SkeletonBuilder().load_from_bvh(bvhreader) left_toe_pos = [] right_toe_pos = [] left_toe_speed = [0] right_toe_speed = [0] for i in range(len(bvhreader.frames)): left_toe_pos.append( get_cartesian_coords(bvhreader, skeleton, feature_joints[0], bvhreader.frames[i])) right_toe_pos.append( get_cartesian_coords(bvhreader, skeleton, feature_joints[1], bvhreader.frames[i])) for i in range(len(bvhreader.frames) - 1): left_toe_speed.append((left_toe_pos[i + 1][0] - left_toe_pos[i][0])**2 + (left_toe_pos[i + 1][2] - left_toe_pos[i][2])**2) right_toe_speed.append( (right_toe_pos[i + 1][0] - right_toe_pos[i][0])**2 + (right_toe_pos[i + 1][2] - right_toe_pos[i][2])**2) return left_toe_speed, right_toe_speed
def normalize_root(self, origin_point): """set the offset of root joint to (0, 0, 0), and shift the motions to original_point, if original_point is None, the set it as (0, 0, 0) """ origin_point = [origin_point['x'], origin_point['y'], origin_point['z']] if self.ref_bvh is not None: self.ref_bvhreader = BVHReader(self.ref_bvh) elif self.bvhreader is not None: self.ref_bvhreader = self.bvhreader else: raise ValueError('No reference BVH file for skeleton information') self.ref_bvhreader.node_names['Hips']['offset'] = [0, 0, 0] skeleton = SkeletonBuilder().load_from_bvh(self.ref_bvhreader) for filename, frames in self.aligned_motions.items(): height_1 = get_cartesian_coordinates_from_euler_full_skeleton(self.ref_bvhreader, skeleton, 'Bip01_R_Toe0', frames[0])[1] height_2 = get_cartesian_coordinates_from_euler_full_skeleton(self.ref_bvhreader, skeleton, 'Bip01_L_Toe0', frames[0])[1] height_3 = get_cartesian_coordinates_from_euler_full_skeleton(self.ref_bvhreader, skeleton, 'Bip01_R_Toe0', frames[-1])[1] height_4 = get_cartesian_coordinates_from_euler_full_skeleton(self.ref_bvhreader, skeleton, 'Bip01_L_Toe0', frames[-1])[1] height_offset = (height_1 + height_2 + height_3 + height_4)/4.0 self.aligned_motions[filename] = self.translate_to_original_point( frames, origin_point, height_offset)
def load_skeleton(path, skeleton_type=None): bvh = BVHReader(path) skeleton = SkeletonBuilder().load_from_bvh(bvh) skeleton.skeleton_model = load_skeleton_model(skeleton_type) return skeleton
class AnnotatedMotionVector(MotionVector): def __init__(self, skeleton=None, algorithm_config=None, rotation_type=ROTATION_TYPE_QUATERNION): super(AnnotatedMotionVector, self).__init__(skeleton, algorithm_config, rotation_type) self.keyframe_event_list = None self.mg_input = None self.graph_walk = None self.grounding_constraints = None self.ground_contacts = None self.ik_constraints = collections.OrderedDict() def export(self, output_filename, add_time_stamp=False, export_details=False): """ Saves the resulting animation frames, the annotation and actions to files. Also exports the input file again to the output directory, where it is used as input for the constraints visualization by the animation server. """ MotionVector.export(self, self.skeleton, output_filename, add_time_stamp) self.export_annotation(output_filename) def export_annotation(self, output_filename): if self.mg_input is not None: write_to_json_file(output_filename + ".json", self.mg_input.mg_input_file) if self.keyframe_event_list is not None: self.keyframe_event_list.export_to_file(output_filename) def load_from_file(self, file_name): bvh = BVHReader(file_name) self.skeleton = SkeletonBuilder().load_from_bvh(bvh) def generate_bvh_string(self): quat_frames = np.array(self.frames) if len(quat_frames) > 0 and len( quat_frames[0]) < self.skeleton.reference_frame_length: quat_frames = self.skeleton.add_fixed_joint_parameters_to_motion( quat_frames) bvh_writer = BVHWriter(None, self.skeleton, quat_frames, self.skeleton.frame_time, True) return bvh_writer.generate_bvh_string() def to_unity_format(self, scale=1.0): """ Converts the frames into a custom json format for use in a Unity client""" animated_joints = [ j for j, n in list(self.skeleton.nodes.items()) if "EndSite" not in j and len(n.children) > 0 ] # self.animated_joints unity_frames = [] for node in list(self.skeleton.nodes.values()): node.quaternion_index = node.index for frame in self.frames: unity_frame = self._convert_frame_to_unity_format( frame, animated_joints, scale) unity_frames.append(unity_frame) result_object = dict() result_object["frames"] = unity_frames result_object["frameTime"] = self.frame_time result_object["jointSequence"] = animated_joints if self.graph_walk is not None: result_object["events"] = self._extract_event_list_from_keyframes() return result_object def _convert_frame_to_unity_format(self, frame, animated_joints, scale=1.0): """ Converts the frame into a custom json format and converts the transformations to the left-handed coordinate system of Unity. src: http://answers.unity3d.com/questions/503407/need-to-convert-to-right-handed-coordinates.html """ unity_frame = {"rotations": [], "rootTranslation": None} for node_name in self.skeleton.nodes.keys(): if node_name in animated_joints: node = self.skeleton.nodes[node_name] if node_name == self.skeleton.root: t = frame[:3] * scale unity_frame["rootTranslation"] = { "x": -t[0], "y": t[1], "z": t[2] } if node_name in self.skeleton.animated_joints: # use rotation from frame # TODO fix: the animated_joints is ordered differently than the nodes list for the latest model index = self.skeleton.animated_joints.index(node_name) offset = index * 4 + 3 r = frame[offset:offset + 4] unity_frame["rotations"].append({ "x": -r[1], "y": r[2], "z": r[3], "w": -r[0] }) else: # use fixed joint rotation r = node.rotation unity_frame["rotations"].append({ "x": -float(r[1]), "y": float(r[2]), "z": float(r[3]), "w": -float(r[0]) }) return unity_frame def _extract_event_list_from_keyframes(self): frame_offset = 0 event_list = list() for step in self.graph_walk.steps: time_function = None if self.graph_walk.use_time_parameters: time_function = self.graph_walk.motion_state_graph.nodes[ step.node_key].back_project_time_function(step.parameters) for c in step.motion_primitive_constraints.constraints: if c.constraint_type == SPATIAL_CONSTRAINT_TYPE_KEYFRAME_POSITION and c.event_name is not None: event_keyframe_index = c.extract_keyframe_index( time_function, frame_offset) event_list.append({ "eventName": c.event_name, "eventTarget": c.event_target, "keyframe": event_keyframe_index }) frame_offset += step.end_frame - step.start_frame + 1 print("extracted", event_list) return event_list
class MotionPrimitiveController(LegacySkeletonAnimationController): def __init__(self, scene_object, name, data, color=(0, 0, 1)): LegacySkeletonAnimationController.__init__(self, scene_object) self.motion_primitive = MotionStateGraphNode(None) self.skeleton = SkeletonBuilder().load_from_json_data(data["skeleton"]) self.frameTime = self.skeleton.frame_time self._visualizations = [] self.samples = [] self.algorithm_config = DEFAULT_ALGORITHM_CONFIG self.color = color self.motion_primitive._initialize_from_json(convert_to_mgrd_skeleton(self.skeleton), data) print("loaded motion primitive") print("spatial", self.motion_primitive.get_n_spatial_components()) print("time", self.motion_primitive.get_n_time_components()) self.motion_primitive.cluster_tree = None self.training_data = None #print("n gmm", len(self.motion_primitive.get_gaussian_mixture_model().weights)) self.name = name self._regenerate = True self.type = CONTROLLER_TYPE_MP set_log_mode(LOG_MODE_DEBUG) self.start_pose = {"position": [0, 0, 0], "orientation": [0, 0, 0]} self.mock_graph = MockGraph(self.skeleton) self.label_color_map = dict() def init_visualization(self): self.generate_random_samples(1) def load_cluster_tree_from_json_file(self, filepath): tree_data = load_json_file(filepath) self.load_cluster_tree_from_json(tree_data) def load_cluster_tree_from_json(self, tree_data): print("load cluster tree") self.motion_primitive.cluster_tree = FeatureClusterTree.load_from_json(tree_data) print("finished loading cluster tree") def clear(self): self.samples = [] self._visualizations = [] def generate_random_samples(self, n_samples, sample_offset=0): self.clear() if n_samples > 1: x_offset = -n_samples / 2 * sample_offset else: x_offset = 0 for idx in range(n_samples): self.generate_random_sample(x_offset) x_offset += sample_offset self.updated_frame() def generate_random_samples_from_tree(self, n_samples, sample_offset=0): if self.motion_primitive.cluster_tree is None: return self.clear() if n_samples > 1: x_offset = -n_samples / 2 * sample_offset else: x_offset = 0 for idx in range(n_samples): self.generate_random_sample_from_tree(x_offset) x_offset += sample_offset self.updated_frame() def generate_random_constraints(self, joint_name, frame_idx, n_samples): positions = [] for idx in range(n_samples): positions.append(self.generate_random_constraint(joint_name, frame_idx)) return positions def generate_random_sample(self, x_offset=0): spline = self.motion_primitive.sample(use_time=False) frames = spline.get_motion_vector() self.create_sample_visualization(frames, x_offset) def generate_random_sample_from_tree(self, x_offset=0): if self.motion_primitive.cluster_tree is not None: n_points = len(self.motion_primitive.cluster_tree.data) sample_idx = np.random.randint(0, n_points) print("visualize", sample_idx, "/", n_points) sample = self.motion_primitive.cluster_tree.data[sample_idx] frames = self.motion_primitive.back_project(sample, False).get_motion_vector() self.create_sample_visualization(frames, x_offset) def generate_random_sample_from_data(self, x_offset=0): self.clear() if self.training_data is not None: n_samples = len(self.training_data) sample_idx = np.random.randint(0, n_samples) print("visualize", sample_idx, "/", n_samples) sample = self.training_data[sample_idx] frames = self.motion_primitive.back_project(sample, False).get_motion_vector() self.create_sample_visualization(frames, x_offset) def create_sample_visualization(self, frames, x_offset=0): motion = AnnotatedMotionVector(skeleton=self.skeleton) frames[:, 0] += x_offset print(frames.shape) motion.append_frames(frames) v = SkeletonVisualization(self.scene_object, self.color) v.set_skeleton(self.skeleton) v.draw_mode = SKELETON_DRAW_MODE_LINES self._visualizations.append(v) self.samples.append(motion) def generate_constrained_sample(self, joint_name, frame_idx, position): action_constraints = ElementaryActionConstraints() action_constraints.motion_state_graph = self.mock_graph self.algorithm_config["local_optimization_settings"]["max_iterations"] = 50000 self.algorithm_config["local_optimization_settings"]["method"] = "L-BFGS-B" mp_generator = MotionPrimitiveGenerator(action_constraints, self.algorithm_config) #mp_generator.numerical_minimizer = OptimizerBuilder(self.algorithm_config).build_path_following_minimizer() mp_generator.numerical_minimizer = OptimizerBuilder(self.algorithm_config).build_path_following_with_likelihood_minimizer() mp_constraints = MotionPrimitiveConstraints() n_frames = self.getNumberOfFrames() if frame_idx == -1: frame_idx = n_frames-1 mp_constraints.skeleton = self.skeleton c_desc = {"joint": joint_name, "canonical_keyframe": frame_idx, "position": position, "n_canonical_frames": n_frames, "semanticAnnotation": {"keyframeLabel":"none"}} print("set constraint", c_desc) c = GlobalTransformConstraint(self.skeleton, c_desc, 1.0, 1.0) mp_constraints.constraints.append(c) mp_constraints.use_local_optimization = self.algorithm_config["local_optimization_mode"] in ["all", "keyframes"] vector = mp_generator.generate_constrained_sample(self.motion_primitive, mp_constraints) spline = self.motion_primitive.back_project(vector, use_time_parameters=False) frames = spline.get_motion_vector() self.create_sample_visualization(frames) def generate_random_constraint(self, joint_name, frame_idx): spline = self.motion_primitive.sample(use_time=False) frames = spline.get_motion_vector() position = self.skeleton.nodes[joint_name].get_global_position(frames[frame_idx]) return position def updated_frame(self): prevPlayAnimation = self.playAnimation self.playAnimation = True self.update(0) self.playAnimation = prevPlayAnimation def getNumberOfFrames(self): if self.isLoadedCorrectly(): return len(self.samples[0].frames) else: return 0 def isLoadedCorrectly(self): return len(self.samples) > 0 def export_to_file(self, filename, sample_idx=0): if sample_idx < len(self.samples): frame_time = self.frameTime frames = self.skeleton.add_fixed_joint_parameters_to_motion(self.samples[0].frames) bvh_writer = BVHWriter(None, self.skeleton, frames, frame_time, True) bvh_writer.write(filename) def get_skeleton_copy(self): skeleton = deepcopy(self.skeleton) count = 0 for node_key in skeleton.get_joint_names(): if node_key != skeleton.root: skeleton.nodes[node_key].quaternion_frame_index = count count += 1 return skeleton def get_motion_vector_copy(self, start_frame, end_frame, sample_idx=0): if sample_idx < len(self.samples): mv_copy = MotionVector() mv_copy.frames = deepcopy(self.samples[0].frames[start_frame:end_frame]) mv_copy.frames = self.skeleton.add_fixed_joint_parameters_to_motion(mv_copy.frames) mv_copy.n_frames = len(mv_copy.frames) mv_copy.frame_time = self.frameTime return mv_copy def draw(self, modelMatrix, viewMatrix, projectionMatrix, lightSources): if self.isLoadedCorrectly() and 0 <= self.currentFrameNumber < self.getNumberOfFrames(): for v in self._visualizations: v.draw(modelMatrix, viewMatrix, projectionMatrix, lightSources) def updateTransformation(self): if self.isLoadedCorrectly() and 0 <= self.currentFrameNumber < self.getNumberOfFrames(): # update global transformation matrices of joints for idx, motion in enumerate(self.samples): current_frame = motion.frames[self.currentFrameNumber] self._visualizations[idx].updateTransformation(current_frame, self.scene_object.scale_matrix) def setColor(self, color): print("set color", color) self.color = color for v in self._visualizations: v.set_color(color) def create_blend_controller(self): skeleton = self.skeleton motions = self.samples name = "Blend Controller" + self.name self.scene_object.scene.object_builder.create_blend_controller(name, skeleton, motions) def update_markers(self): return def set_config(self, algorithm_config): self.algorithm_config = algorithm_config def getFrameTime(self): return self.frameTime def get_semantic_annotation(self): n_keys = len(self.motion_primitive.keyframes) if n_keys <= 0: return None else: sorted_keyframes = collections.OrderedDict(sorted(self.motion_primitive.keyframes.items(), key=lambda t: t[1])) start = 0 end = int(self.motion_primitive.get_n_canonical_frames()) semantic_annotation = collections.OrderedDict() for k, v in sorted_keyframes.items(): semantic_annotation[k] = list(range(start, v)) self.label_color_map[k] = get_random_color() start = v k = "contact"+str(n_keys) semantic_annotation[k] = list(range(start, end)) self.label_color_map[k] = get_random_color() return list(semantic_annotation.items()) def get_label_color_map(self): return self.label_color_map def set_frame_time(self, frame_time): self.frameTime = frame_time def get_frame_time(self): return self.frameTime
def load_from_file(self, file_name): bvh = BVHReader(file_name) self.skeleton = SkeletonBuilder().load_from_bvh(bvh)