moonbvhkit

MoonBit-native BVH motion capture parser, validator, analysis helpers, and asset pipeline toolkit.

bvh
mocap
animation
gamedev
moonbit
moon add zhangbowen2006/moonbvhkit@0.1.0
Download zip
Version
0.1.0
License
MIT
Last updated
20 days ago
Downloads
3
README

#MoonBVHKit

MoonBVHKit is a MoonBit-native BVH motion capture parser, validator, analysis helper library, and asset-pipeline reporting toolkit.

#Status

Version 0.1.0 is a hackathon-ready v1. The package contains a reusable library, CLI smoke command, basic example, tests, documentation, CI configuration, and Mooncakes metadata for zhangbowen2006/moonbvhkit.

Repository target: https://github.com/zhangbowen2006/MoonBVHKit.git.

Author/submission: 张博文.

#Supported Scope

  • ASCII BVH HIERARCHY parsing for ROOT, nested JOINT, and End Site.
  • OFFSET, standard position channels, and standard rotation channels.
  • MOTION parsing with Frames: and Frame Time:.
  • Fixed-width frame data as Array[Array[Double]].
  • Query helpers for joint names, paths, channel order, per-joint frame values, root position, and root motion.
  • Skeleton summaries, signatures, compatibility diffs, and name-based retarget maps.
  • Motion slicing, frame lookup by time, root-speed sampling, root teleport detection, and root-origin normalization.
  • Validation for malformed source, channel offsets, unknown channels, frame counts, frame widths, and importer-oriented warnings.
  • Import quality scoring with severity signals and recommended CI actions.
  • Unity, Blender, strict CI, and preview import profiles for reusable asset-gate decisions.
  • Text, JSON, and CSV reporting for automation.
  • Unity and Blender integration metadata plans, without depending on either application.

#Not Supported in v1

  • Blender Python add-on or Unity Editor plug-in.
  • Binary/private BVH variants.
  • Rotation baking, retargeting, IK, skeleton solving, or coordinate-system conversion.
  • Reading external files from the CLI. The CLI uses a built-in fixture so it is deterministic in CI.
  • GLTF, FBX, USD, or other model formats.

#Install

After publishing:

moon add zhangbowen2006/moonbvhkit

For local development, clone the repository and run the commands below from the project root.

moon check moon build moon test moon run cmd/main moon run cmd/main -- --json moon run cmd/main -- --csv moon run cmd/main -- --quality --json moon run cmd/main -- --profiles --csv moon run examples/basic

#Minimal Example

test "parse a BVH clip" {
let parsed = @moonbvhkit.parse_bvh(@moonbvhkit.fixture_walk_bvh())
assert_true(parsed.ok)
let doc = parsed.document
let stats = @moonbvhkit.analyze_bvh(doc)
assert_eq(stats.joint_count, 4)
assert_eq(stats.channel_count, 15)
}

#CLI

The CLI parses the built-in walk fixture and prints a deterministic report.

moon run cmd/main moon run cmd/main -- --json moon run cmd/main -- --csv moon run cmd/main -- --quality moon run cmd/main -- --quality --json moon run cmd/main -- --profile unity moon run cmd/main -- --profile blender --json moon run cmd/main -- --profile strict-ci --csv moon run cmd/main -- --profiles moon run cmd/main -- --help

Supported profiles are unity, blender, strict-ci, and preview.

#API Summary

AreaPublic API
Parsetokenize_bvh, parse_bvh, parse_bvh_or_empty
ModelBvhDocument, BvhJoint, BvhMotion, BvhChannel, BvhVec3
Queryjoint_names, joint_paths, find_joint, find_joint_by_path, channels_in_motion_order
Framesframe_values_for_joint, frame_values_for_joint_name, root_position_at, joint_rotation_at
Analysisanalyze_bvh, channel_ranges, widest_channel_range, detect_static_channels, sample_root_motion
Skeletonskeleton_bones, summarize_skeleton, compare_skeletons, build_name_based_retarget_map
Motion Toolsslice_document, frame_at_time, root_speed_samples, detect_root_teleports, normalize_root_origin
Validationvalidate_bvh, validate_document, validation_summary
Qualityquality_report, quality_report_from_bvh, quality_report_to_text, quality_report_to_json, quality_report_to_csv, quality_action_for_bvh
Import Profilesunity_import_profile, blender_import_profile, strict_ci_import_profile, evaluate_import_profile, import_decision_to_json
Exportdocument_to_json, joint_table_csv, channel_range_csv, root_motion_csv
Integrationbuild_unity_clip_plan, build_blender_import_plan, bvh_runtime_manifest
Reportbuild_report, format_report, bvh_fixture_report

