mmd-anim-runtime 0.1.3

Renderer-independent MMD animation runtime core
Documentation

mmd-anim

mmd-anim is a Rust animation foundation for playing MikuMikuDance animation across multiple platforms.

It loads PMX/VMD data and evaluates world matrices, skinning matrices, morph weights, and IK state at any frame. The library is designed so the same runtime can be called from browsers, command-line tools, Rust applications, mobile applications, game engines, and other host environments.

Status

mmd-anim is still in an evaluation stage.

It is tested against data exported from the original MMD and against several PMX/VMD assets, but real-world usage is still limited. APIs and features are not frozen yet, and breaking changes may happen before 1.0. Feedback is welcome.

PMM support is partial. The current release can inspect PMMv1/PMMv2 metadata, preserve parsed PMM bytes for lossless round trips, and generate a limited single-model PMMv2 scene from PMX/VMD inputs through the maintainer CLI. It is not a complete semantic PMM exporter yet, and generated PMM files should be validated in MikuMikuDance before production use.

Runtime Evaluation

  • Load a PMX model and convert it into runtime-ready model data.
  • Load a VMD motion, resolve names against the PMX model, and convert it into a playable clip.
  • Evaluate a frame and read the bone matrices, morph weights, and IK on/off state for that moment.
  • Interpolate between keyframes with MMD-style Bezier interpolation for translation and rotation.

Physics simulation is not included. Rigid-body and joint data can be read and written, but cloth, hair, and other physics-driven motion must be handled by the host-side physics engine.

Test Foundation

mmd-anim is a shared animation foundation for multiple projects, so test coverage focuses on keeping evaluated results correct.

The repository includes tests for:

  • animation evaluation, bone hierarchy evaluation, IK, append transforms, morphs, and format read/write paths;
  • round-trip checks that write parsed data and read it back without changing the represented content;
  • frame-by-frame PMX/VMD runtime evaluation against expected synthetic results;
  • maintainer CLI diagnostics for inspecting loaded models and evaluated state;
  • C ABI and WASM smoke checks to confirm host-facing APIs use the same runtime path.

Recommended public release checks:

cargo test --workspace
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo doc --workspace --no-deps

Used By

mmd-anim is developed as the shared animation backend for MMD-related projects.

  • three-mmd-loader: A Three.js MMD loader that uses mmd-anim as its animation and format backend.

More integrations can share the same runtime core through the Rust API, C ABI, or WASM wrapper.

Supported Formats

Format support overview. "Loading" means parsing a file into structured data. "Writing" means outputting the target file format.

Format Loading Writing
PMX model sections + soft-body header diagnostics writing / JSON conversion / generation from mesh data
PMD model structure + partial runtime import writing / JSON conversion
VMD supported supported
VPD supported supported
PMM header, timeline, display state, referenced assets, PMMv2 summaries, and selected keyframe payload metadata partial support: lossless parsed-byte round trip, limited source-byte patches, and experimental single-model PMX/VMD scene generation
X/VAC text X mesh, material, UV, normal, vertex color + VAC settings and raw lines text X / VAC wrapper writing

Crates

Crate Role
mmd-anim Main public crate. Provides the evaluation core and format handling through one entry point.
mmd-anim-runtime Format-independent evaluation core: model arena, pose, VMD evaluation, append transforms, IK, and morphs.
mmd-anim-format PMX/VMD runtime import, format detection, structured loading, and PMX/PMD/VMD/VPD/X/VAC writing.
mmd-anim-ffi C ABI for native hosts. Exposes runtime operations and PMX parts writing. Repository-local for the 0.1.x line.
mmd-anim-wasm wasm-bindgen wrapper for browsers. Exposes runtime operations, loading/writing APIs, and PMX parts writing. Workspace-local for the 0.1.x line.
mmd-anim-cli Maintainer diagnostics and verification command-line tool. Repository-local for the 0.1.x line.
mmd-anim-schema Maintainer quality-check schema helper crate. Repository-local for the 0.1.x line.

For normal library use, depend on mmd-anim. Advanced users who only need a lower layer can depend on mmd-anim-format or mmd-anim-runtime directly.

Rust Usage

[dependencies]
mmd-anim = "0.1"

Native Hosts (C ABI)

Native applications and game engines can use the C ABI from mmd-anim-ffi. It is not tied to a specific engine; any host that can call a C ABI can use it (Unity is one example). The header is crates/mmd-anim-ffi/include/mmd_runtime.h.

// 1. Create a model from PMX bytes
mmd_runtime_model_t* model =
    mmd_runtime_model_create_from_pmx_bytes(pmx_bytes, pmx_len);

