(joints: np.ndarray, output: str = "notebook", title: str = "",
fps: float = 12.5,
kinematic_tree: List[List[int]] = mmm_kinematic_tree,
colors: List[str] = mmm_colors,
figsize: Tuple[int] = (4, 4),
fontsize: int = 15)
| 74 | |
| 75 | |
| 76 | def render_animation(joints: np.ndarray, output: str = "notebook", title: str = "", |
| 77 | fps: float = 12.5, |
| 78 | kinematic_tree: List[List[int]] = mmm_kinematic_tree, |
| 79 | colors: List[str] = mmm_colors, |
| 80 | figsize: Tuple[int] = (4, 4), |
| 81 | fontsize: int = 15): |
| 82 | import matplotlib.pyplot as plt |
| 83 | from matplotlib.animation import FuncAnimation |
| 84 | import matplotlib.patheffects as pe |
| 85 | plt.rcParams.update({'font.size': fontsize}) |
| 86 | |
| 87 | # Z is gravity here |
| 88 | x, y, z = 0, 1, 2 |
| 89 | |
| 90 | # Convert mmm joints for visualization |
| 91 | # into smpl-h "scale" and axis |
| 92 | joints = joints.copy()[..., [2, 0, 1]] * mmm_to_smplh_scaling_factor |
| 93 | |
| 94 | # Create a figure and initialize 3d plot |
| 95 | fig = plt.figure(figsize=figsize) |
| 96 | ax = init_axis(fig, title) |
| 97 | |
| 98 | # Create spline line |
| 99 | trajectory = joints[:, 0, [x, y]] |
| 100 | avg_segment_length = np.mean(np.linalg.norm(np.diff(trajectory, axis=0), axis=1)) + 1e-3 |
| 101 | draw_offset = int(25 / avg_segment_length) |
| 102 | spline_line, = ax.plot(*trajectory.T, zorder=10, color="white") |
| 103 | |
| 104 | # Create a floor |
| 105 | minx, miny, _ = joints.min(axis=(0, 1)) |
| 106 | maxx, maxy, _ = joints.max(axis=(0, 1)) |
| 107 | plot_floor(ax, minx, maxx, miny, maxy, 0) |
| 108 | |
| 109 | # Put the character on the floor |
| 110 | height_offset = np.min(joints[:, :, z]) # Min height |
| 111 | joints = joints.copy() |
| 112 | joints[:, :, z] -= height_offset |
| 113 | |
| 114 | # Initialization for redrawing |
| 115 | lines = [] |
| 116 | initialized = False |
| 117 | |
| 118 | def update(frame): |
| 119 | nonlocal initialized |
| 120 | skeleton = joints[frame] |
| 121 | |
| 122 | root = skeleton[0] |
| 123 | update_camera(ax, root) |
| 124 | |
| 125 | for index, (chain, color) in enumerate(zip(reversed(kinematic_tree), reversed(colors))): |
| 126 | if not initialized: |
| 127 | lines.append(ax.plot(skeleton[chain, x], |
| 128 | skeleton[chain, y], |
| 129 | skeleton[chain, z], linewidth=8.0, color=color, zorder=20, |
| 130 | path_effects=[pe.SimpleLineShadow(), pe.Normal()])) |
| 131 | |
| 132 | else: |
| 133 | lines[index][0].set_xdata(skeleton[chain, x]) |
nothing calls this directly
no test coverage detected