#Project Positioning

MoonBVHKit fills a MoonBit ecosystem gap for motion-capture asset inspection. It is useful for game developers, tool authors, and CI pipelines that need to inspect BVH clips before importing them into Unity, Blender, Godot, or custom runtimes.

The project deliberately does not bind to Unity or Blender. Instead, it provides portable validation and metadata that those workflows can consume.

#Originality and References

This is an original MoonBit implementation. It references the public BVH text format structure commonly used by motion-capture tools, but does not copy code from another project.

All fixtures in this repository are handwritten synthetic data and do not contain third-party motion-capture assets.

#License

MIT.

#
BvhBlenderImportPlan

pub(all) struct BvhBlenderImportPlan {
armature_name : String
bone_count : Int
leaf_count : Int
frame_start : Int
frame_end : Int
fps : Double
preserve_root_motion : Bool
axis_notes : Array[String]
} derive(Eq,
Debug
)

#
BvhChannel

pub(all) enum BvhChannel {
ChannelXPosition
ChannelYPosition
ChannelZPosition
ChannelXRotation
ChannelYRotation
ChannelZRotation
ChannelUnknown(String)
} derive(Eq,
Debug
)

#
BvhChannel::axis

fn BvhChannel::axis(self : BvhChannel) -> String

#
BvhChannel::from_string

fn BvhChannel::from_string(name : String) -> BvhChannel

#
BvhChannel::is_known

fn BvhChannel::is_known(self : BvhChannel) -> Bool

#
BvhChannel::is_position

fn BvhChannel::is_position(self : BvhChannel) -> Bool

#
BvhChannel::is_rotation

fn BvhChannel::is_rotation(self : BvhChannel) -> Bool

#
BvhChannel::to_string

fn BvhChannel::to_string(self : BvhChannel) -> String

#
BvhChannelMean

pub(all) struct BvhChannelMean {
index : Int
name : String
mean : Double
sample_count : Int
} derive(Eq,
Debug
)

#
BvhChannelMean::new

fn BvhChannelMean::new(index : Int, name : String, mean : Double, sample_count : Int) -> BvhChannelMean

#
BvhChannelRange

pub(all) struct BvhChannelRange {
path : String
channel : String
index : Int
min : Double
max : Double
span : Double
} derive(Eq,
Debug
)

#
BvhChannelRange::new

fn BvhChannelRange::new(path : String, channel : String, index : Int, min : Double, max : Double) -> BvhChannelRange

#
BvhDocument

pub(all) struct BvhDocument {
root : BvhJoint
motion : BvhMotion
source_length : Int
token_count : Int
} derive(Eq,
Debug
)

#
BvhDocument::channel_count

fn BvhDocument::channel_count(self : BvhDocument) -> Int

#
BvhDocument::duration_seconds

fn BvhDocument::duration_seconds(self : BvhDocument) -> Double

#
BvhDocument::empty

fn BvhDocument::empty() -> BvhDocument

#
BvhDocument::end_site_count

fn BvhDocument::end_site_count(self : BvhDocument) -> Int

#
BvhDocument::is_complete

fn BvhDocument::is_complete(self : BvhDocument) -> Bool

#
BvhDocument::joint_count

fn BvhDocument::joint_count(self : BvhDocument) -> Int

#
BvhEndSite

pub(all) struct BvhEndSite {
path : String
offset : BvhVec3
depth : Int
} derive(Eq,
Debug
)

#
BvhEndSite::empty

fn BvhEndSite::empty() -> BvhEndSite

#
BvhEndSite::new

fn BvhEndSite::new(path : String, offset : BvhVec3, depth : Int) -> BvhEndSite

#
BvhError

pub(all) struct BvhError {
kind : BvhErrorKind
line : Int
column : Int
token : String
message : String
} derive(Eq,
Debug
)

#
BvhError::code

fn BvhError::code(self : BvhError) -> String

#
BvhError::is_error