// 2. Create an animation clip from VMD bytes
mmd_runtime_clip_t* clip =
    mmd_runtime_clip_create_from_vmd_bytes_for_model(model, vmd_bytes, vmd_len);

// 3. Create an instance
mmd_runtime_instance_t* instance =
    mmd_runtime_instance_create_for_model(model);

// 4. Evaluate a frame
mmd_runtime_instance_evaluate_clip_frame(instance, clip, 300.0f);

// 5. Copy world matrices
size_t len = mmd_runtime_instance_world_matrix_f32_len(instance);
mmd_runtime_instance_copy_world_matrices(instance, out_f32, len);

// 6. Free resources
mmd_runtime_instance_free(instance);
mmd_runtime_clip_free(clip);
mmd_runtime_model_free(model);

The intended split is that the host owns meshes, materials, and textures, while this runtime provides matrices, morph state, and IK state. To generate PMX from host-side geometry data, use mmd_runtime_export_pmx_from_parts. Input arrays remain owned by the caller, and returned bytes must be freed with mmd_runtime_byte_buffer_free.

This native integration crate is not published to crates.io for the 0.1.x line. It is kept in the Rust workspace for builds and checks.

WASM / Browser

The browser build uses wasm-pack build --target web. A Node.js-only build is not used.

cd .\crates\mmd-anim-wasm\harness
npm run build

Generated files are written to crates/mmd-anim-wasm/harness/pkg/.

import init, {
  exportMmdFormatBytes,
  exportPmxFromParts,
  exportVmdAnimationJsonBytes,
  parseMmdFormatJson,
  WasmMmdClip,
  WasmMmdModel,
  WasmMmdRuntimeInstance,
} from "./pkg/mmd_anim_wasm.js";

await init();

// Runtime evaluation
const model = WasmMmdModel.fromPmxBytes(pmxBytes);
const clip = WasmMmdClip.fromVmdBytesForModel(model, vmdBytes);
const runtime = WasmMmdRuntimeInstance.forModel(model);

runtime.evaluateClipFrame(clip, 300);
const world = runtime.worldMatrices();

// Explicitly free resources when they are no longer needed.
runtime.free();
clip.free();
model.free();

// Loading / writing without a runtime handle
const json = parseMmdFormatJson(vmdBytes, "motion.vmd");
const exportedBytes = exportVmdAnimationJsonBytes(json);
const normalizedBytes = exportMmdFormatBytes(vmdBytes, "motion.vmd");

// Generate PMX from typed arrays
const generatedPmxBytes = exportPmxFromParts(
  JSON.stringify({
    modelName: "generated",
    materials: [{ name: "mat", faceCount: 1 }],
    bones: [{ name: "root", parentIndex: -1, position: [0, 0, 0] }],
  }),
  positionsXyz,
  normalsXyz,
  uvsXy,
  indices,
  skinIndices,
  skinWeights,
  edgeScale,
);

The WASM package is not published to crates.io for the 0.1.x line. It is kept in the Rust workspace for builds and checks.

CLI Checks

For local loading and writing checks, use the repository-local mmd-anim-cli. Available subcommands can be listed with:

cargo run -p mmd-anim-cli -- --help

This command-line tool is for maintainer diagnostics and is not required for public releases.

Current Limitations

  • Evaluation core: PMD loading and partial runtime import are supported for bones, IK, morph slots, and vertex morph offsets, but renderer-side vertex deformation and full PMD compatibility are not claimed yet.
  • Writing: PMX generation from parts currently covers the initial range of geometry, materials, bones, display frames, morphs, and physics. PMM writing is limited to the data currently represented by the PMM manifest parser.
  • PMM: Supported PMM data currently includes project header information, timeline-derived values, display state, initial model-slot data, referenced assets, PMMv2 summary information, and asset/header consistency diagnostics. The PMM exporter can re-emit that limited manifest/header/slot/asset-reference surface as a PMMv2 file, but it is not a full PMM project-graph exporter. Keyframe payloads, full camera/light/accessory/self-shadow tracks, and other binary project graph data that are only summarized or not preserved by the parser cannot be reconstructed from PmmParsedManifest.
  • X/VAC: Text X mesh, material, normal, UV, vertex color, and common VAC line order are handled. Binary X is diagnostic-only.
  • Physics: Rigid-body and joint data can be read and written, but physics simulation itself is not provided. Physics-driven parts should be handled by the host engine.
  • API / ABI / WASM: These surfaces are still experimental. When integrating with an external host, start with a small smoke test and representative-frame checks.

Japanese README

References

This project was developed with reference to: