mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-13 14:04:29 -05:00
separate bvh from VrmAnimationExporter
This commit is contained in:
parent
16ff381cdc
commit
a4cfc4ebdb
|
|
@ -1,5 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UniGLTF;
|
||||
using UniHumanoid;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
|
|
@ -10,7 +15,7 @@ namespace UniVRM10
|
|||
var path = EditorUtility.OpenFilePanel("select bvh", null, "bvh");
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
var bytes = VrmAnimationExporter.BvhToVrmAnimation(path);
|
||||
var bytes = BvhToVrmAnimation(path);
|
||||
var dst = EditorUtility.SaveFilePanel("write vrma",
|
||||
Path.GetDirectoryName(path),
|
||||
Path.GetFileNameWithoutExtension(path),
|
||||
|
|
@ -21,5 +26,87 @@ namespace UniVRM10
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Transform GetParentBone(Dictionary<HumanBodyBones, Transform> map, Vrm10HumanoidBones bone)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (bone == Vrm10HumanoidBones.Hips)
|
||||
{
|
||||
break;
|
||||
}
|
||||
var parentBone = Vrm10HumanoidBoneSpecification.GetDefine(bone).ParentBone.Value;
|
||||
var unityParentBone = Vrm10HumanoidBoneSpecification.ConvertToUnityBone(parentBone);
|
||||
if (map.TryGetValue(unityParentBone, out var found))
|
||||
{
|
||||
return found;
|
||||
}
|
||||
bone = parentBone;
|
||||
}
|
||||
|
||||
// hips has no parent
|
||||
return null;
|
||||
}
|
||||
|
||||
static byte[] BvhToVrmAnimation(string path)
|
||||
{
|
||||
var bvh = new BvhImporterContext();
|
||||
bvh.Parse(path, File.ReadAllText(path));
|
||||
bvh.Load();
|
||||
|
||||
var data = new ExportingGltfData();
|
||||
using var exporter = new VrmAnimationExporter(
|
||||
data, new GltfExportSettings());
|
||||
exporter.Prepare(bvh.Root.gameObject);
|
||||
|
||||
exporter.Export((VrmAnimationExporter vrma) =>
|
||||
{
|
||||
//
|
||||
// setup
|
||||
//
|
||||
var map = new Dictionary<HumanBodyBones, Transform>();
|
||||
var animator = bvh.Root.GetComponent<Animator>();
|
||||
foreach (HumanBodyBones bone in Enum.GetValues(typeof(HumanBodyBones)))
|
||||
{
|
||||
if (bone == HumanBodyBones.LastBone)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var t = animator.GetBoneTransform(bone);
|
||||
if (t == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
map.Add(bone, t);
|
||||
}
|
||||
|
||||
vrma.SetPositionBoneAndParent(map[HumanBodyBones.Hips], bvh.Root.transform);
|
||||
|
||||
foreach (var kv in map)
|
||||
{
|
||||
var vrmBone = Vrm10HumanoidBoneSpecification.ConvertFromUnityBone(kv.Key);
|
||||
var parent = GetParentBone(map, vrmBone) ?? bvh.Root.transform;
|
||||
vrma.AddRotationBoneAndParent(kv.Key, kv.Value, parent);
|
||||
}
|
||||
|
||||
//
|
||||
// get data
|
||||
//
|
||||
var animation = bvh.Root.gameObject.GetComponent<Animation>();
|
||||
var clip = animation.clip;
|
||||
var state = animation[clip.name];
|
||||
|
||||
var time = default(TimeSpan);
|
||||
for (int i = 0; i < bvh.Bvh.FrameCount; ++i, time += bvh.Bvh.FrameTime)
|
||||
{
|
||||
state.time = (float)time.TotalSeconds;
|
||||
animation.Sample();
|
||||
vrma.AddFrame(time);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return data.ToGlbBytes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ namespace UniVRM10
|
|||
}
|
||||
}
|
||||
PositionExporter m_position;
|
||||
public void SetPositionBoneAndParent(Transform bone, Transform parent)
|
||||
{
|
||||
m_position = new PositionExporter(bone, parent);
|
||||
}
|
||||
|
||||
class RotationExporter
|
||||
{
|
||||
|
|
@ -62,29 +66,12 @@ namespace UniVRM10
|
|||
}
|
||||
}
|
||||
readonly Dictionary<HumanBodyBones, RotationExporter> m_rotations = new();
|
||||
|
||||
static Transform GetParentBone(Dictionary<HumanBodyBones, Transform> map, Vrm10HumanoidBones bone)
|
||||
public void AddRotationBoneAndParent(HumanBodyBones bone, Transform transform, Transform parent)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (bone == Vrm10HumanoidBones.Hips)
|
||||
{
|
||||
break;
|
||||
}
|
||||
var parentBone = Vrm10HumanoidBoneSpecification.GetDefine(bone).ParentBone.Value;
|
||||
var unityParentBone = Vrm10HumanoidBoneSpecification.ConvertToUnityBone(parentBone);
|
||||
if (map.TryGetValue(unityParentBone, out var found))
|
||||
{
|
||||
return found;
|
||||
}
|
||||
bone = parentBone;
|
||||
}
|
||||
|
||||
// hips has no parent
|
||||
return null;
|
||||
m_rotations.Add(bone, new RotationExporter(transform, parent));
|
||||
}
|
||||
|
||||
private void AddFrame(TimeSpan time)
|
||||
public void AddFrame(TimeSpan time)
|
||||
{
|
||||
m_times.Add((float)time.TotalSeconds);
|
||||
m_position.Add();
|
||||
|
|
@ -94,53 +81,11 @@ namespace UniVRM10
|
|||
}
|
||||
}
|
||||
|
||||
public void Export(BvhImporterContext bvh)
|
||||
public void Export(Action<VrmAnimationExporter> addFrames)
|
||||
{
|
||||
base.Export(new RuntimeTextureSerializer());
|
||||
|
||||
//
|
||||
// setup
|
||||
//
|
||||
var map = new Dictionary<HumanBodyBones, Transform>();
|
||||
var animator = bvh.Root.GetComponent<Animator>();
|
||||
foreach (HumanBodyBones bone in Enum.GetValues(typeof(HumanBodyBones)))
|
||||
{
|
||||
if (bone == HumanBodyBones.LastBone)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var t = animator.GetBoneTransform(bone);
|
||||
if (t == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
map.Add(bone, t);
|
||||
}
|
||||
|
||||
m_position = new PositionExporter(map[HumanBodyBones.Hips],
|
||||
bvh.Root.transform);
|
||||
|
||||
foreach (var kv in map)
|
||||
{
|
||||
var vrmBone = Vrm10HumanoidBoneSpecification.ConvertFromUnityBone(kv.Key);
|
||||
var parent = GetParentBone(map, vrmBone) ?? bvh.Root.transform;
|
||||
m_rotations.Add(kv.Key, new RotationExporter(kv.Value, parent));
|
||||
}
|
||||
|
||||
//
|
||||
// get data
|
||||
//
|
||||
var animation = bvh.Root.gameObject.GetComponent<Animation>();
|
||||
var clip = animation.clip;
|
||||
var state = animation[clip.name];
|
||||
|
||||
var time = default(TimeSpan);
|
||||
for (int i = 0; i < bvh.Bvh.FrameCount; ++i, time += bvh.Bvh.FrameTime)
|
||||
{
|
||||
state.time = (float)time.TotalSeconds;
|
||||
animation.Sample();
|
||||
AddFrame(time);
|
||||
}
|
||||
addFrames(this);
|
||||
|
||||
//
|
||||
// export
|
||||
|
|
@ -201,24 +146,10 @@ namespace UniVRM10
|
|||
}
|
||||
|
||||
// VRMC_vrm_animation
|
||||
var vrmAnimation = VrmAnimationUtil.Create(map, names);
|
||||
var vrmAnimation = VrmAnimationUtil.Create(m_rotations.ToDictionary(kv => kv.Key, kv => kv.Value.Node), names);
|
||||
UniGLTF.Extensions.VRMC_vrm_animation.GltfSerializer.SerializeTo(
|
||||
ref _data.Gltf.extensions
|
||||
, vrmAnimation);
|
||||
}
|
||||
|
||||
public static byte[] BvhToVrmAnimation(string path)
|
||||
{
|
||||
var bvh = new BvhImporterContext();
|
||||
bvh.Parse(path, File.ReadAllText(path));
|
||||
bvh.Load();
|
||||
|
||||
var data = new ExportingGltfData();
|
||||
using var exporter = new VrmAnimationExporter(
|
||||
data, new GltfExportSettings());
|
||||
exporter.Prepare(bvh.Root.gameObject);
|
||||
exporter.Export(bvh);
|
||||
return data.ToGlbBytes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user