fn BvhError::is_error(self : BvhError) -> Bool

#
BvhError::new

fn BvhError::new(kind : BvhErrorKind, message : String, line? : Int, column? : Int, token? : String) -> BvhError

#
BvhError::none

fn BvhError::none() -> BvhError

#
BvhErrorKind

pub(all) enum BvhErrorKind {
ErrorNone
ErrorEmptyInput
ErrorUnexpectedToken
ErrorUnexpectedEof
ErrorInvalidNumber
ErrorInvalidHierarchy
ErrorInvalidMotion
ErrorFrameWidthMismatch
ErrorUnsupportedFeature
} derive(Eq,
Debug
)

Error categories returned by the tokenizer, parser, validator, and report API.

#
BvhErrorKind::code

fn BvhErrorKind::code(self : BvhErrorKind) -> String

#
BvhFrameWindow

pub(all) struct BvhFrameWindow {
start_frame : Int
end_frame : Int
frame_count : Int
duration_seconds : Double
} derive(Eq,
Debug
)

#
BvhFrameWindow::new

fn BvhFrameWindow::new(start_frame : Int, end_frame : Int, frame_time : Double) -> BvhFrameWindow

#
BvhImportDecision

pub(all) struct BvhImportDecision {
profile_name : String
accepted : Bool
action : String
quality : BvhQualityReport
issues : Array[BvhValidationIssue]
} derive(Eq,
Debug
)

#
BvhImportDecision::error_count

fn BvhImportDecision::error_count(self : BvhImportDecision) -> Int

#
BvhImportDecision::issue_count

fn BvhImportDecision::issue_count(self : BvhImportDecision) -> Int

#
BvhImportDecision::ok

fn BvhImportDecision::ok(self : BvhImportDecision) -> Bool

#
BvhImportDecision::warning_count

fn BvhImportDecision::warning_count(self : BvhImportDecision) -> Int

#
BvhImportProfile

pub(all) struct BvhImportProfile {
kind : BvhImportProfileKind
name : String
max_joint_count : Int
max_depth : Int
max_duration_seconds : Double
min_frame_rate : Double
max_frame_rate : Double
max_root_speed : Double
max_root_teleport : Double
min_quality_score : Int
require_root_position : Bool
allow_unknown_channels : Bool
allow_child_position_channels : Bool
require_loop_closure : Bool
} derive(Eq,
Debug
)

#
BvhImportProfile::new

fn BvhImportProfile::new(kind : BvhImportProfileKind, name : String, max_joint_count? : Int, max_depth? : Int, max_duration_seconds? : Double, min_frame_rate? : Double, max_frame_rate? : Double, max_root_speed? : Double, max_root_teleport? : Double, min_quality_score? : Int, require_root_position? : Bool, allow_unknown_channels? : Bool, allow_child_position_channels? : Bool, require_loop_closure? : Bool) -> BvhImportProfile

#
BvhImportProfileKind

pub(all) enum BvhImportProfileKind {
ProfileUnity
ProfileBlender
ProfileStrictCI
ProfilePreview
} derive(Eq,
Debug
)

#
BvhImportProfileKind::to_string

fn BvhImportProfileKind::to_string(self : BvhImportProfileKind) -> String

#
BvhIssueSeverity

pub(all) enum BvhIssueSeverity {
IssueError
IssueWarning
IssueInfo
} derive(Eq,
Debug
)

#
BvhIssueSeverity::to_string

fn BvhIssueSeverity::to_string(self : BvhIssueSeverity) -> String

#
BvhJoint

pub(all) struct BvhJoint {
name : String
path : String
kind : BvhJointKind
offset : BvhVec3
channels : Array[BvhChannel]
channel_start : Int
channel_count : Int
depth : Int
children : Array[BvhJoint]
end_sites : Array[BvhEndSite]
} derive(Eq,
Debug
)

#
BvhJoint::empty

fn BvhJoint::empty() -> BvhJoint

#
BvhJoint::has_channel

fn BvhJoint::has_channel(self : BvhJoint, channel : BvhChannel) -> Bool

#
BvhJoint::is_root

fn BvhJoint::is_root(self : BvhJoint) -> Bool

#
BvhJoint::position_channel_count

fn BvhJoint::position_channel_count(self : BvhJoint) -> Int

