///|
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.Debug)
///|
pub fn build_unity_clip_plan(
document : BvhDocument,
clip_name? : String = "clip",
) -> BvhUnityClipPlan {
let warnings : Array[String] = []
let frame_rate = if document.motion.frame_time > 0.0 {
1.0 / document.motion.frame_time
} else {
0.0
}
if contains_unknown_channels(document.root) {
warnings.push("unknown BVH channels should be remapped before import")
}
if document.root.position_channel_count() == 0 {
warnings.push(
"root has no position channels; root motion delta will be zero",
)
}
{
clip_name,
frame_rate,
duration_seconds: document.duration_seconds(),
root_joint: document.root.name,
joint_paths: joint_paths(document),
root_motion_delta: root_motion_delta(document),
warnings,
}
}
///|
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.Debug)
///|
pub fn build_blender_import_plan(
document : BvhDocument,
armature_name? : String = "Armature",
) -> BvhBlenderImportPlan {
let notes : Array[String] = [
"BVH offsets are preserved in file units", "rotation channel order is kept per joint",
"v1 does not bake coordinate-system conversion",
]
{
armature_name,
bone_count: document.joint_count(),
leaf_count: document.end_site_count(),
frame_start: 1,
frame_end: document.motion.frame_count,
fps: if document.motion.frame_time > 0.0 {
1.0 / document.motion.frame_time
} else {
0.0
},
preserve_root_motion: document.root.position_channel_count() > 0,
axis_notes: notes,
}
}
///|
pub fn unity_clip_plan_to_json(plan : BvhUnityClipPlan) -> String {
let paths : Array[String] = []
for path in plan.joint_paths {
paths.push(json_string(path))
}
let warnings : Array[String] = []
for warning in plan.warnings {
warnings.push(json_string(warning))
}
let result =
$|{"clipName":\{json_string(plan.clip_name)},"frameRate":\{plan.frame_rate},"durationSeconds":\{plan.duration_seconds},"rootJoint":\{json_string(plan.root_joint)},"jointPaths":[\{paths.join(",")}],"rootMotionDelta":\{vec3_to_json(plan.root_motion_delta)},"warnings":[\{warnings.join(",")}]}
result
}
///|
pub fn blender_import_plan_to_json(plan : BvhBlenderImportPlan) -> String {
let notes : Array[String] = []
for note in plan.axis_notes {
notes.push(json_string(note))
}
let result =
$|{"armatureName":\{json_string(plan.armature_name)},"boneCount":\{plan.bone_count},"leafCount":\{plan.leaf_count},"frameStart":\{plan.frame_start},"frameEnd":\{plan.frame_end},"fps":\{plan.fps},"preserveRootMotion":\{plan.preserve_root_motion},"axisNotes":[\{notes.join(",")}]}
result
}