in fairmotion/tasks/motion_graph/motion_graph.py [0:0]
def create_random_motion(self, length, start_node=None):
"""
This funtion generate a motion from the given motion graph by randomly
traversing the graph.
length - length of the generated motion
start_node - we can specify a start node if necessary
"""
motion = velocity.MotionWithVelocity(skel=self.skel, fps=self.fps)
t_processed = 0.0
nodes = list(self.graph.nodes)
if start_node is None or start_node not in self.graph.nodes:
cur_node = random.choice(nodes)
else:
cur_node = start_node
visited_nodes = []
while t_processed < length:
# Record currently visiting node
visited_nodes.append(cur_node)
# Append the selected motion to the current motion
motion_idx = self.graph.nodes[cur_node]["motion_idx"]
frame_start = self.graph.nodes[cur_node]["frame_start"]
frame_end = self.graph.nodes[cur_node]["frame_end"]
# Load the motion if it is not loaded in advance
if self.motions[motion_idx] is None:
self.load_motion_at_idx(
motion_idx, self.motion_files[motion_idx]
)
"""
We should detach with the extra (frames_blend)
because motion.append affects the end of current motion
"""
m = motion_ops.cut(
self.motions[motion_idx],
frame_start,
frame_end + self.frames_blend,
)
if self.verbose:
logging.info(f"[{cur_node}] {self.graph.nodes[cur_node]}")
motion = motion_ops.append_and_blend(
motion, m, blend_length=self.blend_length,
)
t_processed = motion.length()
# Jump to adjacent node (motion) randomly
if self.graph.out_degree(cur_node) == 0:
if self.verbose:
logging.info("Dead-end exists in the graph!")
break
cur_node = random.choice(list(self.graph.successors(cur_node)))
return motion, visited_nodes