Bvh.cs を分割

This commit is contained in:
ousttrue
2023-02-22 21:08:26 +09:00
parent dbe33c3c1e
commit 1bd8cc4e63
14 changed files with 272 additions and 210 deletions

View File

@@ -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);
}

View 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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 885c621c7dd0faf4e8e3de2e0187d2ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 588638a01ee0b7c47bd731aeed170cea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc2103bbe9c95224e9458e1fb058140f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using System;
namespace UniHumanoid
{
public class BvhException : Exception
{
public BvhException(string msg) : base(msg) { }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 86267a6edfc8fc749948c586e622846f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7f4ac3efd1faca94381a344a5be51cc2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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();
}
}

View File

@@ -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];

View File

@@ -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);
}