diff --git a/README.md b/README.md index def49329..6dd61369 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Video overview of [Animated Drawings OS Project](https://www.youtube.com/watch?v ## Installation -*This project has been tested with macOS Ventura 13.2.1 and Ubuntu 18.04. If you're installing on another operating sytem, you may encounter issues.* +*This project has been tested with macOS Ventura 13.2.1 and Ubuntu 18.04. If you're installing on another operating system, you may encounter issues.* We *strongly* recommend activating a Python virtual environment prior to installing Animated Drawings. Conda's Miniconda is a great choice. Follow [these steps](https://conda.io/projects/conda/en/stable/user-guide/install/index.html) to download and install it. Then run the following commands: @@ -78,7 +78,7 @@ Instead of an interactive window, the animation was saved to a file, video.mp4, ### Export transparent .gif -Perhaps you'd like a transparent .gif instead of an .mp4? Copy these lines in the Python interpreter intead: +Perhaps you'd like a transparent .gif instead of an .mp4? Copy these lines in the Python interpreter instead: ````python from animated_drawings import render diff --git a/animated_drawings/config.py b/animated_drawings/config.py index 1dd9c6a0..3a4b2dce 100644 --- a/animated_drawings/config.py +++ b/animated_drawings/config.py @@ -19,7 +19,7 @@ def __init__(self, user_mvc_cfg_fn: str) -> None: with open(resource_filename(__name__, "mvc_base_cfg.yaml"), 'r') as f: base_cfg = defaultdict(dict, yaml.load(f, Loader=yaml.FullLoader) or {}) # pyright: ignore[reportUnknownMemberType]) - # search for the user-specified mvc confing + # search for the user-specified mvc config user_mvc_cfg_p: Path = resolve_ad_filepath(user_mvc_cfg_fn, 'user mvc config') logging.info(f'Using user-specified mvc config file located at {user_mvc_cfg_p.resolve()}') with open(str(user_mvc_cfg_p), 'r') as f: @@ -410,7 +410,7 @@ def __init__(self, motion_cfg_fn: str) -> None: # noqa: C901 assert False, msg def validate_bvh(self, bvh_joint_names: List[str]) -> None: - """ Performs all the validation steps that depend upon knowing the BVH joint names. This should be called once the BVH had been leaded """ + """ Performs all the validation steps that depend upon knowing the BVH joint names. This should be called once the BVH had been loaded.""" try: for prox_joint_name, dist_joint_name in self.forward_perp_joint_vectors: assert prox_joint_name in bvh_joint_names, f'invalid prox_joint name in motion_cfg.forward_perp_joint_vectors: {prox_joint_name}' @@ -459,7 +459,7 @@ def __init__(self, retarget_cfg_fn: str) -> None: # noqa: C901 self.bvh_projection_bodypart_groups = retarget_cfg['bvh_projection_bodypart_groups'] for group in self.bvh_projection_bodypart_groups: - assert group['method'] in ['pca', 'saggital', 'frontal'], 'group method must be "pca", "saggital", or "frontal"' + assert group['method'] in ['pca', 'sagittal', 'frontal'], 'group method must be "pca", "sagittal", or "frontal"' except (AssertionError, ValueError) as e: msg = f'Error validating bvh_projection_bodypart_groups: {e}' logging.critical(msg) diff --git a/animated_drawings/model/animated_drawing.py b/animated_drawings/model/animated_drawing.py index 21537529..341f8c5c 100644 --- a/animated_drawings/model/animated_drawing.py +++ b/animated_drawings/model/animated_drawing.py @@ -587,7 +587,7 @@ def _initialize_vertices(self) -> None: # initialize xy positions of mesh vertices self.vertices[:, :2] = self.arap.solve(self.rig.get_joints_2D_positions()).reshape([-1, 2]) - # initialize texture coordiantes + # initialize texture coordinates self.vertices[:, 6] = self.mesh['vertices'][:, 1] # u tex self.vertices[:, 7] = self.mesh['vertices'][:, 0] # v tex diff --git a/animated_drawings/model/bvh.py b/animated_drawings/model/bvh.py index c7e96773..f97e8471 100644 --- a/animated_drawings/model/bvh.py +++ b/animated_drawings/model/bvh.py @@ -138,7 +138,7 @@ def from_file(cls, bvh_fn: str, start_frame_idx: int = 0, end_frame_idx: Optiona lines = f.read().splitlines() if lines.pop(0) != 'HIERARCHY': - msg = f'Malformed BVH in line preceeding {lines}' + msg = f'Malformed BVH in line preceding {lines}' logging.critical(msg) assert False, msg @@ -146,7 +146,7 @@ def from_file(cls, bvh_fn: str, start_frame_idx: int = 0, end_frame_idx: Optiona root_joint: BVH_Joint = BVH._parse_skeleton(lines) if lines.pop(0) != 'MOTION': - msg = f'Malformed BVH in line preceeding {lines}' + msg = f'Malformed BVH in line preceding {lines}' logging.critical(msg) assert False, msg @@ -206,13 +206,13 @@ def _parse_skeleton(cls, lines: List[str]) -> BVH_Joint: assert False, msg if lines.pop(0).strip() != '{': - msg = f'Malformed BVH in line preceeding {lines}' + msg = f'Malformed BVH in line preceding {lines}' logging.critical(msg) assert False, msg # Get offset if not lines[0].strip().startswith('OFFSET'): - msg = f'Malformed BVH in line preceeding {lines}' + msg = f'Malformed BVH in line preceding {lines}' logging.critical(msg) assert False, msg _, *xyz = lines.pop(0).strip().split(' ') @@ -225,7 +225,7 @@ def _parse_skeleton(cls, lines: List[str]) -> BVH_Joint: else: channel_num, channel_order = 0, [] if int(channel_num) != len(channel_order): - msg = f'Malformed BVH in line preceeding {lines}' + msg = f'Malformed BVH in line preceding {lines}' logging.critical(msg) assert False, msg diff --git a/animated_drawings/model/quaternions.py b/animated_drawings/model/quaternions.py index e2b53dc7..5500f0a9 100644 --- a/animated_drawings/model/quaternions.py +++ b/animated_drawings/model/quaternions.py @@ -135,7 +135,7 @@ def from_euler_angles(cls, order: str, angles: npt.NDArray[np.float32]) -> Quate angles = np.expand_dims(angles, axis=0) if len(order) != angles.shape[-1]: - msg = 'lengh of orders and angles does not match' + msg = 'length of orders and angles does not match' logging.critical(msg) assert False, msg diff --git a/animated_drawings/model/retargeter.py b/animated_drawings/model/retargeter.py index 1e1ffc68..f4e1a6c0 100644 --- a/animated_drawings/model/retargeter.py +++ b/animated_drawings/model/retargeter.py @@ -113,7 +113,7 @@ def _compute_normalized_joint_positions_and_fwd_vectors(self) -> None: Called during initialization. Computes fwd vector for bvh skeleton at each frame. Extracts all bvh skeleton joint locations for all frames. - Repositions them so root is above the orign. + Repositions them so root is above the origin. Rotates them so skeleton faces along the +X axis. """ # get joint positions and forward vectors @@ -128,7 +128,7 @@ def _compute_normalized_joint_positions_and_fwd_vectors(self) -> None: self.bvh_root_positions = self.joint_positions[:, :3] self.joint_positions = self.joint_positions - np.tile(self.bvh_root_positions, [1, len(self.bvh_joint_names)]) - # compute angle between skelton's forward vector and x axis + # compute angle between skeleton's forward vector and x axis v1 = np.tile(np.array([1.0, 0.0], dtype=np.float32), reps=(self.joint_positions.shape[0], 1)) v2 = self.fwd_vectors dot: npt.NDArray[np.float32] = v1[:, 0]*v2[:, 0] + v1[:, 1]*v2[:, 2] @@ -157,7 +157,7 @@ def _determine_projection_plane_normal(self, group_name: str, joint_names: List[ if projection_method == 'frontal': logging.info(f'{group_name} projection_method is {projection_method}. Using {x_axis}') return x_axis - elif projection_method == 'saggital': + elif projection_method == 'sagittal': logging.info(f'{group_name} projection_method is {projection_method}. Using {z_axis}') return z_axis elif projection_method == 'pca': @@ -240,7 +240,7 @@ def scale_root_positions_for_character(self, char_to_bvh_scale: float, projectio self.char_root_positions[0] = [0, 0] for idx in range(1, self.bvh_root_positions.shape[0]): - if np.array_equal(projection_plane, np.array([0.0, 0.0, 1.0])): # if saggital projection + if np.array_equal(projection_plane, np.array([0.0, 0.0, 1.0])): # if sagittal projection v1 = self.fwd_vectors[idx] # we're interested in forward motion else: # if frontal projection v1 = self.fwd_vectors[idx][::-1]*np.array([-1, 1, -1]) # we're interested in lateral motion @@ -316,7 +316,7 @@ def compute_orientations(self, bvh_prox_joint_name: str, bvh_dist_joint_name: st def get_retargeted_frame_data(self, time: float) -> Tuple[Dict[str, float], Dict[str, float], npt.NDArray[np.float32]]: """ Input: time, in seconds, used to select the correct BVH frame. - Caculate the proper frame and, for it, returns: + Calculate the proper frame and, for it, returns: - orientations, dictionary mapping from character joint names to world orientations (degrees CCW from +Y axis) - joint_depths, dictionary mapping from BVH skeleton's joint names to distance from joint to projection plane - root_positions, the position of the character's root at this frame. diff --git a/animated_drawings/model/time_manager.py b/animated_drawings/model/time_manager.py index 6ce5837d..cff6efb5 100644 --- a/animated_drawings/model/time_manager.py +++ b/animated_drawings/model/time_manager.py @@ -16,7 +16,7 @@ def __init__(self, **kwargs): self._is_paused: bool = False def tick(self, delta_t: float) -> None: - """ Progress objects interal time by delta_t seconds if not paused """ + """ Progress objects interval time by delta_t seconds if not paused """ if not self._is_paused: self._time += delta_t self.update() diff --git a/animated_drawings/view/shaders/shader.py b/animated_drawings/view/shaders/shader.py index 4345881c..cf2ec9c0 100644 --- a/animated_drawings/view/shaders/shader.py +++ b/animated_drawings/view/shaders/shader.py @@ -50,6 +50,6 @@ def __init__(self, vertex_source, fragment_source): status: bool = GL.glGetProgramiv(self.glid, GL.GL_LINK_STATUS) if not status: - msg = f'Errror creating shader program: {GL.glGetProgramInfoLog(self.glid).decode("ascii")}' + msg = f'Error creating shader program: {GL.glGetProgramInfoLog(self.glid).decode("ascii")}' logging.critical(msg) assert False, msg diff --git a/examples/config/README.md b/examples/config/README.md index 13992d60..5172d8b7 100644 --- a/examples/config/README.md +++ b/examples/config/README.md @@ -10,7 +10,7 @@ There are four different types of configuration files: ## MVC Config File This is the top-level configuration file, passed into `render.start()` to generate the animation. All parameters and options not specifically related to the Animated Drawing character, the BVH file, or the retargeting process go in here. Such parameters belong to one of three subgroups, in alignment with the Model-View-Controller design pattern. (Note: the 'Model' element of MVC is referred to as 'scene') -Most of the available parameters are defined in [animated_drawings/mvc_base_cfg.yaml](../../animated_drawings/mvc_base_cfg.yaml). This file should **not** be changed. Instead, create a new mvc config file containg *only* the parameters that need to be modified. +Most of the available parameters are defined in [animated_drawings/mvc_base_cfg.yaml](../../animated_drawings/mvc_base_cfg.yaml). This file should **not** be changed. Instead, create a new mvc config file containing *only* the parameters that need to be modified. The rendering script will read the initial parameters from `mvc_base_cfg.yaml` and overwrite any parameters specified within the new mvc config file. See the [example mvc config files](mvc) for examples. @@ -18,7 +18,7 @@ See the [example mvc config files](mvc) for examples. - ADD_FLOOR (bool): If `True`, a floor will be added to the scene and rendered. - - ADD_AD_RETARGET_BVH (bool): If `True`, a visualization of the original BVH motion driving hte Animated Drawing characters will be added to the scene. + - ADD_AD_RETARGET_BVH (bool): If `True`, a visualization of the original BVH motion driving the Animated Drawing characters will be added to the scene. - ANIMATED_CHARACTERS List[dict[str:str, str:str, str:str]]: A list of dictionaries containing the filepaths of config files necessary to create and animated an Animated Drawing character. @@ -78,7 +78,7 @@ Only used in `video_render` mode and only if a `.mp4` output video file is speci ## Character Config File -This configuration file (referred to below as `char_cfg`) contains the information necessary to create an instance of the Animated Drawing class. In addition to the fields below, which are explicitly listed within `char_cfg`, the filepath of `char_cfg` is used to store the location of the character's texture and mask files. Essentally, just make sure the associated `texture.png` and `mask.png` files are in the same directory as `char_cfg`. +This configuration file (referred to below as `char_cfg`) contains the information necessary to create an instance of the Animated Drawing class. In addition to the fields below, which are explicitly listed within `char_cfg`, the filepath of `char_cfg` is used to store the location of the character's texture and mask files. Essentially, just make sure the associated `texture.png` and `mask.png` files are in the same directory as `char_cfg`. - height (int): Height, in pixels, of `texture.png` and `mask.png` files located in same directory as `char_cfg`. @@ -145,7 +145,7 @@ The starting xzy position of the character's root. The big-picture goal of the retargeter is to use 3D skeletal motion data to drive a 2D character rig. As part of this process, we project the skeletal joint positions onto 2D planes. But we don't need to use the same 2D plane for every joint within the skeleton. -Depending upon the motion of particular skeletal bodyparts, it may be preferrable to use different planes (e.g. a frontal projection plane for the skeletal arms and torso, but a saggital projection plane for the legs). +Depending upon the motion of particular skeletal bodyparts, it may be preferable to use different planes (e.g. a frontal projection plane for the skeletal arms and torso, but a sagittal projection plane for the legs). `projection_bodypart_groups` contains a list of bodypart groups, corresponding the BVH skeletal joints which should all be projected onto the same plane. Each bodypart group is a dictionary with the follow key-value pairs: - joint_names (list[str]): @@ -161,17 +161,17 @@ Currently, three options supported: - `'frontal'`: Joints are projected onto the frontal plane of the skeleton, as determined by its forward vector. - - `'saggital'`: -Joints are projected onto the saggital plane of the skeleton, who's normal vector is clockwise perpendicular to the skeleton's forward vector. + - `'sagittal'`: +Joints are projected onto the sagittal plane of the skeleton, who's normal vector is clockwise perpendicular to the skeleton's forward vector. - `'pca'`: -We attempt to automatically choose the best plane (`frontal` or `saggital`) using the following method: +We attempt to automatically choose the best plane (`frontal` or `sagittal`) using the following method: 1. Subtract the skeleton root's xy position from each frame, fixing it above the origin. 2. Rotate the skeleton so it's forward vector is facing along the +x axis at each frame. 3. Create a point cloud comprised of the xzy locations of every joint within the bodypart group at every frame. 4. Perform principal component analysis upon the point cloud. (The first 1st and 2nd components define a projection plane that preserves the maximal variance within the point cloud. The 3rd component defines this plane's normal vector) - 5. Take the 3rd component and compute it's cosine similarity to the skeleton's `forward` vector and `saggital` vector. Use the projection plane who's normal vector is more similar to the 3rd component. + 5. Take the 3rd component and compute it's cosine similarity to the skeleton's `forward` vector and `sagittal` vector. Use the projection plane who's normal vector is more similar to the 3rd component. - char_bodypart_groups (list[dict]): If there is overlap between the character's torso and its arm, for example, one should be rendered in front of the other. @@ -192,7 +192,7 @@ the average depth is calculated, then character bodypart groups are rendered fro Unless the BVH skeleton stands in the same place for the entirety of motion clip, the root joint of the character rig must be offset to account for the skeleton's translation. But the proportion of the skeleton and character rig may be very different. Additionally, the skeleton moves in three dimensions while the character rig is restricted to two dimensions. -The fields within this dicionary are necessary to account for these issues. +The fields within this dictionary are necessary to account for these issues. - bvh_joints (list[list[str]]): A list of one or more lists of joints defining a series of joint chains within the BVH skeleton (but joints do not need to be directly connected within the BVH skeleton). diff --git a/examples/config/retarget/fair1_spf.yaml b/examples/config/retarget/fair1_spf.yaml index b742a7bd..ca9a7357 100644 --- a/examples/config/retarget/fair1_spf.yaml +++ b/examples/config/retarget/fair1_spf.yaml @@ -11,7 +11,7 @@ bvh_projection_bodypart_groups: - LeftForeArm - LeftHand - LeftHandEnd - method: saggital + method: sagittal name: Upper Limbs - bvh_joint_names: - RightUpLeg diff --git a/tests/test_render_files/human_zombie.yaml b/tests/test_render_files/human_zombie.yaml index b742a7bd..ca9a7357 100644 --- a/tests/test_render_files/human_zombie.yaml +++ b/tests/test_render_files/human_zombie.yaml @@ -11,7 +11,7 @@ bvh_projection_bodypart_groups: - LeftForeArm - LeftHand - LeftHandEnd - method: saggital + method: sagittal name: Upper Limbs - bvh_joint_names: - RightUpLeg