tanish434/Truebones-ZOO-Annotations
Truebones ZOO Annotations Text prompts, per-clip metadata, rest-pose renders and the exact build pipeline for Truebones ZOO — 1,097 animal motion clips across 74 skeletons: mammals, birds, reptiles, insects, marine and prehistoric creatures. 1.02 hours, 111,158 frames, uniformly 30 fps. Rigs range from 9 to 143 joints; clips from 0.3 to 18.5 seconds. The motion files themselves are not in this repository. Truebones ZOO is a commercial library by Truebones Motions Animation… See the full description on the dataset page: https://huggingface.co/datasets/tanish434/Truebones-ZOO-Annotations.
Truebones ZOO Annotations
Text prompts, per-clip metadata, rest-pose renders and the exact build pipeline for Truebones ZOO — 1,097 animal motion clips across 74 skeletons: mammals, birds, reptiles, insects, marine and prehistoric creatures. 1.02 hours, 111,158 frames, uniformly 30 fps. Rigs range from 9 to 143 joints; clips from 0.3 to 18.5 seconds.
The motion files themselves are not in this repository. Truebones ZOO is a commercial library by Truebones Motions Animation Studios and may not be redistributed. What ships here is everything around the motions — one text prompt per clip, four-view renders of every clip, per-clip and per-species metadata, one rest-pose render per skeleton, and the dependency-free pipeline that rebuilds the exact per-clip dataset from your own purchased copy: buy the library at <https://truebones.gumroad.com/l/skZMC>, unpack it here, run four scripts, and animation/ materialises byte-for-byte (sixteen clips excepted; see below).
Structure
animation.csv one row per clip (1,097)
animation_prompts.json one text prompt per clip (1,097)
animation_frames.json clip -> frame count
animation_bones.json species -> its joint names
species.csv one row per species (74)
species_tpose/<Species>.png one rest-pose render grid per species (74)
animation_render/<clip>/ four-view render per clip: MP4 + camera JSON per view (1,097)
clips.csv one row per source file (2,447), mapped onto animation/
excluded.csv source files no importer reads (1)
scripts/pipeline|probes the build pipeline and the format readers
animation/<Species>-<Action>.fbx not included — rebuilt from your purchased copy (see below)
animation_glb/ not included — the same clips as GLB, converted locally
Truebone_Z-OO/<Group>/… not included — the original commercial downloadRebuilding animation/
Purchase Truebones ZOO from <https://truebones.gumroad.com/l/skZMC> and unpack it next to these files as Truebone_Z-OO/, one folder per animal group, layout and names as shipped. Then run the pipeline — pure Python 3, no dependencies:
cd scripts
python3 pipeline/build_dataset.py # 1. index the download -> ../clips.csv
python3 pipeline/normalize.py # 2. name every clip -> ../clips.csv
python3 pipeline/build_animation.py # 3. one file per motion -> ../animation/
python3 pipeline/build_metadata.py # 4. measure animation/ -> ../animation.csv, ../species.csv, sidecarsThe result is one flat folder, one file per motion, named <Species>-<Action>.fbx:
Cat-Walk.fbx Trex-Big_Roar_Step.fbx SabreToothTiger-Tired_Yawn.fbxThe species is a single alphanumeric token and the action never contains a hyphen, so name.split("-", 1) always recovers both parts. Actions are underscore-separated capitalised words with a trailing _2 / _3 for variants, matching the Mixamo convention.
Guarantees, each checked rather than assumed: exactly one animation per file, no clip repeats another, every source motion is covered (one exception, Lynx/Idle4, ships only inside a combined file), and 30 fps throughout, measured from key times.
Selecting and renaming only — nothing is ever re-exported. Every clip is a hardlink straight into Truebone_Z-OO/, byte for byte, so no clip carries a rig that a round trip through an editor has altered. Steps 1 and 4 regenerate clips.csv, animation.csv, species.csv and the two JSON sidecars; apart from the sixteen repaired clips below they should match the files shipped here, which is also how to verify a rebuild. Step 5, build_prompts.py, re-downloads the captions from their source; its result already ships here as animation_prompts.json. scripts/README.md documents each step.
Sixteen of the 1,097 clips received a one-off binary repair that the pipeline does not re-apply: the four Cat clips had their missing texture embedded (probes/fbx_embed_texture.py), and the twelve KingCobra clips had a duplicated co-located mesh variant removed (probes/fbx_strip_variant.py); one of them, KingCobra-Walk, whose source shipped no mesh at all, additionally received a sibling's mesh (probes/fbx_graft_mesh.py) and had its material settings aligned with its siblings' (probes/fbx_align_material.py). These edits touch textures and meshes only, never the motion. All four probes are included and documented in scripts/README.md, each gated on a byte-identical no-edit round trip and writing through a temporary file so the source keeps its own bytes.
The GLB mirror, animation_glb/, is a one-to-one conversion of animation/ — mesh, armature, and the clip's single animation take, named after the action — for toolchains that read glTF rather than FBX. Regenerate it from your rebuilt clips with Blender's FBX importer and glTF exporter.
animation.csv
species.csv
Per species: num_clips, num_joints, rig_variants, root_joint, total_frames, total_duration_sec, mean_duration_sec, num_textures, source_fbx, source_bvh, has_combined_all, has_tpose.
rig_variants is how many distinct joint-name sets the species' clips use — 1 for 72 of them, 2 for KingCobra and 4 for Monkey. Counts run from 70 clips (Trex) to 3 (Chicken, Parrot2), median 12.
species_tpose/
One 1024×1024 PNG per species: a 2×2 grid of its rest pose — front and back on the top row, left and right below — rendered (EEVEE) from the species' first clip in animation/. A visual index of the 74 rigs.
animation_render/
A four-view render of every clip, straight from its FBX (mesh and textures included). One folder per clip, named after the FBX stem:
animation_render/Cat-Walk/
v000.mp4 v000.json front (azimuth -90°)
v001.mp4 v001.json back (azimuth +90°)
v002.mp4 v002.json left (azimuth 180°)
v003.mp4 v003.json right (azimuth 0°)Rendered with Blender EEVEE at 512×512, 30 fps, elevation 0, and composed into one H.264 MP4 per view — the transparent-film frames flattened onto a light-grey background, since H.264 carries no alpha. The MP4s preview each motion directly on the Hub; the per-frame RGBA PNGs behind them are not hosted (they would add over 400k files), so extract stills from the MP4s (ffmpeg -i v000.mp4 frames/%04d.png) if you need them.
Rendering covers the first 200 frames of a clip (~6.7 s); 117 of the 1,097 clips are longer and are truncated — frame_start/frame_end in the per-view JSON record the covered range. Frame counts otherwise match animation_frames.json exactly.
Each v00X.json holds the camera in NeRF convention: view, azimuth/elevation (radians), resolution, camera_angle_x (horizontal FoV, radians), the 4×4 camera-to-world transform_matrix, the scene_scale/scene_offset that normalised the asset into frame, and frame_start/frame_end/fps. The nine inferred prompts in animation_prompts.json were written against these renders.
clips.csv
One row per file in Truebone_Z-OO/, mapping every source path onto the dataset: status says what the file is (linked into animation/, a BVH mirror of a linked clip, a duplicate, a group's combined ALL file, a static pose, or an orphan), and animation_file points at the clip that carries its motion. Use it to trace any clip back to the exact source files it came from.
animationframes.json and animationbones.json
Two flat sidecars, sorted by key:
// animation_frames.json — 1,097 keys
"Alligator-Big_Mouth.fbx": 136
// animation_bones.json — 74 keys, one per species
"Pigeon": ["Hips", "LeftArm", "LeftForeArm", "LeftLeg",
"RightArm", "RightForeArm", "RightLeg", "Spine", "Tail01"]The skeleton is per species, so the bone list is keyed by species: the joint set its clips most often carry, taken from actual files. For 72 of the 74 every clip matches it exactly; the exceptions are KingCobra and Monkey, whose variants species.csv records as rig_variants.
animation_prompts.json
One text prompt per clip — a flat map from filename to a small record, absent fields left out:
"Trex-Death.fbx": {
"object_name": "Tyrannosaurus Rex",
"prompt": "A running tyrannosaurus rex loses balance and falls to the right.",
"prompt_source": "t2m4lvo"
}The captions come from T2M4LVO, the annotation set released with How to Move Your Dragon (ICML 2025). T2M4LVO is CC-BY-NC-4.0 — non-commercial use only, narrower than the rest of this repository. Three captions are shared by two clips each; retrieval metrics should group ground truth by caption text so those pairs are not scored as misses.
Processing it into motion data
This repository is the raw layer. The pipeline that turns it into canonicalized, text-paired motion clips is open at `UniMate/data_process`: it exports each clip to NPZ, renders previews, captions them with a vision-language model, cleans the joint labels and derives the training features. The processed release built from it is UniML3D.
bash data_process/scripts/run_download.sh truebones
bash data_process/scripts/run_export.sh truebonesUsage
import csv, collections
clips = list(csv.DictReader(open("animation.csv")))
species = list(csv.DictReader(open("species.csv")))
# clips of at least a second, grouped by species
by_species = collections.defaultdict(list)
for c in clips:
if float(c["duration_sec"]) >= 1.0:
by_species[c["species"]].append(c)
# every walk cycle in the library
walks = [c for c in clips if c["action"].startswith("Walk")]scripts/probes/ bundles dependency-free FBX and BVH readers (fbx_probe.probe(path), bvh_probe.probe(path)) that return joints, keyframes, fps, duration, root and joint names.
Data notes
- `num_joints` counts every node in the FBX hierarchy, not only bones — the exporter types mesh and null containers as
LimbNodetoo, so an FBX typically reports two to four more "joints" than the matching BVH, and for a handful of rigsroot_jointis a container (Null,EAL1_2,N_ALL) rather thanHips. - Five species do not share one skeleton across their clips —
Elephant,Fox,Monkey,KingCobraandPolarBearBvary in rest offsets along authoring-batch lines, inherited from the source. Joint names agree everywhere;KingCobraadditionally ships 19- and 20-joint variants. A clip's rest pose is its own first frame, so these are also the five species whose clips carry more than one rest pose. - Source spelling is preserved verbatim, typos included (
Angery_Swat,Sqwak,Begg), so the mapping back toTruebone_Z-OO/stays exact. Joint naming is not standardised across species. - Materials are 2014 Phong with no `ReflectionFactor` set; Blender's importer defaults that to
Metallic1.0, so clips import fully metallic — setMetallicto 0 after import for a dielectric look. excluded.csvlists the one source file no importer reads (Truebone_Z-OO/Crocodile/CrocodileALL.fbx, not a binary FBX).
Source
Truebones Z-OO by Truebones Motions Animation Studios, obtained from <https://truebones.gumroad.com/l/skZMC>. Terms of Use.txt ships with the original download and governs what may be done with these assets: they may not be resold or redistributed — which is why no FBX, GLB or BVH is included here, and why animation/ is rebuilt from your own purchased copy. The metadata, sidecars and scripts describe and rebuild the library without containing it; the renders — the per-clip multi-view videos and frames and the rest-pose grids — depict Truebones assets and are included as visual reference. The captions carry their own license (CC-BY-NC-4.0; see animation_prompts.json above).
Citation
This dataset is part of UniML3D, the training corpus introduced in UniMate: One Unified Model to Animate Diverse Skeletons (SIGGRAPH Asia 2026; paper page). If you use it, please cite the paper:
@article{mou2026unimate,
title = {UniMate: One Unified Model to Animate Diverse Skeletons},
author = {Mou, Linzhan and Lei, Jiahui and Dou, Zhiyang and Cai, Chenyue and Song, Chaoyue and Finkelstein, Adam and Rusinkiewicz, Szymon},
journal = {arXiv preprint arXiv:2609.05415},
year = {2026}
}