# ozz-animation: a C++ skeletal animation runtime and DCC conversion toolchain

> ozz-animation is an MIT-licensed C++17 library for loading, sampling and blending skeletal animation, plus offline tools that convert glTF, FBX, Collada, Obj, 3ds and dxf files into its own runtime structures. It is aimed at engine and tools programmers who want animation playback without a renderer or engine attached.

**guillaumeblanc/ozz-animation** — Open source c++ skeletal animation library and toolset

- Repository: https://github.com/guillaumeblanc/ozz-animation
- Website: http://guillaumeblanc.github.io/ozz-animation/
- Stars: 2,954 · Forks: 347
- Language: C++
- License: NOASSERTION
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/guillaumeblanc-ozz-animation

## The problem ozz-animation solves, and who it is for

Most engines treat animation as a subsystem of the engine. If you are building a renderer, a simulation, a console tool or a WebAssembly demo and you only need a skeleton posed correctly at time t, pulling in a full engine to get that is a bad trade. ozz-animation is the opposite arrangement: it is a runtime library for "loading, sampling, blending" character animation, and the README states plainly that it is renderer agnostic and game-engine agnostic. Nothing in it draws anything.

The audience follows from that. This is for engine programmers, tools programmers and technical animators who are comfortable with C++17 and with the idea that an animation clip is a data structure to be sampled rather than an object owned by a scene graph. The README notes the runtime code (ozz_base, ozz_animation, ozz_geometry) depends only on C++17, the C and C++ standard libraries, and contains no OS specific code. That is a deliberate constraint, and it is the reason the library can be dropped into a console build, a server-side tool or a WebAssembly target without a porting layer.

The second half of the project is easy to overlook. ozz-animation ships a toolchain that converts from glTF, Fbx, Collada, Obj, 3ds and dxf into its optimized runtime structures, and it also exposes offline libraries so you can implement conversion from a format it does not handle. So the project is really two things: a small runtime, and a converter that produces the data the runtime eats.

## How the runtime is put together: data-oriented, SoA, SIMD

The design vocabulary in the README and repository topics is explicit: data-oriented, SoA (structure of arrays), SIMD, SSE. In practice that means the library stores animation samples in layouts chosen for batch processing rather than for object-oriented convenience. A local-space transform for one joint at one key is not a heap-allocated object with virtual methods; it is an element in a contiguous array, and sampling a clip across many joints becomes a loop over that array. The repository's build files reflect the same priorities, with .clang-format at the top level and a src/ tree separate from include/.

The data flow has three stages. First, offline: the converter reads a DCC format and writes ozz runtime structures. Second, at load time: the runtime reads those structures. Third, per frame: you sample and blend. Blending is where the library spends most of its surface area, and the sample directories name the variants directly: samples/blend, samples/additive, samples/partial_blend, samples/motion_blend. Additive blending, partial blending and motion blending are distinct operations with distinct sample programs, which tells you the library does not pretend one blend function covers every case.

Two other sample directories are worth noting because they mark the boundary of the core. samples/two_bone_ik and samples/foot_ik implement inverse kinematics, and samples/look_at implements a constraint. These are built on top of the sampling and blending primitives rather than being part of the minimal runtime, which is consistent with a library that ships its higher-level techniques as examples you can read and adapt. samples/multithread is the counterpart on the execution side: sampling is presented as something you can spread across threads.

## Building ozz-animation and running a first sample

The repository is CMake-based: CMakeLists.txt sits at the top level, with build-utils/ alongside it. The README does not print a build command sequence, so the steps below follow the conventional CMake flow that the repository layout implies rather than a quoted block from the documentation. Clone the repository, configure a build directory, and build.

```bash
git clone https://github.com/guillaumeblanc/ozz-animation.git
cd ozz-animation
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release
```

The configure step is where you will first meet the dependency situation. The README separates the runtime from everything else: samples, tools and tests depend on external libraries (glfw, tinygltf, Fbx SDK, jsoncpp, gtest, among others), and those are not needed to ship the runtime. If you only want the runtime libraries, you do not need any of them. If you want the samples, you do need them, and the Fbx SDK in particular is a separate download with its own licence terms.

Once the samples are built, the ones worth starting with are the playback and skinning pair. samples/playback shows sampling a clip, and samples/skinning shows the result applied to a mesh. The samples share code under samples/framework/, which is where the windowing and file loading live. Run the playback sample first; if it opens and animates, your build and your asset path are both correct, and you can then move to samples/blend or samples/additive to see the blending API in use.

For the conversion path, the toolchain reads DCC formats and writes ozz runtime structures. The README does not document the converter's command line, so check the tool's own help output after building rather than assuming flags. The howtos/ directory and the project website at guillaumeblanc.github.io/ozz-animation are the documented entry points for that step.

## Where ozz-animation is the wrong choice

The library does not render. If you are looking for something that draws a character, you are looking at the wrong project, and the samples only draw because they link glfw and a rendering framework of their own. The README is honest about this: renderer agnostic is a design goal, not an oversight.

The dependency split cuts both ways. The runtime is nearly dependency-free, but the moment you want the offline conversion step you are in a different world: Fbx SDK, tinygltf, jsoncpp. If your build environment cannot host those, or if you need the conversion to happen on a machine where installing an Autodesk SDK is not acceptable, the toolchain half of the project is closed to you, and you are left writing your own converter against the offline libraries.

