# Configuration Files
There are four different types of configuration files:
- MVC Configuration Files
- Character Configuration Files
- Motion Configuration Files
- Retarget 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 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.
- scene (dict): Dictionary containing parameters used by the MVC's Model/Scene component.
- 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 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 animate an Animated Drawing character.
Add more dictionaries to add more characters into a scene.
Contains the following key-value pairs:
- character_cfg (str): Path to the character config file.
- motion_cfg (str): Path to the motion config file.
- retarget_cfg (str): Path to the retarget config file.
- view (dict): Dictionary containing parameters used by the MVC's View component.
- CLEAR_COLOR (List[float, float, float, float]): 0-1 float values indicating RGBA clear color (i.e. background color).
- WINDOW_DIMENSIONS (List[int, int]): Width, height (in pixels) of the window or output video file.
- DRAW_AD_RIG (bool): If `True`, renders the rig used to deform the Animated Drawings Mesh. Hides it otherwise.
- DRAW_AD_TXTR (bool): If `True`, renders the texture of the Animated Drawings character. Hides it otherwise.
- DRAW_AD_COLOR (bool): If `True`, renders the Animated Drawings mesh using per-joint colors instead of the original texture. Hides this otherwise.
- DRAW_AD_MESH_LINES (bool): If `True`, renders the Animated Drawings mesh edges. Hides this otherwise.
- CAMERA_POS (List[float, float, float]): The xyz position of the camera used to render the scene.
- CAMERA_FWD (List[float, float, float]): The vector used to define the 'forward' orientation of the camera.
- USE_MESA (bool): If `True`, will attempt to use osmesa to to render the scene directly to a file without requiring a window.
Necessary for headless video rendering.
This cannot be used if using an `interactive` mode controller.
- BACKGROUND_IMAGE (str): Path to an image to use for the video background. Will be stretched to fit WINDOW_DIMENSIONS.
- controller (dict): Dictionary containing parameters used by the MVC's Controller component.
- MODE (str): Specifies the 'mode' of the controller.
If set to `'interactive'`, scene is rendered into an interactive window with a movable camera, pause-able scene, and arrows that progress and rewind time.
Cannot be used when `view['USE_MESA']` is `True`.
If set to `video_render`, renders the video directly to file.
The window, if it appears, is non-interactive.
- KEYBOARD_TIMESTEP (float): The number of seconds to step forward/backward using left/right arrow keys.
Only used in `interactive` mode.
- OUTPUT_VIDEO_PATH (str): The full filepath where the output video will be saved.
Only used in `video_render` mode.
Currently, only `.gif` and `.mp4` video formats are supported.
Transparency is only available for `.gif` videos.
- OUTPUT_VIDEO_CODEC (str):
The codec to use when encoding the output video.
Only used in `video_render` mode and only if a `.mp4` output video file is specified.
## 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. 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`.
- width (int):
Width, in pixels, of `texture.png` and `mask.png` files located in same directory as `char_cfg`.
- skeleton (list[dict]): List of joints that comprise the character's skeleton. Each joint is a dictionary with the following key:value pairs:
- loc (List[int, int]):
The image-space location, in pixels, of the joint. (Note: (0, 0) is top-left corner of image)
- name (str):
The name of the joint.
- parent (str):
The name of the joint's parent joint within the skeletal chain. All joints must have another skeletal joint as their parent, with the exception of the joint named 'root', who's parent must be `null`.
## Motion Config File
This contains information about the motion used to drive the Animated Drawing.
Currently, only BVH (BioVision Hierarchy) files are supported, but there is considerable flexibility
regarding the skeleton specified within the BVH (note- only BVH's with one skeleton are supported).
- filepath (str): Path to the BVH file. This can be an absolute path, path relative to the current working directory, or path relative the AnimatedDrawings root directory.
- start_frame_idx (int):
If you want to skip beginning motion frames, this can be set to an int between 0 and `end_frame_idx`, inclusive.
- end_frame_idx (int):
If you want to skip ending motion frames, this can be set to an int between `start_frame_idx+1` and the BVH Frames Count, inclusive.
- frame_time (float):
If you want to override the frame time specified within the BVH, you can set it here.
- groundplane_joint (str):
The name of a joint that exists within the BVH's skeleton.
When visualizing the BVH's motion, the skeleton will have it's worldspace y offset adjusted so this joint is within the y=0 plane at `start_frame_idx`.
- forward_perp_joint_vectors (list[List[str, str]]):
During retargeting, it is necessary to compute the 'forward' vector for the skeleton at each frame.
To compute this, we define a series of joint name pairs.
Each joint name specifies a joint within the BVH skeleton.
For each pair, we compute the normalized vector from the first joint to the second joint.
We then compute the average of these vectors and compute its counter-clockwise perpendicular vector.
We zero out this vector's y value, and are left with a vector along an xz plane indicating the skeleton's forward vector.
- scale (float):
Uniformly scales the BVH skeleton.
Useful for visualizing the BVH motion.
Scaling the skeleton so it fits roughly within a (1, 1, 1) cube will visualize nicely.
- up (str):
The direction corresponding to 'up' within the BVH.
This is used during retargeting, not just BVH motion visualization.
Currently, only `+y` and `+z` are supported.
## Retarget Config File
This file contains the information necessary to apply the motion specified by the motion config onto the Animated Drawing character specified in the character config. Note: below we refer to the BVH actor's skeleton as skeleton and we refer to the Animated Drawing character's rig as rig or character rig.
- char_starting_location (List[float, float, float]):
The starting xzy position of the character's root.
- bvh_projection_bodypart_groups (list[dict]):
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 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:
- bvh_joint_names (list[str]):
A list containing the names of joints within the BVH skeleton.
- name (str):
A name used to refer to the projection group.
- method (str):
Specifies the projection plane to be used for joints within this group.
Currently, three options supported:
- `'frontal'`:
Joints are projected onto the frontal plane of the skeleton, as determined by its 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 `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 `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.
But how do we know the order in which to render character bodyparts?
The dictionaries within this list contain information specifying which joints should be rendered together (i.e. during the same pass) and how their 'depth' should be determined. Each dictionary contains the following key-value pairs:
- char_joints (list[str]):
A list of names of distal joints of bones within the character rig.
All mesh triangles close to these bones will be rendered on the same pass.
- bvh_depth_drivers (list[str]):
But how do we determine the order in which to render the character bodypart groups?
We do this by computing the distance from one or more skeleton joints (i.e. depth drivers) to their projection planes.
This contains a list of one or more skeleton joints used for this purpose:
the average depth is calculated, then character bodypart groups are rendered from smallest average depth to largest average depth.
- char_bvh_root_offset (dict):
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 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).
We compute the sum of the length of all joint chains; this is used as a heuristic for the scale of the skeleton. We compute a similar heuristic for the character rig, and scale the skeleton's per-frame root offset by the ratio of these values before applying it to the character.
- char_joints (list[list[str]]):
A list of one or more lists of joints defining a series of joint chains within the character rig (but joints do not need to be directly connected within the character rig).
We compute the sum of the length of all joint chains; this is used as a heuristic for the scale of the rig. We compute a similar heuristic for the BVH skeleton, and scale the skeleton's per-frame root offset by the ratio of these values before applying it to the character.
- bvh_projection_bodypart_group_for_offset (str):
The skeleton root position offsets must be projected onto a 2D plane prior to being used to translate the character rig.
But which plane should be used?
Ideally, this is the same plane as the BVH skeleton projection bodypart group responsible for translating the skeleton (often this is the legs).
Therefore, this is the `name` of a `bvh_projection_bodypart_group`: whichever plane this bvh_bodypart_group is projected onto will also be used for the root offset.
- char_joint_bvh_joints_mapping (dict[str, List[str, str]]):
To retarget a skeletal pose onto a character rig, we rotate the bones of the rig such that their global orientations within the 2D plane matches the global orientations of corresponding joints from the BVH skeleton after projections onto a 2D plane.
This dictionary defines a set of mappings between a character rig joint and a set of 2 BVH skeleton joints.
The dictionary keys are strings specifying the names of character rig joints.
At each frame, the character rig's bone (whose distal joint name is specified by the key) is rotated to match the orientation of the vector from the first BVH skeletal joints to the second BVH skeletal joint.
Note: the 2 BVH joints do not need to be directly connected within the BVH skeleton.
- char_runtime_checks (list[list[str]]):
Depending upon the pose the character is drawn in, sometimes it's better to remove elements from `char_joint_bvh_joints_mapping`.
The most frequent example of this occurs when tadpole people are drawn- characters in which the torso and the head are essentially the same.
For such characters, the 'neck' of the character, as drawn, essentially points downward.
When the neck is rotated to match the orientation of a human skeleton, this flips the character's face, producing poor results.
For situations like this, you can specify runtime checks to do once the starting pose of the drawn character is known.
Each item in the list is its own check to run; the first item in the list is the type of test to run, and the other list items are the parameters it needs.
Currently, only `above` test is supported.
In this test, the second element is the name of a target joint, and the third and fourth elements are the names of reference joints.
If the target joint is not `above` the vector from the first to the second reference joint, it is removed.