#
BvhJoint::rotation_channel_count

fn BvhJoint::rotation_channel_count(self : BvhJoint) -> Int

#
BvhJointKind

pub(all) enum BvhJointKind {
JointRoot
JointRegular
} derive(Eq,
Debug
)

#
BvhJointKind::to_string

fn BvhJointKind::to_string(self : BvhJointKind) -> String

#
BvhMotion

pub(all) struct BvhMotion {
frame_count : Int
frame_time : Double
channel_count : Int
frames : Array[Array[Double]]
} derive(Eq,
Debug
)

#
BvhMotion::duration_seconds

fn BvhMotion::duration_seconds(self : BvhMotion) -> Double

#
BvhMotion::empty

fn BvhMotion::empty() -> BvhMotion

#
BvhMotion::is_empty

fn BvhMotion::is_empty(self : BvhMotion) -> Bool

#
BvhParseResult

pub(all) struct BvhParseResult {
ok : Bool
document : BvhDocument
error : BvhError
} derive(Eq,
Debug
)

#
BvhParseResult::failure

fn BvhParseResult::failure(error : BvhError) -> BvhParseResult

#
BvhParseResult::is_ok

fn BvhParseResult::is_ok(self : BvhParseResult) -> Bool

#
BvhParseResult::success

fn BvhParseResult::success(document : BvhDocument) -> BvhParseResult

#
BvhPoseSample

pub(all) struct BvhPoseSample {
frame_index : Int
root_position : BvhVec3
root_delta_from_first : BvhVec3
} derive(Eq,
Debug
)

#
BvhPoseSample::new

fn BvhPoseSample::new(frame_index : Int, root_position : BvhVec3, root_delta_from_first : BvhVec3) -> BvhPoseSample

#
BvhQualityGrade

pub(all) enum BvhQualityGrade {
QualityExcellent
QualityUsable
QualityNeedsReview
QualityBlocked
} derive(Eq,
Debug
)

#
BvhQualityGrade::recommended_action

fn BvhQualityGrade::recommended_action(self : BvhQualityGrade) -> String

#
BvhQualityGrade::to_string

fn BvhQualityGrade::to_string(self : BvhQualityGrade) -> String

#
BvhQualityReport

pub(all) struct BvhQualityReport {
grade : BvhQualityGrade
score : Int
signals : Array[BvhQualitySignal]
recommended_action : String
} derive(Eq,
Debug
)

#
BvhQualityReport::new

fn BvhQualityReport::new(score : Int, signals : Array[BvhQualitySignal]) -> BvhQualityReport

#
BvhQualityReport::ok_for_import

fn BvhQualityReport::ok_for_import(self : BvhQualityReport) -> Bool

#
BvhQualitySignal

pub(all) struct BvhQualitySignal {
severity : BvhIssueSeverity
code : String
score_delta : Int
message : String
} derive(Eq,
Debug
)

#
BvhQualitySignal::new

fn BvhQualitySignal::new(severity : BvhIssueSeverity, code : String, score_delta : Int, message : String) -> BvhQualitySignal

#
BvhReport

pub(all) struct BvhReport {
ok : Bool
summary : String
stats : BvhStats
validation : BvhValidationReport
error_code : String
} derive(Eq,
Debug
)

#
BvhReport::failure

fn BvhReport::failure(error : BvhError) -> BvhReport

#
BvhReport::success

fn BvhReport::success(summary : String, stats : BvhStats, validation : BvhValidationReport) -> BvhReport

#
BvhReportFormat

pub(all) enum BvhReportFormat {
ReportText
ReportJson
ReportCsv
} derive(Eq,
Debug
)

#
BvhRetargetMapEntry

pub(all) struct BvhRetargetMapEntry {
source_path : String
target_path : String
source_channel_count : Int
target_channel_count : Int
channel_compatible : Bool
notes : String
} derive(Eq,
Debug
)

#
BvhRetargetMapEntry::new

fn BvhRetargetMapEntry::new(source_path : String, target_path : String, source_channel_count : Int, target_channel_count : Int) -> BvhRetargetMapEntry

#
BvhRootTeleport

pub(all) struct BvhRootTeleport {
frame_index : Int
distance : Double
threshold : Double
} derive(Eq,
Debug
)

#
BvhRootTeleport::new

