mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-24 11:35:24 -05:00
Bvh.cs を分割
This commit is contained in:
@@ -6,190 +6,6 @@ using System.Linq;
|
||||
|
||||
namespace UniHumanoid
|
||||
{
|
||||
public class BvhException : Exception
|
||||
{
|
||||
public BvhException(string msg) : base(msg) { }
|
||||
}
|
||||
|
||||
public enum Channel
|
||||
{
|
||||
Xposition,
|
||||
Yposition,
|
||||
Zposition,
|
||||
Xrotation,
|
||||
Yrotation,
|
||||
Zrotation,
|
||||
}
|
||||
public static class ChannelExtensions
|
||||
{
|
||||
public static string ToProperty(this Channel ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case Channel.Xposition: return "localPosition.x";
|
||||
case Channel.Yposition: return "localPosition.y";
|
||||
case Channel.Zposition: return "localPosition.z";
|
||||
case Channel.Xrotation: return "localEulerAnglesBaked.x";
|
||||
case Channel.Yrotation: return "localEulerAnglesBaked.y";
|
||||
case Channel.Zrotation: return "localEulerAnglesBaked.z";
|
||||
}
|
||||
|
||||
throw new BvhException("no property for " + ch);
|
||||
}
|
||||
|
||||
public static bool IsLocation(this Channel ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case Channel.Xposition:
|
||||
case Channel.Yposition:
|
||||
case Channel.Zposition: return true;
|
||||
case Channel.Xrotation:
|
||||
case Channel.Yrotation:
|
||||
case Channel.Zrotation: return false;
|
||||
}
|
||||
|
||||
throw new BvhException("no property for " + ch);
|
||||
}
|
||||
}
|
||||
|
||||
public struct Single3
|
||||
{
|
||||
public Single x;
|
||||
public Single y;
|
||||
public Single z;
|
||||
|
||||
public Single3(Single _x, Single _y, Single _z)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
}
|
||||
}
|
||||
|
||||
public class BvhNode
|
||||
{
|
||||
public String Name
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Single3 Offset
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Channel[] Channels
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public List<BvhNode> Children
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public BvhNode(string name)
|
||||
{
|
||||
Name = name;
|
||||
Children = new List<BvhNode>();
|
||||
}
|
||||
|
||||
public int GetChannelIndex(Channel channel)
|
||||
{
|
||||
for (int i = 0; i < Channels.Length; ++i)
|
||||
{
|
||||
if (channel == Channels[i])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
|
||||
public virtual void Parse(StringReader r)
|
||||
{
|
||||
Offset = ParseOffset(r.ReadLine());
|
||||
|
||||
Channels = ParseChannel(r.ReadLine());
|
||||
}
|
||||
|
||||
static Single3 ParseOffset(string line)
|
||||
{
|
||||
var split = line.Trim().Split();
|
||||
if (split[0] != "OFFSET")
|
||||
{
|
||||
throw new BvhException("OFFSET is not found");
|
||||
}
|
||||
|
||||
var offset = split.Skip(1).Where(x => !string.IsNullOrEmpty(x)).Select(x => float.Parse(x, System.Globalization.CultureInfo.InvariantCulture)).ToArray();
|
||||
return new Single3(offset[0], offset[1], offset[2]);
|
||||
}
|
||||
|
||||
static Channel[] ParseChannel(string line)
|
||||
{
|
||||
var split = line.Trim().Split();
|
||||
if (split[0] != "CHANNELS")
|
||||
{
|
||||
throw new BvhException("CHANNELS is not found");
|
||||
}
|
||||
var count = int.Parse(split[1]);
|
||||
if (count + 2 != split.Length)
|
||||
{
|
||||
throw new BvhException("channel count is not match with split count");
|
||||
}
|
||||
return split.Skip(2).Select(x => (Channel)Enum.Parse(typeof(Channel), x)).ToArray();
|
||||
}
|
||||
|
||||
public IEnumerable<BvhNode> Traverse()
|
||||
{
|
||||
yield return this;
|
||||
|
||||
foreach (var child in Children)
|
||||
{
|
||||
foreach (var descendant in child.Traverse())
|
||||
{
|
||||
yield return descendant;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EndSite : BvhNode
|
||||
{
|
||||
public EndSite() : base("")
|
||||
{
|
||||
}
|
||||
|
||||
public override void Parse(StringReader r)
|
||||
{
|
||||
r.ReadLine(); // offset
|
||||
}
|
||||
}
|
||||
|
||||
public class ChannelCurve
|
||||
{
|
||||
public float[] Keys
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public ChannelCurve(int frameCount)
|
||||
{
|
||||
Keys = new float[frameCount];
|
||||
}
|
||||
|
||||
public void SetKey(int frame, float value)
|
||||
{
|
||||
Keys[frame] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public class Bvh
|
||||
{
|
||||
public BvhNode Root
|
||||
@@ -204,7 +20,7 @@ namespace UniHumanoid
|
||||
private set;
|
||||
}
|
||||
|
||||
public ChannelCurve[] Channels
|
||||
public BvhChannelCurve[] Channels
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
@@ -223,7 +39,7 @@ namespace UniHumanoid
|
||||
public bool IsLocation;
|
||||
}
|
||||
|
||||
public bool TryGetPathWithPropertyFromChannel(ChannelCurve channel, out PathWithProperty pathWithProp)
|
||||
public bool TryGetPathWithPropertyFromChannel(BvhChannelCurve channel, out PathWithProperty pathWithProp)
|
||||
{
|
||||
var index = Channels.ToList().IndexOf(channel);
|
||||
if (index == -1)
|
||||
@@ -282,7 +98,7 @@ namespace UniHumanoid
|
||||
return null;
|
||||
}
|
||||
|
||||
public ChannelCurve GetChannel(BvhNode target, Channel channel)
|
||||
public BvhChannelCurve GetChannel(BvhNode target, BvhChannel channel)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var node in Root.Traverse())
|
||||
@@ -318,7 +134,7 @@ namespace UniHumanoid
|
||||
.Select(x => x.Channels.Length)
|
||||
.Sum();
|
||||
Channels = Enumerable.Range(0, channelCount)
|
||||
.Select(x => new ChannelCurve(frames))
|
||||
.Select(x => new BvhChannelCurve(frames))
|
||||
.ToArray()
|
||||
;
|
||||
}
|
||||
@@ -422,7 +238,7 @@ namespace UniHumanoid
|
||||
{
|
||||
throw new BvhException("End in level 0");
|
||||
}
|
||||
node = new EndSite();
|
||||
node = new BvhEndSite();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -445,7 +261,7 @@ namespace UniHumanoid
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(child is EndSite))
|
||||
if (!(child is BvhEndSite))
|
||||
{
|
||||
node.Children.Add(child);
|
||||
}
|
||||
|
||||
45
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhChannel.cs
Normal file
45
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhChannel.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
namespace UniHumanoid
|
||||
{
|
||||
public enum BvhChannel
|
||||
{
|
||||
Xposition,
|
||||
Yposition,
|
||||
Zposition,
|
||||
Xrotation,
|
||||
Yrotation,
|
||||
Zrotation,
|
||||
}
|
||||
|
||||
public static class BvhChannelExtensions
|
||||
{
|
||||
public static string ToProperty(this BvhChannel ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case BvhChannel.Xposition: return "localPosition.x";
|
||||
case BvhChannel.Yposition: return "localPosition.y";
|
||||
case BvhChannel.Zposition: return "localPosition.z";
|
||||
case BvhChannel.Xrotation: return "localEulerAnglesBaked.x";
|
||||
case BvhChannel.Yrotation: return "localEulerAnglesBaked.y";
|
||||
case BvhChannel.Zrotation: return "localEulerAnglesBaked.z";
|
||||
}
|
||||
|
||||
throw new BvhException("no property for " + ch);
|
||||
}
|
||||
|
||||
public static bool IsLocation(this BvhChannel ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case BvhChannel.Xposition:
|
||||
case BvhChannel.Yposition:
|
||||
case BvhChannel.Zposition: return true;
|
||||
case BvhChannel.Xrotation:
|
||||
case BvhChannel.Yrotation:
|
||||
case BvhChannel.Zrotation: return false;
|
||||
}
|
||||
|
||||
throw new BvhException("no property for " + ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhChannel.cs.meta
Normal file
11
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhChannel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 885c621c7dd0faf4e8e3de2e0187d2ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
21
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhChannelCurve.cs
Normal file
21
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhChannelCurve.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace UniHumanoid
|
||||
{
|
||||
public class BvhChannelCurve
|
||||
{
|
||||
public float[] Keys
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public BvhChannelCurve(int frameCount)
|
||||
{
|
||||
Keys = new float[frameCount];
|
||||
}
|
||||
|
||||
public void SetKey(int frame, float value)
|
||||
{
|
||||
Keys[frame] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 588638a01ee0b7c47bd731aeed170cea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhEndSite.cs
Normal file
16
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhEndSite.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.IO;
|
||||
|
||||
namespace UniHumanoid
|
||||
{
|
||||
public class BvhEndSite : BvhNode
|
||||
{
|
||||
public BvhEndSite() : base("")
|
||||
{
|
||||
}
|
||||
|
||||
public override void Parse(StringReader r)
|
||||
{
|
||||
r.ReadLine(); // offset
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhEndSite.cs.meta
Normal file
11
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhEndSite.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc2103bbe9c95224e9458e1fb058140f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace UniHumanoid
|
||||
{
|
||||
public class BvhException : Exception
|
||||
{
|
||||
public BvhException(string msg) : base(msg) { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86267a6edfc8fc749948c586e622846f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
100
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhNode.cs
Normal file
100
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhNode.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniHumanoid
|
||||
{
|
||||
public class BvhNode
|
||||
{
|
||||
public String Name
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Vector3 Offset
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public BvhChannel[] Channels
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public List<BvhNode> Children
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public BvhNode(string name)
|
||||
{
|
||||
Name = name;
|
||||
Children = new List<BvhNode>();
|
||||
}
|
||||
|
||||
public int GetChannelIndex(BvhChannel channel)
|
||||
{
|
||||
for (int i = 0; i < Channels.Length; ++i)
|
||||
{
|
||||
if (channel == Channels[i])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
|
||||
public virtual void Parse(StringReader r)
|
||||
{
|
||||
Offset = ParseOffset(r.ReadLine());
|
||||
|
||||
Channels = ParseChannel(r.ReadLine());
|
||||
}
|
||||
|
||||
private static Vector3 ParseOffset(string line)
|
||||
{
|
||||
string[] split = line.Trim().Split();
|
||||
if (split[0] != "OFFSET")
|
||||
{
|
||||
throw new BvhException("OFFSET is not found");
|
||||
}
|
||||
|
||||
var offset = split.Skip(1).Where(x => !string.IsNullOrEmpty(x)).Select(x => float.Parse(x, System.Globalization.CultureInfo.InvariantCulture)).ToArray();
|
||||
return new Vector3(offset[0], offset[1], offset[2]);
|
||||
}
|
||||
|
||||
private static BvhChannel[] ParseChannel(string line)
|
||||
{
|
||||
var split = line.Trim().Split();
|
||||
if (split[0] != "CHANNELS")
|
||||
{
|
||||
throw new BvhException("CHANNELS is not found");
|
||||
}
|
||||
var count = int.Parse(split[1]);
|
||||
if (count + 2 != split.Length)
|
||||
{
|
||||
throw new BvhException("channel count is not match with split count");
|
||||
}
|
||||
return split.Skip(2).Select(x => (BvhChannel)Enum.Parse(typeof(BvhChannel), x)).ToArray();
|
||||
}
|
||||
|
||||
public IEnumerable<BvhNode> Traverse()
|
||||
{
|
||||
yield return this;
|
||||
|
||||
foreach (var child in Children)
|
||||
{
|
||||
foreach (var descendant in child.Traverse())
|
||||
{
|
||||
yield return descendant;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhNode.cs.meta
Normal file
11
Assets/UniGLTF/Runtime/UniHumanoid/Format/BvhNode.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f4ac3efd1faca94381a344a5be51cc2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -16,9 +16,9 @@ namespace UniHumanoid
|
||||
Node = node;
|
||||
}
|
||||
|
||||
public ChannelCurve PositionX;
|
||||
public ChannelCurve PositionY;
|
||||
public ChannelCurve PositionZ;
|
||||
public BvhChannelCurve PositionX;
|
||||
public BvhChannelCurve PositionY;
|
||||
public BvhChannelCurve PositionZ;
|
||||
public Vector3 GetPosition(int i)
|
||||
{
|
||||
return new Vector3(
|
||||
@@ -27,9 +27,9 @@ namespace UniHumanoid
|
||||
PositionZ.Keys[i]);
|
||||
}
|
||||
|
||||
public ChannelCurve RotationX;
|
||||
public ChannelCurve RotationY;
|
||||
public ChannelCurve RotationZ;
|
||||
public BvhChannelCurve RotationX;
|
||||
public BvhChannelCurve RotationY;
|
||||
public BvhChannelCurve RotationZ;
|
||||
public Quaternion GetRotation(int i)
|
||||
{
|
||||
if (EulerToRotation == null)
|
||||
@@ -43,7 +43,7 @@ namespace UniHumanoid
|
||||
);
|
||||
}
|
||||
|
||||
static void AddCurve(Bvh bvh, AnimationClip clip, ChannelCurve ch, float scaling)
|
||||
static void AddCurve(Bvh bvh, AnimationClip clip, BvhChannelCurve ch, float scaling)
|
||||
{
|
||||
if (ch == null) return;
|
||||
var pathWithProp = default(Bvh.PathWithProperty);
|
||||
@@ -106,12 +106,12 @@ namespace UniHumanoid
|
||||
var curve = bvh.Channels[j];
|
||||
switch (node.Channels[i])
|
||||
{
|
||||
case Channel.Xposition: set.PositionX = curve; break;
|
||||
case Channel.Yposition: set.PositionY = curve; break;
|
||||
case Channel.Zposition: set.PositionZ = curve; break;
|
||||
case Channel.Xrotation: set.RotationX = curve; break;
|
||||
case Channel.Yrotation: set.RotationY = curve; break;
|
||||
case Channel.Zrotation: set.RotationZ = curve; break;
|
||||
case BvhChannel.Xposition: set.PositionX = curve; break;
|
||||
case BvhChannel.Yposition: set.PositionY = curve; break;
|
||||
case BvhChannel.Zposition: set.PositionZ = curve; break;
|
||||
case BvhChannel.Xrotation: set.RotationX = curve; break;
|
||||
case BvhChannel.Yrotation: set.RotationY = curve; break;
|
||||
case BvhChannel.Zrotation: set.RotationZ = curve; break;
|
||||
default: throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace UniHumanoid
|
||||
//
|
||||
// scaling. reposition
|
||||
//
|
||||
var yCh = Bvh.Root.GetChannelIndex(Channel.Yposition);
|
||||
var yCh = Bvh.Root.GetChannelIndex(BvhChannel.Yposition);
|
||||
var curve = Bvh.Channels[yCh];
|
||||
var hipHeight = curve.Keys[0];
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace UniHumanoid
|
||||
{
|
||||
public static Func<float, float, float, Quaternion> GetEulerToRotation(this BvhNode bvh)
|
||||
{
|
||||
var order = bvh.Channels.Where(x => x == Channel.Xrotation || x == Channel.Yrotation || x == Channel.Zrotation).ToArray();
|
||||
var order = bvh.Channels.Where(x => x == BvhChannel.Xrotation || x == BvhChannel.Yrotation || x == BvhChannel.Zrotation).ToArray();
|
||||
|
||||
return (x, y, z) =>
|
||||
{
|
||||
@@ -22,9 +22,9 @@ namespace UniHumanoid
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case Channel.Xrotation: r = r * xRot; break;
|
||||
case Channel.Yrotation: r = r * yRot; break;
|
||||
case Channel.Zrotation: r = r * zRot; break;
|
||||
case BvhChannel.Xrotation: r = r * xRot; break;
|
||||
case BvhChannel.Yrotation: r = r * yRot; break;
|
||||
case BvhChannel.Zrotation: r = r * zRot; break;
|
||||
default: throw new BvhException("no rotation");
|
||||
}
|
||||
}
|
||||
@@ -32,12 +32,12 @@ namespace UniHumanoid
|
||||
};
|
||||
}
|
||||
|
||||
public static Vector3 ToVector3(this Single3 s3)
|
||||
public static Vector3 ToVector3(this Vector3 s3)
|
||||
{
|
||||
return new Vector3(s3.x, s3.y, s3.z);
|
||||
}
|
||||
|
||||
public static Vector3 ToXReversedVector3(this Single3 s3)
|
||||
public static Vector3 ToXReversedVector3(this Vector3 s3)
|
||||
{
|
||||
return new Vector3(-s3.x, s3.y, s3.z);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user