def __init__( self, request: Any, client_address: Any, server: BaseServer, command: Signal ) -> None: self.response = Signal() self.command = command self.response.connect(self.send_response) super().__init__(request, client_address, server)
class SkeletonAnimationControllerBase(ComponentBase): updated_animation_frame = Signal() reached_end_of_animation = Signal() update_scene_object = Signal() def __init__(self, scene_object): ComponentBase.__init__(self, scene_object)
def __init__(self): self.command = Signal() self.command.connect(self.handle_command) self.games = addon_loader() self.address = ("127.0.0.1", 12345) super().__init__( server_address=self.address, RequestHandlerClass=self.Handler, bind_and_activate=True, ) self.serve_forever()
class GSMServer(ThreadingTCPServer): class Handler(StreamRequestHandler): def __init__( self, request: Any, client_address: Any, server: BaseServer, command: Signal ) -> None: self.response = Signal() self.command = command self.response.connect(self.send_response) super().__init__(request, client_address, server) def handle(self) -> None: print(f"Connection from: {self.client_address}") while True: raw = self.rfile.readline() command = raw.decode(encoding="utf-8").strip().lower() if command == "": print(f"Disconnecting from: {self.client_address}") break print(f"{self.client_address[0]} wrote: {command}") self.command.emit(self.response, command) def send_response(self, msg: bytes): print(f"Sending:\n{str(msg, encoding='utf-8')}") self.wfile.write(msg) def __init__(self): self.command = Signal() self.command.connect(self.handle_command) self.games = addon_loader() self.address = ("127.0.0.1", 12345) super().__init__( server_address=self.address, RequestHandlerClass=self.Handler, bind_and_activate=True, ) self.serve_forever() def handle_command(self, return_signal: Signal, command: str): response = str() if command == "gamelist": response = json.dumps(self.games) return_signal.emit((response + "\n").encode("utf-8")) def finish_request(self, request: bytes, client_address: Tuple[str, int]) -> None: self.RequestHandlerClass(request, client_address, self, self.command)
def __init__(self, visualize=True, sim=None): Scene.__init__(self, visualize, sim) self.added_scene_object = Signal() self.updated_animation_frame = Signal() self.reached_end_of_animation = Signal() self.deleted_scene_object = Signal() self.update_scene_object = Signal() if self.visualize: self._create_visual_reference_frame() if constants.activate_simulation: self.contact_renderer = self.object_builder.create_object("contact_renderer",0.5, [0, 5, 0]) self.addObject(self.contact_renderer) self.scene_edit_widget = SceneEditWidget() else: self.ground = None self.scene_edit_widget = None self.enable_scene_edit_widget = False
class Handler(StreamRequestHandler): def __init__( self, request: Any, client_address: Any, server: BaseServer, command: Signal ) -> None: self.response = Signal() self.command = command self.response.connect(self.send_response) super().__init__(request, client_address, server) def handle(self) -> None: print(f"Connection from: {self.client_address}") while True: raw = self.rfile.readline() command = raw.decode(encoding="utf-8").strip().lower() if command == "": print(f"Disconnecting from: {self.client_address}") break print(f"{self.client_address[0]} wrote: {command}") self.command.emit(self.response, command) def send_response(self, msg: bytes): print(f"Sending:\n{str(msg, encoding='utf-8')}") self.wfile.write(msg)
class MotionStateMachineController(StateMachineController): """ can be combined with a SkeletonVisualization component""" update_scene_object = Signal() def __init__(self, scene_object, skeleton, motion_vector): StateMachineController.__init__(self, scene_object) self.skeleton = skeleton self.state = MotionLoopState(motion_vector.frames, motion_vector.frame_time) self.vis = None self.play = False def update(self, dt): if self.play: self.state.update_pose(dt) if self.vis is not None and self.visible: self.vis.updateTransformation(self.state.current_pose, self.scene_object.scale_matrix) def get_pose(self, frame_idx=None): return self.state.current_pose def get_skeleton(self): return self.skeleton def toggleAnimation(self): self.play = not self.play
class ApplicationManager(QObject): """ main application logic controls the updates to the scene done by the main thread via a Qt.QTimer event holds the reference to the server thread "singleton class" by calling convention #http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python/33201#33201 """ instance = None added_scene_object = Signal() updated_animation_frame = Signal() reached_end_of_animation = Signal() deleted_scene_object = Signal() update_scene_object = Signal() def __init__(self, visualize=True, graphics_widget=None): if ApplicationManager.instance == None: ApplicationManager.instance = self QObject.__init__(self) self.visualize = visualize self.frames = 0 self.fps = 60.0 self.sim_dt = 1 / 30 self.interval = 1.0 / self.fps self.last_time = time.perf_counter() self.last_fps_update_time = self.last_time self.views = list() self.drawDebugVisualization = True self.statusBar = None self.scene = None self.graphics_widget = graphics_widget self.interaction = SceneInteraction() self.timer = QTimer() self.timer.timeout.connect(self.update) self.timer.start(0) self.timer.setInterval(self.interval * 1000) def toggle_renderer(self): self.use_color_renderer = not self.use_color_renderer print("use color picking renderer") def add_view(self, view): """adds view to list of views whose paint function is called by the function self.update() """ self.views.append(view) def init_scenes(self): sim = None if constants.activate_simulation: sim_settings = dict() sim_settings["auto_disable"] = False sim_settings["engine"] = "ode" #sim_settings["engine"] = "bullet" sim_settings["add_ground"] = True sim = SimWorld(**sim_settings) self.scene = EditorScene(self.visualize, sim) self.scene.added_scene_object.connect(self.relayAddedSceneObject) self.scene.reached_end_of_animation.connect(self.relayEndOfAnimation) self.scene.deleted_scene_object.connect(self.relayDeletedSceneObject) self.scene.update_scene_object.connect(self.relayUpdateSceneObject) #self.connect(self.scene, QtCore.SIGNAL('displayError(QString)'),self.relayShowErrorMessage) self.scene.updated_animation_frame.connect( self.relayUpdateAnimationFrame) self.interaction.set_scene(self.scene) for view in self.views: view.mouse_click.connect(self.on_mouse_click) view.mouse_move.connect(self.on_mouse_move) view.mouse_release.connect(self.on_mouse_release) print("init scene") def on_mouse_click(self, event, ray_start, ray_dir, pos, node_id): self.interaction.handleMouseClick(event, ray_start, ray_dir, pos) if event.button() == Qt.LeftButton: self.select_object(node_id, (ray_start, ray_dir)) self.update_scene_object.emit(node_id) def on_mouse_release(self, event): print("mouse release") self.scene.deactivate_axis() def on_mouse_move(self, event, last_mouse_pos, cam_pos, cam_ray): self.scene.handle_mouse_movement(cam_pos, cam_ray) def update(self): """ main loop of the application """ dt = self.update_delta_time() if self.scene is not None: # from locotest n_steps = int(math.ceil(self.interval / self.sim_dt)) self.scene.before_update(dt) for i in range(0, n_steps): self.scene.sim_update(self.sim_dt) self.scene.update(dt) self.scene.after_update(dt) for view in self.views: view.graphics_context.update(dt) self.drawOnView(view) def update_scene(self, scene, dt): n_steps = int(math.ceil(self.interval / self.sim_dt)) scene.before_update(dt) for i in range(0, n_steps): scene.sim_update(self.sim_dt) scene.update(dt) scene.after_update(dt) def draw(self, projection, view): return def drawOnView(self, view): """ draw current scene on the given view (note before calling this function the context of the view has to be set as current using makeCurrent() and afterwards the doubble buffer has to swapped to display the current frame swapBuffers()) """ view.makeCurrent() view.graphics_context.render(self.scene) view.swapBuffers() def update_delta_time(self): t = time.perf_counter() dt = t - self.last_time self.last_time = t if t - self.last_fps_update_time > 1.0: self.fps = self.frames self.frames = 0 self.last_fps_update_time = t self.update_status_bar("FPS " + str(round(self.fps))) self.frames += 1 return dt def update_status_bar(self, message): if self.statusBar != None: self.statusBar.showMessage(message) def getDisplayedScene(self): return self.scene def select_object(self, sceneId, ray=None): return self.scene.select_object(sceneId, ray) def getSelectedObject(self): return self.scene.getSelectedObject() def getObject(self, sceneId): return self.scene.getObject(sceneId) def showSceneObject(self, sceneId): self.scene.showSceneObject(sceneId) def hideSceneObject(self, sceneId): self.scene.hideSceneObject(sceneId) def runPythonScript(self, filename): self.scene.runPythonScript(filename) def startSplineDefinition(self): self.interaction.set_mode(INTERACTION_DEFINE_SPLINE) def stopSceneInteraction(self): self.interaction.set_mode(INTERACTION_NONE) def startMarkerDefinition(self): self.interaction.set_mode(INTERACTION_DEFINE_MARKER) def createBoxObject(self): self.interaction.set_mode("box") def createSphereObject(self): self.interaction.set_mode("sphere") def createCapsuleObject(self): self.interaction.set_mode("capsule") def createLinkedCapsuleObject(self): self.interaction.set_mode("linked_capsule") def createRagDoll(self): self.interaction.set_mode("ragdoll") #====================================================================================================== # SCENE SIGNAL RELAYS #====================================================================================================== def relayAddedSceneObject(self, sceneId): sceneObject = self.scene.getObject(sceneId) if sceneObject is not None: self.added_scene_object.emit(sceneId, sceneObject.name) else: self.added_scene_object.emit(None, None) def relayUpdateSceneObject(self, sceneId): self.update_scene_object.emit(sceneId) def relayEndOfAnimation(self, animationIndex, loop): self.reached_end_of_animation.emit(animationIndex, loop) def relayUpdateAnimationFrame(self, frameNumber): self.updated_animation_frame.emit(frameNumber) def relayDeletedSceneObject(self, node_id): self.deleted_scene_object.emit(node_id) def deinitialize(self): self.timer.stop() def loadFile(self, path): if self.scene.object_builder.load_file(path): return elif path.endswith(".py"): self.scene.runPythonScript(path) else: print("Could not load", path)
class MotionGraphController(ComponentBase, AnimationController): """ The MotionGraphController class displays a motion genenrated by motion similarity graph The class emits a Qt signals when the animation state changes. The scene containing a controller connects to those signals and relays them to the GUI. """ updated_animation_frame = Signal() reached_end_of_animation = Signal() def __init__(self, scene_object, color=(0, 0, 1), mg=None): ComponentBase.__init__(self, scene_object) AnimationController.__init__(self) self._motion_graph = mg self._visualization = SkeletonVisualization(self.scene_object, color) self.name = "" strong_components = self._motion_graph.strong_components self.current_node_id = min(strong_components) self.current_direction = [] self.current_root_pos = [] self.current_root_quat = [] self.angleX = 0 self.frameTime = 0 self.animationSpeed = 1 def init_visualization(self): msg_node = self._motion_graph.get_pose_by_node_id(self.current_node_id) pose = np.copy(msg_node.pose) self.current_direction = quat_rotate_vector(pose[3:7], np.array([0, 0, 1])) self.current_direction[1] = 0 #prevent error accumulation in y axis self.current_root_pos = pose[:3] self.current_root_quat = pose[3:7] self._visualization.updateTransformation( msg_node.pose, self.scene_object.scale_matrix) def set_skeleton(self, skeleton): self._visualization.set_skeleton(skeleton) def update(self, dt): """ update current frame and global joint transformation matrices """ if self.playAnimation: self.updateTransformation() self.currentFrameNumber += 1 self.updated_animation_frame.emit(self.currentFrameNumber) def updateTransformation(self): # update global transformation matrices of joints if self.angleX > np.pi: self.angleX -= 2 * np.pi if self.angleX < -np.pi: self.angleX += 2 * np.pi if self.animationSpeed < 1: self.animationSpeed = 1 #for i in range(self.animationSpeed): self.current_node_id = self._motion_graph.sample_next_node_id( self.current_node_id) self.scene_object.scene.global_vars["node_id"] = self.current_node_id current_node = self._motion_graph.get_pose_by_node_id( self.current_node_id) pose = np.copy(current_node.pose) root_velocity = np.linalg.norm(current_node.velocity[:3]) if (math.isclose(self.angleX, 0.0)): #walking direction remains unchanged self.current_root_pos = self.current_root_pos + root_velocity * self.current_direction pose[:3] = self.current_root_pos else: pose[3:7] = quaternion_multiply(pose[3:7], current_node.velocity[3:7]) pose[3:7] = quaternion_multiply( pose[3:7], quaternion_from_euler(self.angleX, 0, 0)) self.current_root_quat = pose[3:7] self.current_direction = quat_rotate_vector( pose[3:7], np.array([0, 0, 1])) self.current_direction[ 1] = 0 # prevent error accumulation in y axis self.current_root_pos = self.current_root_pos + root_velocity * self.current_direction pose[:3] = self.current_root_pos self._visualization.updateTransformation( pose, self.scene_object.scale_matrix) def draw(self, modelMatrix, viewMatrix, projectionMatrix, lightSources): self._visualization.draw(modelMatrix, viewMatrix, projectionMatrix, lightSources) def drawFrame(self, viewMatrix, projectionMatrix, lightSources, color=(1.0, 1.0, 1.0)): for joint in self.jointControllers.values(): # print "draw",joint.name joint.draw(viewMatrix, projectionMatrix, lightSources, color=color) def getNumberOfFrames(self): return math.inf def getPosition(self): return self.current_root_pos * self.scene_object.get_scale() def set_frame_time(self, frame_time): self.skeleton.frame_time = frame_time def get_frame_time(self): return self.skeleton.frame_time
def handle_command(self, return_signal: Signal, command: str): response = str() if command == "gamelist": response = json.dumps(self.games) return_signal.emit((response + "\n").encode("utf-8"))
class EditorScene(Scene): """class for scenes that are supposed to be visualized """ def __init__(self, visualize=True, sim=None): Scene.__init__(self, visualize, sim) self.added_scene_object = Signal() self.updated_animation_frame = Signal() self.reached_end_of_animation = Signal() self.deleted_scene_object = Signal() self.update_scene_object = Signal() if self.visualize: self._create_visual_reference_frame() if constants.activate_simulation: self.contact_renderer = self.object_builder.create_object("contact_renderer",0.5, [0, 5, 0]) self.addObject(self.contact_renderer) self.scene_edit_widget = SceneEditWidget() else: self.ground = None self.scene_edit_widget = None self.enable_scene_edit_widget = False def toggle_scene_edit_widget(self): self.enable_scene_edit_widget = not self.enable_scene_edit_widget if self.selected_scene_object is not None and self.selected_scene_object != self.ground: self.scene_edit_widget.visible = self.enable_scene_edit_widget def _create_visual_reference_frame(self, scale=1): self.add_directional_light(scale) self.addObject(CoordinateSystemObject(10)) self.ground = SceneObject() self.ground.clickable = False diffuse_texture = Texture() diffuse_texture.make_chessboard() material = TextureMaterial(diffuse_texture) geom = Mesh.build_plane(10000, 10000, 8, 100, material) self.ground._components["geometry"] = GeometryDataComponent(self.ground, geom) self.addObject(self.ground) def add_directional_light(self, scale): o = SceneObject() origin = np.array([0.0, 0.0, 0.0]) intensities = np.array([1, 1, 1]) pos = np.array([20 * scale, 100 * scale, 10 * scale]) w = SHADOW_MAP_WIDTH h = SHADOW_MAP_HEIGHT shadow_box_length = SHADOW_BOX_LENGTH l = DirectionalLight(pos, origin, np.array([0.0, 1.0, 0.0]), intensities, w, h, scene_scale=scale,shadow_box_length=shadow_box_length) o._components["light"] = LightComponent(o, l) self.addObject(o) def addObject(self, sceneObject, parentId=None): sceneId = Scene.addObject(self, sceneObject, parentId) sceneObject.scene = self self.added_scene_object.emit(sceneId) return sceneId def update_and_draw(self, viewMatrix, projectionMatrix, dt): Scene.update_and_draw(self, viewMatrix, projectionMatrix, dt) def addAnimationController(self, scene_object, key): self.register_animation_controller(scene_object, key) self.addObject(scene_object) def register_animation_controller(self, scene_object, key): scene_object._components[key].updated_animation_frame.connect(self.slotUpdateAnimationFrameRelay) scene_object._components[key].reached_end_of_animation.connect(self.slotEndOfAnimationFrameRelay) if hasattr(scene_object._components[key], "update_scene_object"): scene_object._components[key].update_scene_object.connect(self.slotUpdateSceneObjectRelay) def slotUpdateAnimationFrameRelay(self, frameNumber): self.updated_animation_frame.emit(frameNumber) def slotEndOfAnimationFrameRelay(self, loop): self.reached_end_of_animation.emit(0, loop) def slotUpdateSceneObjectRelay(self, node_id): self.update_scene_object.emit(node_id) def loadUnityConstraintsFile(self, file_path): self.object_builder.create_object_from_file("unity_constraints",file_path) def loadAnimatedMesh(self, rig_path): scene_object = self.object_builder.create_object_from_file("rig",rig_path) self.addAnimationController(scene_object, "animation_controller") def getSplineObjects(self): for sceneObject in self.object_list: if isinstance(sceneObject, ConstraintObject): yield sceneObject def addSphere(self, name, position, radius=1.0, material=materials.blue, simulate=False, kinematic=True): #return self.object_builder.create_sphere_object(name, position, [1,0,0,0], radius, material, simulate, kinematic) return self.object_builder.create_object("sphere", name, position, [1, 0, 0, 0], radius, material, simulate, kinematic) def createGroupAnimationController(self, node_ids): anim_controllers = self.get_animation_controllers(node_ids) if len(anim_controllers) > 0: scene_object = SceneObject() group_animation_controller = GroupAnimationController(scene_object) for anim_controller in anim_controllers: group_animation_controller.add_animation_controller(anim_controller) scene_object.name = "Animation Group " + str(scene_object.node_id) scene_object.add_component("group_player", group_animation_controller) self.addAnimationController(scene_object, "group_player") def createBlendAnimationController(self, node_ids): anim_controllers = self.get_animation_controllers(node_ids) motions = [c._motion for c in anim_controllers] if len(motions) > 0: name = "Blend Controller" skeleton = anim_controllers[0].get_skeleton_copy() self.object_builder.create_object("blend_controller",name, skeleton, motions) def addArticulatedBody(self, node_id): scene_object = self.getSceneNode(node_id) if "static_mesh" in list(scene_object._components.keys()): self.object_builder.create_component("articulated_body", scene_object) def addSplineObject(self, name, points, color, granularity): scene_object = SceneObject() scene_object.name = name scene_object.visualization = splines.CatmullRomSplineRenderer(points, color[0], color[1], color[2], granularity) self.addObject(scene_object) return scene_object def removeObject(self, node_id): Scene.removeObject(self, node_id) self.deleted_scene_object.emit(node_id) def get_animation_controllers(self, node_ids): anim_objects = [self.getSceneNode(node_id) for node_id in node_ids] anim_controllers = [] for anim_object in anim_objects: if "animation_controller" in list(anim_object._components.keys()): anim_controller = anim_object._components["animation_controller"] anim_controllers.append(anim_controller) return anim_controllers def runPythonScript(self, filename): with open(filename, "r") as script_file: lines = script_file.read() #globals = globals()locals(), globals() context = dict() context["scene"] = self exec(lines, context) def select_object(self, scene_id, ray=None): self.selected_scene_object = self.getObject(scene_id) if self.selected_scene_object is not None and not self.selected_scene_object.clickable: self.selected_scene_object = None if self.scene_edit_widget is not None: if self.selected_scene_object is not None and self.selected_scene_object != self.ground: self.scene_edit_widget.activate(self.selected_scene_object, self.enable_scene_edit_widget) else: if not self.scene_edit_widget.activate_axis(scene_id, ray): self.scene_edit_widget.deactivate() elif self.scene_edit_widget.visible: self.selected_scene_object = self.scene_edit_widget.scene_object return self.selected_scene_object def update(self, dt): super().update(dt) self.scene_edit_widget.update(dt) def deactivate_axis(self): if self.scene_edit_widget is not None: self.scene_edit_widget.deactivate_axis() def handle_mouse_movement(self, cam_pos, cam_ray): if self.scene_edit_widget is not None: self.scene_edit_widget.move(cam_pos, cam_ray)
class AnimationDirectoryExplorer(ComponentBase, AnimationController): updated_animation_frame = Signal() reached_end_of_animation = Signal() def __init__(self, scene_object, folder_path, filetype, color): ComponentBase.__init__(self, scene_object) self.mainContext = 0 self.name = folder_path AnimationController.__init__(self) self.skeleton_vis = SkeletonVisualization(scene_object, color) self.skeleton_vis.draw_mode = 2 self.skeleton_vis.visible = False scene_object.add_component("skeleton_vis", self.skeleton_vis) self.folder_path = Path(folder_path) self._animation_files = [] self.current_controller = None self.motion_cache = dict() self.state = None for filename in self.folder_path.iterdir(): print(filename, filetype, filename.suffix) if filename.is_file() and filename.suffix == "." + filetype: self._animation_files.append(filename.name) self.select_file(self._animation_files[0]) def select_file(self, filename): if filename not in self._animation_files: return if filename not in self.motion_cache: self.load_file(filename) self.current_controller = filename self.skeleton_vis.set_skeleton(self.motion_cache[filename].skeleton, True) self.skeleton_vis.visible = True self.state = MotionState(self.motion_cache[filename]) self.state.play = self.playAnimation self.updateTransformation() return self.motion_cache[filename].n_frames 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 get_animation_files(self): return self._animation_files def update(self, dt): """ update current frame and global joint transformation matrices """ dt *= self.animationSpeed if self.isLoadedCorrectly(): if self.playAnimation: self.state.update(dt) self.updateTransformation() # update gui if self.state.frame_idx > self.getNumberOfFrames(): self.resetAnimationTime() self.reached_end_of_animation.emit(self.loopAnimation) else: self.updated_animation_frame.emit(self.state.frame_idx) def draw(self, modelMatrix, viewMatrix, projectionMatrix, lightSources): return def updateTransformation(self, frame_idx=None): if self.state is None: return if frame_idx is not None: self.state.set_frame_idx(frame_idx) pose = self.state.get_pose() self.skeleton_vis.updateTransformation(pose, np.eye(4)) def resetAnimationTime(self): if self.state is None: return AnimationController.resetAnimationTime(self) self.currentFrameNumber = 0 self.state.reset() self.updateTransformation(self.state.frame_idx) def setCurrentFrameNumber(self, frame_idx): if self.state is None: return self.state.set_frame_idx(frame_idx) self.updateTransformation() def getNumberOfFrames(self): if self.state is not None: return self.state.mv.n_frames else: return 0 def isLoadedCorrectly(self): return len(self._animation_files) > 0 and self.state is not None def getFrameTime(self): if self.isLoadedCorrectly(): return self.state.mv.frame_time else: return 0 def toggle_animation_loop(self): self.loopAnimation = not self.loopAnimation def set_draw_mode(self, draw_mode): self.skeleton_vis.draw_mode = draw_mode return def startAnimation(self): if self.state is None: return self.playAnimation = True self.state.play = True def stopAnimation(self): if self.state is None: return self.playAnimation = False self.state.play = False def load_selected(self): mv_copy = deepcopy(self.state.mv) self.scene_object.scene.object_builder.create_object( "animation_controller", self.current_controller, mv_copy.skeleton, mv_copy, mv_copy.frame_time)
class PointCloudAnimationController(ComponentBase, AnimationController): updated_animation_frame = Signal() reached_end_of_animation = Signal() def __init__(self, scene_object, color=DEFAULT_COLOR, visualize=True): ComponentBase.__init__(self, scene_object) AnimationController.__init__(self) self.animated_joints = [] self.visualize = visualize self.skeleton = None if visualize: self._sphere = SphereRenderer(10, 10, 1, color=color) a = [0, 0, 0] b = [1, 0, 0] self._line = DebugLineRenderer(a, b, color) self.draw_bone = False self._semantic_annotation = None self.frameTime = 1.0 / 30 self.motion_data = [] self.skeleton_model = None self.target_skeleton = None def toggle_animation_loop(self): self.loopAnimation = not self.loopAnimation def isLoadedCorrectly(self): return len(self.motion_data) > 0 def set_data(self, data): self.motion_data = [] for idx, frame in enumerate(data["motion_data"]): pc_frame = [] for p in frame: pc_frame.append(list(map(float, p))) self.motion_data.append(pc_frame) self.motion_data = np.array(self.motion_data) if 'skeleton' in list(data.keys()): self.skeleton = data["skeleton"] else: self.skeleton = None if 'has_skeleton' in list(data.keys()) and 'skeleton' in list( data.keys()): self.draw_bone = False #data['has_skeleton'] def update(self, dt): dt *= self.animationSpeed if self.isLoadedCorrectly(): if self.playAnimation: self.animationTime += dt self.currentFrameNumber = int(self.animationTime / self.getFrameTime()) # update gui if self.currentFrameNumber > self.getNumberOfFrames(): self.resetAnimationTime() else: self.updated_animation_frame.emit(self.currentFrameNumber) def draw(self, modelMatrix, viewMatrix, projectionMatrix, lightSources): if self._sphere is None: return if self.currentFrameNumber < 0 or self.currentFrameNumber >= self.getNumberOfFrames( ): return for position in self.motion_data[self.currentFrameNumber]: m = get_translation_matrix(position[:3]) m = np.dot(m, modelMatrix) self._sphere.draw(m, viewMatrix, projectionMatrix, lightSources) if self.draw_bone: for joint, value in list(self.skeleton.items()): if value['parent'] is not None: joint_idx = value['index'] joint_parent_idx = self.skeleton[value['parent']]['index'] start_point = self.motion_data[ self.currentFrameNumber][joint_parent_idx] end_point = self.motion_data[ self.currentFrameNumber][joint_idx] self._line.set_line(start_point, end_point) self._line.draw(modelMatrix, viewMatrix, projectionMatrix) def getNumberOfFrames(self): return len(self.motion_data) def getFrameTime(self): return self.frameTime def updateTransformation(self, frame_number=None): if frame_number is not None: self.currentFrameNumber = frame_number self.animationTime = self.getFrameTime() * self.currentFrameNumber def setCurrentFrameNumber(self, frame_number=None): if frame_number is not None: self.currentFrameNumber = frame_number self.animationTime = self.getFrameTime() * self.currentFrameNumber def apply_scale(self, scale): self.motion_data[:, :, :3] *= scale def apply_transform(self, m): for i, frame in enumerate(self.motion_data): for j, p in enumerate(frame): p = self.motion_data[i, j, :3] self.motion_data[i, j, :3] = np.dot(m, p) def setColor(self, color): self._sphere.technique.material.diffuse_color = color self._sphere.technique.material.ambient_color = color * 0.1 def getColor(self): return self._sphere.technique.material.diffuse_color def replace_skeleton_model(self, filename): data = load_json_file(filename) self.set_skeleton_model(data) def set_skeleton_model(self, model): self.skeleton_model = model #self.skeleton = SkeletonBuilder().load_from_json_data(data) #self.skeleton.joints = self._joints def get_semantic_annotation(self): return dict() def get_current_frame(self): if self.currentFrameNumber < 0 or self.currentFrameNumber >= self.getNumberOfFrames( ): return None return self.motion_data[self.currentFrameNumber] def get_skeleton(self): return self.skeleton def get_frame_time(self): return self.getFrameTime() def get_label_color_map(self): return dict() def set_frame_time(self, frame_time): self.frameTime = frame_time
class GroupAnimationController(ComponentBase, AnimationController): updated_animation_frame = Signal() reached_end_of_animation = Signal() def __init__(self, scene_object): ComponentBase.__init__(self, scene_object) self.mainContext = 0 AnimationController.__init__(self) self._animation_controllers = [] def add_animation_controller(self, animation_controller): self._animation_controllers.append(animation_controller) self.frameTime = animation_controller.frameTime def get_animation_controllers(self): return self._animation_controllers def update(self, dt): """ update current frame and global joint transformation matrices """ dt *= self.animationSpeed if self.isLoadedCorrectly(): if self.playAnimation: # frame and transformation matrices self.animationTime += dt self.currentFrameNumber = int(self.animationTime / self.getFrameTime()) self.updateTransformation(self.currentFrameNumber) # update gui if self.currentFrameNumber > self.getNumberOfFrames(): self.resetAnimationTime() self.reached_end_of_animation.emit(self.loopAnimation) else: self.updated_animation_frame.emit(self.currentFrameNumber) def draw(self, modelMatrix, viewMatrix, projectionMatrix, lightSources): return def updateTransformation(self, frameNumber=None): for controller in self._animation_controllers: if frameNumber is not None: controller.setCurrentFrameNumber(frameNumber) controller.updateTransformation() def resetAnimationTime(self): AnimationController.resetAnimationTime(self) self.currentFrameNumber = 0 self.updateTransformation(self.currentFrameNumber) def setCurrentFrameNumber(self, frameNumber): self.currentFrameNumber = frameNumber self.updateTransformation(self.currentFrameNumber) self.animationTime = self.getFrameTime() * self.currentFrameNumber def getNumberOfFrames(self): n_frames = [0] n_frames += [ controller.getNumberOfFrames() for controller in self._animation_controllers ] return max(n_frames) def isLoadedCorrectly(self): return len(self._animation_controllers) > 0 def getFrameTime(self): if self.isLoadedCorrectly(): # print self.frameTime return self.frameTime else: return 0 def toggle_animation_loop(self): self.loopAnimation = not self.loopAnimation