fn BvhRootTeleport::new(frame_index : Int, distance : Double, threshold : Double) -> BvhRootTeleport

#
BvhRuntimeManifest

pub(all) struct BvhRuntimeManifest {
package_name : String
version : String
supported_format : String
entries : Array[BvhSupportEntry]
} derive(Eq,
Debug
)

#
BvhSkeletonBone

pub(all) struct BvhSkeletonBone {
path : String
parent_path : String
name : String
depth : Int
offset : BvhVec3
offset_length : Double
channel_count : Int
has_end_site : Bool
} derive(Eq,
Debug
)

#
BvhSkeletonBone::new

fn BvhSkeletonBone::new(path : String, parent_path : String, name : String, depth : Int, offset : BvhVec3, channel_count : Int, has_end_site : Bool) -> BvhSkeletonBone

#
BvhSkeletonDiff

pub(all) struct BvhSkeletonDiff {
compatible : Bool
matched_paths : Array[String]
missing_paths : Array[String]
extra_paths : Array[String]
channel_mismatch_paths : Array[String]
offset_warning_paths : Array[String]
} derive(Eq,
Debug
)

#
BvhSkeletonDiff::issue_count

fn BvhSkeletonDiff::issue_count(self : BvhSkeletonDiff) -> Int

#
BvhSkeletonDiff::new

fn BvhSkeletonDiff::new(matched_paths : Array[String], missing_paths : Array[String], extra_paths : Array[String], channel_mismatch_paths : Array[String], offset_warning_paths : Array[String]) -> BvhSkeletonDiff

#
BvhSkeletonSummary

pub(all) struct BvhSkeletonSummary {
root_name : String
bone_count : Int
leaf_count : Int
end_site_count : Int
max_depth : Int
total_offset_length : Double
signature : String
} derive(Eq,
Debug
)

#
BvhSkeletonSummary::empty

#
BvhSpeedSample

pub(all) struct BvhSpeedSample {
frame_index : Int
seconds : Double
distance_from_previous : Double
speed_units_per_second : Double
} derive(Eq,
Debug
)

#
BvhSpeedSample::new

fn BvhSpeedSample::new(frame_index : Int, seconds : Double, distance_from_previous : Double, speed_units_per_second : Double) -> BvhSpeedSample

#
BvhStats

pub(all) struct BvhStats {
joint_count : Int
end_site_count : Int
max_depth : Int
channel_count : Int
frame_count : Int
frame_time : Double
duration_seconds : Double
root_motion_distance : Double
} derive(Eq,
Debug
)

#
BvhStats::empty

fn BvhStats::empty() -> BvhStats

#
BvhSupportEntry

pub(all) struct BvhSupportEntry {
feature : String
status : String
notes : String
} derive(Eq,
Debug
)

#
BvhSupportEntry::new

fn BvhSupportEntry::new(feature : String, status : String, notes : String) -> BvhSupportEntry

#
BvhToken

pub(all) struct BvhToken {
kind : BvhTokenKind
text : String
line : Int
column : Int
} derive(Eq,
Debug
)

#
BvhToken::is_text

fn BvhToken::is_text(self : BvhToken, text : String) -> Bool

#
BvhToken::new

fn BvhToken::new(kind : BvhTokenKind, text : String, line : Int, column : Int) -> BvhToken

#
BvhTokenKind

pub(all) enum BvhTokenKind {
TokenWord
TokenOpenBrace
TokenCloseBrace
} derive(Eq,
Debug
)

#
BvhTokenizeResult

pub(all) struct BvhTokenizeResult {
ok : Bool
tokens : Array[BvhToken]
error : BvhError
} derive(Eq,
Debug
)

#
BvhTokenizeResult::failure

#
BvhTokenizeResult::success

#
BvhUnityClipPlan

pub(all) struct BvhUnityClipPlan {
clip_name : String
frame_rate : Double
duration_seconds : Double
root_joint : String
joint_paths : Array[String]
root_motion_delta : BvhVec3
warnings : Array[String]
} derive(Eq,
Debug
)

#
BvhValidationIssue

pub(all) struct BvhValidationIssue {
severity : BvhIssueSeverity
path : String
code : String
message : String
} derive(Eq,
Debug
)

#
BvhValidationIssue::error

fn BvhValidationIssue::error(code : String, message : String, path? : String) -> BvhValidationIssue