There is also a versioning cost. The project is at 0.17.0, released on 2026-08-01, following 0.16.0 on 2025-01-19 and 0.15.0 on 2024-04-13. That is a roughly annual cadence with pre-1.0 numbering, and it means the data formats and APIs are not frozen by a stability promise. If your pipeline bakes ozz runtime structures into shipped assets, a version bump is a re-bake, not just a recompile. The CHANGES.md file at the top level is where that cost is itemised, and it is the file to read before upgrading.

Finally, the licence metadata on the repository is NOASSERTION while the README states MIT. Those disagree, and the discrepancy is worth resolving from LICENSE.md itself before you rely on either.

## How ozz-animation differs from Assimp and from engine-bundled animation

The obvious comparison is Assimp, which people search for alongside this project. Assimp is an import library: it reads a large set of asset formats into an in-memory scene representation and stops there. It is not an animation runtime, and it does not define a compact on-disk format for clips. ozz-animation overlaps with Assimp only on the import side, and even there the goal differs: the README describes converting DCC formats into ozz optimized runtime structures, which is a bake step producing data shaped for sampling, not a general scene graph.

That distinction matters if you are choosing between them. If your problem is "read this FBX and give me a scene", Assimp is the direct answer. If your problem is "play this character animation at 60 Hz with additive blending and partial blending, on a platform with no OS abstraction", Assimp does not address it, and ozz-animation does. Using both is coherent: import broadly with one, bake narrowly with the other.

The second alternative is whatever animation system your engine already has. Unity and Unreal both ship skeletal animation, and the search data shows people asking about ozz-animation in a Unity context. The difference is architectural rather than feature-based. An engine's animation system is integrated with its scene graph, its asset pipeline and its editor. ozz-animation has none of those, which is exactly why it can be embedded in a renderer you wrote yourself, and exactly why it will feel like more work if you were expecting an editor-driven workflow.

## Maintenance, licence and the cost of upgrading

The repository is not archived, and the last push was on 2026-08-01, which is recent. Releases are tagged and dated: 0.17.0 on 2026-08-01, 0.16.0 on 2025-01-19, 0.15.0 on 2024-04-13. Continuous integration covers Linux, macOS, Windows and WebAssembly on both master and develop branches, per the build status table in the README, and a dashboard for all branches is published on the project site.

The upgrade cost has a specific shape. Because the toolchain bakes DCC files into ozz runtime structures, an upgrade can invalidate previously baked data, and the re-bake has to happen wherever your source assets live. That is a pipeline operation, not a library swap. The CHANGES.md file is the primary source for what moved between 0.16.0 and 0.17.0; the README does not document a compatibility policy or a rollback procedure, so treat the version pin as something you control on your side.

On licensing: the README states ozz-animation is distributed under the MIT License, while the repository metadata reports NOASSERTION. MIT is permissive and imposes essentially only attribution, but the disagreement between the two statements is a fact you should resolve by reading LICENSE.md and, if it matters to your organisation, by asking counsel. This is a description of what the files say, not legal advice. One more licence boundary sits outside the project: the Fbx SDK that the tools depend on is a separate component with its own terms, and it is not covered by ozz-animation's MIT grant.

## Conclusion

Adopt ozz-animation if you are writing a C++17 engine or tool and want skeletal playback that does not drag a renderer or an engine along with it, and if you can absorb the cost of running its offline converter as a build step. Do not adopt it if you need a ready-made character controller, a scene graph, or an editor: the README describes runtime playback, not a game framework. Before committing, check the CHANGES.md entry for 0.17.0, confirm that the sample closest to your use case (samples/two_bone_ik, samples/motion_extraction, samples/multithread) actually maps onto your pipeline, and verify the licence text in LICENSE.md yourself rather than relying on the repository's NOASSERTION metadata.

## FAQ

### How much do two minutes of animation cost in ozz-animation?

No memory or storage figure for animation length is published. The README describes the runtime as focusing on performance and memory constraints with a data-oriented design, and the toolchain converts DCC formats into ozz optimized runtime structures, but it does not state a per-minute cost.

### What are the four main types of animation in ozz-animation?

No list of four animation types appears in the README. What the repository does show is distinct blending operations with their own samples: samples/blend, samples/additive, samples/partial_blend and samples/motion_blend, alongside constraint samples such as samples/two_bone_ik and samples/look_at.

### Is Rick and Morty frame by frame animation in ozz-animation?

This question is about a television production and has no connection to ozz-animation. The project is a C++ skeletal animation library and toolset, and the README says nothing about any film or series.

### Which coding is best for animation with ozz-animation?

ozz-animation is a C++ library. The README states the runtime code (ozz_base, ozz_animation, ozz_geometry) depends only on C++17, the C and C++ standard libraries, and has no OS specific code, and that it is tested on WebAssembly, Linux, macOS and Windows for x86, x86-64 and ARM.

## Sources

- [guillaumeblanc/ozz-animation on GitHub](https://github.com/guillaumeblanc/ozz-animation)
- [Issues](https://github.com/guillaumeblanc/ozz-animation/issues)
- [Project website](http://guillaumeblanc.github.io/ozz-animation/)
- [README](https://github.com/guillaumeblanc/ozz-animation/blob/master/README.md)
- [Releases](https://github.com/guillaumeblanc/ozz-animation/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/guillaumeblanc-ozz-animation