#
BvhValidationIssue::info

fn BvhValidationIssue::info(code : String, message : String, path? : String) -> BvhValidationIssue

#
BvhValidationIssue::new

fn BvhValidationIssue::new(severity : BvhIssueSeverity, code : String, message : String, path? : String) -> BvhValidationIssue

#
BvhValidationIssue::warning

fn BvhValidationIssue::warning(code : String, message : String, path? : String) -> BvhValidationIssue

#
BvhValidationReport

pub(all) struct BvhValidationReport {
issues : Array[BvhValidationIssue]
error_count : Int
warning_count : Int
info_count : Int
} derive(Eq,
Debug
)

#
BvhValidationReport::new

#
BvhValidationReport::ok

#
BvhVec3

pub(all) struct BvhVec3 {
x : Double
y : Double
z : Double
} derive(Eq,
Debug
)

#
BvhVec3::add

fn BvhVec3::add(self : BvhVec3, other : BvhVec3) -> BvhVec3

#
BvhVec3::magnitude

fn BvhVec3::magnitude(self : BvhVec3) -> Double

#
BvhVec3::new

fn BvhVec3::new(x : Double, y : Double, z : Double) -> BvhVec3

#
BvhVec3::scale

fn BvhVec3::scale(self : BvhVec3, factor : Double) -> BvhVec3

#
BvhVec3::sub

fn BvhVec3::sub(self : BvhVec3, other : BvhVec3) -> BvhVec3

#
BvhVec3::to_csv

fn BvhVec3::to_csv(self : BvhVec3) -> String

#
BvhVec3::zero

fn BvhVec3::zero() -> BvhVec3

#
analyze_bvh

fn analyze_bvh(document : BvhDocument) -> BvhStats

#
average_root_speed

fn average_root_speed(document : BvhDocument) -> Double

#
blender_import_plan_to_json

fn blender_import_plan_to_json(plan : BvhBlenderImportPlan) -> String

#
blender_import_profile

fn blender_import_profile() -> BvhImportProfile

#
build_blender_import_plan

fn build_blender_import_plan(document : BvhDocument, armature_name? : String) -> BvhBlenderImportPlan

#
build_name_based_retarget_map

fn build_name_based_retarget_map(source : BvhDocument, target : BvhDocument) -> Array[BvhRetargetMapEntry]

#
build_report

fn build_report(input : String) -> BvhReport

#
build_unity_clip_plan

fn build_unity_clip_plan(document : BvhDocument, clip_name? : String) -> BvhUnityClipPlan

#
bvh_fixture_report

fn bvh_fixture_report(format? : BvhReportFormat) -> String

#
bvh_runtime_manifest

fn bvh_runtime_manifest() -> BvhRuntimeManifest

#
bvh_summary_line

fn bvh_summary_line(document : BvhDocument) -> String

#
bvh_tokens_to_text

fn bvh_tokens_to_text(tokens : Array[BvhToken]) -> String

#
channel_index_for_path

fn channel_index_for_path(document : BvhDocument, path : String, channel : BvhChannel) -> Int

#
channel_names

fn channel_names(channels : Array[BvhChannel]) -> Array[String]

#
channel_range_csv

fn channel_range_csv(document : BvhDocument) -> String

#
channel_ranges

fn channel_ranges(document : BvhDocument) -> Array[BvhChannelRange]

#
channels_in_motion_order

fn channels_in_motion_order(document : BvhDocument) -> Array[String]

#
channels_to_json

fn channels_to_json(channels : Array[BvhChannel]) -> String

#
clamp_frame_index

fn clamp_frame_index(document : BvhDocument, frame_index : Int) -> Int

#
compare_skeletons

fn compare_skeletons(reference : BvhDocument, candidate : BvhDocument, offset_epsilon? : Double) -> BvhSkeletonDiff

#
contains_unknown_channels

fn contains_unknown_channels(joint : BvhJoint) -> Bool

#
default_import_profiles

fn default_import_profiles() -> Array[BvhImportProfile]

#
detect_root_teleports

fn detect_root_teleports(document : BvhDocument, threshold : Double) -> Array[BvhRootTeleport]

#
detect_static_channels

fn detect_static_channels(document : BvhDocument, epsilon? : Double) -> Array[BvhChannelRange]

#
document_frame_rate

fn document_frame_rate(document : BvhDocument) -> Double

#
document_to_json

fn document_to_json(document : BvhDocument) -> String

#
end_site_paths

fn end_site_paths(document : BvhDocument) -> Array[String]

#
evaluate_bvh_import_profile

fn evaluate_bvh_import_profile(input : String, profile : BvhImportProfile) -> BvhImportDecision

#
evaluate_default_import_profiles

fn evaluate_default_import_profiles(document : BvhDocument) -> Array[BvhImportDecision]

#
evaluate_import_profile

fn evaluate_import_profile(document : BvhDocument, profile : BvhImportProfile) -> BvhImportDecision

#
find_joint

fn find_joint(document : BvhDocument, name : String) -> BvhJoint?

#
find_joint_by_path

fn find_joint_by_path(document : BvhDocument, path : String) -> BvhJoint?

#
first_frame

fn first_frame(document : BvhDocument) -> Array[Double]

#
fixture_empty_bvh

fn fixture_empty_bvh() -> String

#
fixture_invalid_frame_width

fn fixture_invalid_frame_width() -> String

#
fixture_invalid_missing_motion

fn fixture_invalid_missing_motion() -> String

#
fixture_static_pose_bvh

fn fixture_static_pose_bvh() -> String

#
fixture_unknown_channel

fn fixture_unknown_channel() -> String

#
fixture_walk_bvh

fn fixture_walk_bvh() -> String

#
format_report

fn format_report(report : BvhReport, format? : BvhReportFormat) -> String

#
frame_at

fn frame_at(document : BvhDocument, frame_index : Int) -> Array[Double]

#
frame_at_time

fn frame_at_time(document : BvhDocument, seconds : Double) -> Array[Double]

#
frame_values_for_joint

fn frame_values_for_joint(document : BvhDocument, joint : BvhJoint, frame_index : Int) -> Array[Double]

#
frame_values_for_joint_name

fn frame_values_for_joint_name(document : BvhDocument, name : String, frame_index : Int) -> Array[Double]

#
frame_window

fn frame_window(document : BvhDocument, start_frame : Int, end_frame : Int) -> BvhFrameWindow

#
has_joint

fn has_joint(document : BvhDocument, name : String) -> Bool

#
import_decision_to_json

fn import_decision_to_json(decision : BvhImportDecision) -> String

#
import_decision_to_text

fn import_decision_to_text(decision : BvhImportDecision) -> String

#
import_decisions_to_csv

fn import_decisions_to_csv(decisions : Array[BvhImportDecision]) -> String

#
import_profile_by_name

fn import_profile_by_name(name : String) -> BvhImportProfile

#
import_profile_issues

fn import_profile_issues(document : BvhDocument, profile : BvhImportProfile) -> Array[BvhValidationIssue]

#
import_profile_to_json

fn import_profile_to_json(profile : BvhImportProfile) -> String

#
import_profiles_to_csv

fn import_profiles_to_csv(profiles : Array[BvhImportProfile]) -> String

#
joint_channel_names

fn joint_channel_names(joint : BvhJoint) -> Array[String]

#
joint_names

fn joint_names(document : BvhDocument) -> Array[String]

#
joint_paths

fn joint_paths(document : BvhDocument) -> Array[String]

#
joint_rotation_at

fn joint_rotation_at(document : BvhDocument, joint : BvhJoint, frame_index : Int) -> BvhVec3

#
joint_table_csv

fn joint_table_csv(document : BvhDocument) -> String

#
joint_to_json

fn joint_to_json(joint : BvhJoint) -> String

#
last_frame

fn last_frame(document : BvhDocument) -> Array[Double]

#
leaf_joint_paths

fn leaf_joint_paths(document : BvhDocument) -> Array[String]

#
loop_closure_error

fn loop_closure_error(document : BvhDocument) -> Double

#
manifest_to_json

fn manifest_to_json(manifest : BvhRuntimeManifest) -> String

#
manifest_to_text

fn manifest_to_text(manifest : BvhRuntimeManifest) -> String

#
max_joint_depth

fn max_joint_depth(joint : BvhJoint) -> Int

#
max_root_speed

fn max_root_speed(document : BvhDocument) -> Double

#
motion_channel_means

fn motion_channel_means(document : BvhDocument) -> Array[BvhChannelMean]

#
nearest_frame_index_at_time

fn nearest_frame_index_at_time(document : BvhDocument, seconds : Double) -> Int

#
normalize_root_origin

fn normalize_root_origin(document : BvhDocument) -> BvhDocument

#
parse_bvh

fn parse_bvh(input : String) -> BvhParseResult

Parse ASCII BVH source into hierarchy and motion data.

#
parse_bvh_or_empty

fn parse_bvh_or_empty(input : String) -> BvhDocument

#
preview_import_profile

fn preview_import_profile() -> BvhImportProfile

#
quality_action_for_bvh

fn quality_action_for_bvh(input : String) -> String

#
quality_report

fn quality_report(document : BvhDocument) -> BvhQualityReport

#
quality_report_from_bvh

fn quality_report_from_bvh(input : String) -> BvhQualityReport

#
quality_report_to_csv

fn quality_report_to_csv(report : BvhQualityReport) -> String

#
quality_report_to_json

fn quality_report_to_json(report : BvhQualityReport) -> String

#
quality_report_to_text

fn quality_report_to_text(report : BvhQualityReport) -> String

#
quality_signal_to_json

fn quality_signal_to_json(signal : BvhQualitySignal) -> String

#
report_to_csv

fn report_to_csv(report : BvhReport) -> String

#
report_to_json

fn report_to_json(report : BvhReport) -> String

#
report_to_text

fn report_to_text(report : BvhReport) -> String

#
retarget_map_to_csv

fn retarget_map_to_csv(entries : Array[BvhRetargetMapEntry]) -> String

#
root_motion_csv

fn root_motion_csv(document : BvhDocument) -> String

#
root_motion_delta

fn root_motion_delta(document : BvhDocument) -> BvhVec3

#
root_motion_distance

fn root_motion_distance(document : BvhDocument) -> Double

#
root_position_at

fn root_position_at(document : BvhDocument, frame_index : Int) -> BvhVec3

#
root_speed_samples

fn root_speed_samples(document : BvhDocument) -> Array[BvhSpeedSample]

#
sample_root_motion

fn sample_root_motion(document : BvhDocument, max_samples? : Int) -> Array[BvhPoseSample]

#
skeleton_bones

fn skeleton_bones(document : BvhDocument) -> Array[BvhSkeletonBone]

#
skeleton_bones_csv

fn skeleton_bones_csv(document : BvhDocument) -> String

#
skeleton_diff_to_json

fn skeleton_diff_to_json(diff : BvhSkeletonDiff) -> String

#
skeleton_signature

fn skeleton_signature(document : BvhDocument) -> String

#
skeleton_summary_to_json

fn skeleton_summary_to_json(summary : BvhSkeletonSummary) -> String

#
slice_document

fn slice_document(document : BvhDocument, start_frame : Int, end_frame : Int) -> BvhDocument

#
slice_motion

fn slice_motion(motion : BvhMotion, start_frame : Int, end_frame : Int) -> BvhMotion

#
speed_samples_to_csv

fn speed_samples_to_csv(samples : Array[BvhSpeedSample]) -> String

#
stats_to_json

fn stats_to_json(stats : BvhStats) -> String

#
strict_ci_import_profile

fn strict_ci_import_profile() -> BvhImportProfile

#
summarize_skeleton

fn summarize_skeleton(document : BvhDocument) -> BvhSkeletonSummary

#
tokenize_bvh

fn tokenize_bvh(input : String) -> BvhTokenizeResult

Split ASCII BVH source into words and braces while preserving token position.

#
unity_clip_plan_to_json

fn unity_clip_plan_to_json(plan : BvhUnityClipPlan) -> String

#
unity_import_profile

fn unity_import_profile() -> BvhImportProfile

#
validate_bvh

fn validate_bvh(input : String) -> BvhValidationReport

#
validate_document

fn validate_document(document : BvhDocument) -> BvhValidationReport

#
validation_summary

fn validation_summary(report : BvhValidationReport) -> String

#
validation_to_json

fn validation_to_json(report : BvhValidationReport) -> String

#
vec3_to_json

fn vec3_to_json(vec : BvhVec3) -> String

#
widest_channel_range

fn widest_channel_range(document : BvhDocument) -> BvhChannelRange?