mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-14 23:10:46 -05:00
Merge pull request #2000 from ousttrue/feature/experimental_vrm_animation
[experimental][vrm-animation] vrm animation の試験実装
This commit is contained in:
@@ -75,6 +75,57 @@ namespace UniHumanoid
|
||||
}
|
||||
}
|
||||
|
||||
class UniqueName
|
||||
{
|
||||
HashSet<string> m_uniqueNameSet = new HashSet<string>();
|
||||
int m_counter = 1;
|
||||
|
||||
public void ForceUniqueName(Transform t)
|
||||
{
|
||||
if (!m_uniqueNameSet.Contains(t.name))
|
||||
{
|
||||
m_uniqueNameSet.Add(t.name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.parent != null && t.childCount == 0)
|
||||
{
|
||||
/// AvatarBuilder:BuildHumanAvatar で同名の Transform があるとエラーになる。
|
||||
///
|
||||
/// AvatarBuilder 'GLTF': Ambiguous Transform '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/neck_1/neck_2/head/ENDSITE' and '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/l_shoulder/l_up_arm/l_low_arm/l_hand/ENDSITE' found in hierarchy for human bone 'Head'. Transform name mapped to a human bone must be unique.
|
||||
/// UnityEngine.AvatarBuilder:BuildHumanAvatar (UnityEngine.GameObject,UnityEngine.HumanDescription)
|
||||
/// UniHumanoid.AvatarDescription:CreateAvatar (UnityEngine.Transform)
|
||||
///
|
||||
/// 主に BVH の EndSite 由来の GameObject 名が重複することへの対策
|
||||
/// ex: parent-ENDSITE
|
||||
var newName = $"{t.parent.name}-{t.name}";
|
||||
if (!m_uniqueNameSet.Contains(newName))
|
||||
{
|
||||
Debug.LogWarning($"force rename: {t.name} => {newName}");
|
||||
t.name = newName;
|
||||
m_uniqueNameSet.Add(newName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 連番
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
// ex: name.1
|
||||
var newName = $"{t.name}{m_counter++}";
|
||||
if (!m_uniqueNameSet.Contains(newName))
|
||||
{
|
||||
Debug.LogWarning($"force rename: {t.name} => {newName}");
|
||||
t.name = newName;
|
||||
m_uniqueNameSet.Add(newName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class AvatarDescription : ScriptableObject
|
||||
{
|
||||
@@ -125,6 +176,14 @@ namespace UniHumanoid
|
||||
|
||||
public Avatar CreateAvatar(Transform root)
|
||||
{
|
||||
// force unique name
|
||||
var uniqueName = new UniqueName();
|
||||
var transforms = root.GetComponentsInChildren<Transform>();
|
||||
foreach (var t in transforms)
|
||||
{
|
||||
uniqueName.ForceUniqueName(t);
|
||||
}
|
||||
|
||||
return AvatarBuilder.BuildHumanAvatar(root.gameObject, ToHumanDescription(root));
|
||||
}
|
||||
|
||||
|
||||
@@ -95,15 +95,6 @@ namespace UniHumanoid
|
||||
hips.position = new Vector3(0, scaledHeight, 0); // foot to ground
|
||||
}
|
||||
|
||||
//
|
||||
// avatar
|
||||
//
|
||||
Avatar = description.CreateAvatar(Root.transform);
|
||||
Avatar.name = "Avatar";
|
||||
AvatarDescription = description;
|
||||
var animator = Root.AddComponent<Animator>();
|
||||
animator.avatar = Avatar;
|
||||
|
||||
//
|
||||
// create AnimationClip
|
||||
//
|
||||
@@ -117,15 +108,14 @@ namespace UniHumanoid
|
||||
animation.clip = Animation;
|
||||
animation.Play();
|
||||
|
||||
var humanPoseTransfer = Root.AddComponent<HumanPoseTransfer>();
|
||||
humanPoseTransfer.Avatar = Avatar;
|
||||
|
||||
// create SkinnedMesh for bone visualize
|
||||
var renderer = SkeletonMeshUtility.CreateRenderer(animator);
|
||||
Material = new Material(Shader.Find("Standard"));
|
||||
renderer.sharedMaterial = Material;
|
||||
Mesh = renderer.sharedMesh;
|
||||
Mesh.name = "box-man";
|
||||
//
|
||||
// avatar
|
||||
//
|
||||
Avatar = description.CreateAvatar(Root.transform);
|
||||
Avatar.name = "Avatar";
|
||||
AvatarDescription = description;
|
||||
var animator = Root.AddComponent<Animator>();
|
||||
animator.avatar = Avatar;
|
||||
}
|
||||
|
||||
static Transform BuildHierarchy(Transform parent, BvhNode node, float toMeter)
|
||||
|
||||
@@ -8,75 +8,89 @@ namespace UniHumanoid
|
||||
{
|
||||
public static class SkeletonMeshUtility
|
||||
{
|
||||
readonly struct TSRBox
|
||||
{
|
||||
public readonly Vector3 T;
|
||||
public readonly Vector3 S;
|
||||
public readonly Quaternion R;
|
||||
public readonly Vector3 HeadPosition;
|
||||
|
||||
public TSRBox(
|
||||
Vector3 t,
|
||||
Vector3 s,
|
||||
Quaternion r,
|
||||
Vector3 head)
|
||||
{
|
||||
T = t;
|
||||
S = s;
|
||||
R = r;
|
||||
HeadPosition = head;
|
||||
}
|
||||
|
||||
public Matrix4x4 ToMatrix()
|
||||
{
|
||||
return Matrix4x4.Translate(HeadPosition)
|
||||
* Matrix4x4.Rotate(R) * Matrix4x4.Scale(S) * Matrix4x4.Translate(T);
|
||||
}
|
||||
}
|
||||
|
||||
class MeshBuilder
|
||||
{
|
||||
List<Vector3> m_positions = new List<Vector3>();
|
||||
List<int> m_indices = new List<int>();
|
||||
List<BoneWeight> m_boneWeights = new List<BoneWeight>();
|
||||
|
||||
public void AddBone(Vector3 head, Vector3 tail, int boneIndex, float xWidth, float zWidth)
|
||||
public void AddBone(Vector3 head, Vector3 tail, int boneIndex, float width, float height, Vector3 xAxis)
|
||||
{
|
||||
var dir = (tail - head).normalized;
|
||||
Vector3 xaxis;
|
||||
Vector3 zaxis;
|
||||
if (Vector3.Dot(dir, Vector3.forward) >= 1.0f - float.Epsilon)
|
||||
{
|
||||
xaxis = Vector3.right;
|
||||
zaxis = Vector3.down;
|
||||
}
|
||||
else
|
||||
{
|
||||
xaxis = Vector3.Cross(dir, Vector3.forward).normalized;
|
||||
zaxis = Vector3.forward;
|
||||
}
|
||||
AddBox((head+tail)*0.5f,
|
||||
xaxis*xWidth,
|
||||
(tail-head)*0.5f,
|
||||
zaxis*zWidth,
|
||||
boneIndex);
|
||||
var yAxis = (tail - head).normalized;
|
||||
var zAxis = Vector3.Cross(xAxis, yAxis);
|
||||
xAxis = Vector3.Cross(yAxis, zAxis);
|
||||
|
||||
AddBox(boneIndex, new TSRBox
|
||||
(
|
||||
new Vector3(0, 0.5f, 0),
|
||||
new Vector3(width, (tail - head).magnitude, height),
|
||||
new Matrix4x4(
|
||||
xAxis, yAxis, zAxis, new Vector4(0, 0, 0, 1)
|
||||
).rotation,
|
||||
head
|
||||
));
|
||||
}
|
||||
|
||||
void AddBox(Vector3 center, Vector3 xaxis, Vector3 yaxis, Vector3 zaxis, int boneIndex)
|
||||
// rotation * scale * beforeTranslation
|
||||
void AddBox(int boneIndex, TSRBox box)
|
||||
{
|
||||
AddQuad(
|
||||
center - yaxis - xaxis - zaxis,
|
||||
center - yaxis + xaxis - zaxis,
|
||||
center - yaxis + xaxis + zaxis,
|
||||
center - yaxis - xaxis + zaxis,
|
||||
boneIndex);
|
||||
AddQuad(
|
||||
center + yaxis - xaxis - zaxis,
|
||||
center + yaxis + xaxis - zaxis,
|
||||
center + yaxis + xaxis + zaxis,
|
||||
center + yaxis - xaxis + zaxis,
|
||||
boneIndex, true);
|
||||
AddQuad(
|
||||
center - xaxis - yaxis - zaxis,
|
||||
center - xaxis + yaxis - zaxis,
|
||||
center - xaxis + yaxis + zaxis,
|
||||
center - xaxis - yaxis + zaxis,
|
||||
boneIndex, true);
|
||||
AddQuad(
|
||||
center + xaxis - yaxis - zaxis,
|
||||
center + xaxis + yaxis - zaxis,
|
||||
center + xaxis + yaxis + zaxis,
|
||||
center + xaxis - yaxis + zaxis,
|
||||
boneIndex);
|
||||
AddQuad(
|
||||
center - zaxis - xaxis - yaxis,
|
||||
center - zaxis + xaxis - yaxis,
|
||||
center - zaxis + xaxis + yaxis,
|
||||
center - zaxis - xaxis + yaxis,
|
||||
boneIndex, true);
|
||||
AddQuad(
|
||||
center + zaxis - xaxis - yaxis,
|
||||
center + zaxis + xaxis - yaxis,
|
||||
center + zaxis + xaxis + yaxis,
|
||||
center + zaxis - xaxis + yaxis,
|
||||
boneIndex);
|
||||
var m = box.ToMatrix();
|
||||
|
||||
// v6+---+v7
|
||||
// v2/| v3|
|
||||
// +---+ |
|
||||
// | +v5-+v4
|
||||
// |/ |/
|
||||
// +---+
|
||||
// v1 v0
|
||||
var s = 0.5f;
|
||||
var cube = new Vector3[]
|
||||
{
|
||||
m.MultiplyPoint(new Vector3(+s, -s, -s)),
|
||||
m.MultiplyPoint(new Vector3(-s, -s, -s)),
|
||||
m.MultiplyPoint(new Vector3(-s, +s, -s)),
|
||||
m.MultiplyPoint(new Vector3(+s, +s, -s)),
|
||||
m.MultiplyPoint(new Vector3(+s, -s, +s)),
|
||||
m.MultiplyPoint(new Vector3(-s, -s, +s)),
|
||||
m.MultiplyPoint(new Vector3(-s, +s, +s)),
|
||||
m.MultiplyPoint(new Vector3(+s, +s, +s)),
|
||||
};
|
||||
|
||||
AddQuad(boneIndex, cube[0], cube[1], cube[2], cube[3]);
|
||||
AddQuad(boneIndex, cube[1], cube[5], cube[6], cube[2]);
|
||||
AddQuad(boneIndex, cube[5], cube[4], cube[7], cube[6]);
|
||||
AddQuad(boneIndex, cube[4], cube[0], cube[3], cube[7]);
|
||||
AddQuad(boneIndex, cube[3], cube[2], cube[6], cube[7]);
|
||||
AddQuad(boneIndex, cube[4], cube[5], cube[1], cube[0]);
|
||||
}
|
||||
|
||||
void AddQuad(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, int boneIndex, bool reverse=false)
|
||||
void AddQuad(int boneIndex, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3)
|
||||
{
|
||||
var i = m_positions.Count;
|
||||
m_positions.Add(v0);
|
||||
@@ -86,25 +100,14 @@ namespace UniHumanoid
|
||||
|
||||
var bw = new BoneWeight
|
||||
{
|
||||
boneIndex0=boneIndex,
|
||||
weight0=1.0f,
|
||||
boneIndex0 = boneIndex,
|
||||
weight0 = 1.0f,
|
||||
};
|
||||
m_boneWeights.Add(bw);
|
||||
m_boneWeights.Add(bw);
|
||||
m_boneWeights.Add(bw);
|
||||
m_boneWeights.Add(bw);
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
m_indices.Add(i + 3);
|
||||
m_indices.Add(i + 2);
|
||||
m_indices.Add(i + 1);
|
||||
|
||||
m_indices.Add(i + 1);
|
||||
m_indices.Add(i);
|
||||
m_indices.Add(i + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_indices.Add(i);
|
||||
m_indices.Add(i + 1);
|
||||
@@ -133,55 +136,59 @@ namespace UniHumanoid
|
||||
public HumanBodyBones Head;
|
||||
public HumanBodyBones Tail;
|
||||
public Vector3 TailOffset;
|
||||
public float XWidth;
|
||||
public float ZWidth;
|
||||
public float Width;
|
||||
public float Height;
|
||||
public Vector3 XAxis;
|
||||
|
||||
public BoneHeadTail(HumanBodyBones head, HumanBodyBones tail, float xWidth = 0.05f, float zWidth = 0.05f)
|
||||
public BoneHeadTail(HumanBodyBones head, HumanBodyBones tail, Vector3 xAxis, float width = 0.05f, float height = 0.05f)
|
||||
{
|
||||
Head = head;
|
||||
Tail = tail;
|
||||
TailOffset = Vector3.zero;
|
||||
XWidth = xWidth;
|
||||
ZWidth = zWidth;
|
||||
XAxis = xAxis;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public BoneHeadTail(HumanBodyBones head, Vector3 tailOffset, float xWidth = 0.05f, float zWidth = 0.05f)
|
||||
public BoneHeadTail(HumanBodyBones head, Vector3 tailOffset, Vector3 xAxis, float width = 0.05f, float height = 0.05f)
|
||||
{
|
||||
Head = head;
|
||||
Tail = HumanBodyBones.LastBone;
|
||||
TailOffset = tailOffset;
|
||||
XWidth = xWidth;
|
||||
ZWidth = zWidth;
|
||||
XAxis = xAxis;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
}
|
||||
|
||||
static BoneHeadTail[] Bones = new BoneHeadTail[]
|
||||
{
|
||||
new BoneHeadTail(HumanBodyBones.Hips, HumanBodyBones.Spine, 0.1f, 0.06f),
|
||||
new BoneHeadTail(HumanBodyBones.Spine, HumanBodyBones.Chest),
|
||||
new BoneHeadTail(HumanBodyBones.Chest, HumanBodyBones.Neck, 0.1f, 0.06f),
|
||||
new BoneHeadTail(HumanBodyBones.Neck, HumanBodyBones.Head, 0.03f, 0.03f),
|
||||
new BoneHeadTail(HumanBodyBones.Head, new Vector3(0, 0.1f, 0), 0.1f, 0.1f),
|
||||
new BoneHeadTail(HumanBodyBones.Hips, HumanBodyBones.Spine, Vector3.right, 0.2f, 0.12f),
|
||||
new BoneHeadTail(HumanBodyBones.Spine, HumanBodyBones.Chest, Vector3.right),
|
||||
new BoneHeadTail(HumanBodyBones.Chest, HumanBodyBones.Neck, Vector3.right, 0.2f, 0.12f),
|
||||
new BoneHeadTail(HumanBodyBones.Neck, HumanBodyBones.Head, Vector3.right, 0.06f, 0.06f),
|
||||
new BoneHeadTail(HumanBodyBones.Head, new Vector3(0, 0.1f, 0), Vector3.right, 0.2f, 0.2f),
|
||||
new BoneHeadTail(HumanBodyBones.Head, new Vector3(0, 0, 0.1f), Vector3.right, 0.2f, 0.2f),
|
||||
|
||||
new BoneHeadTail(HumanBodyBones.LeftShoulder, HumanBodyBones.LeftUpperArm),
|
||||
new BoneHeadTail(HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm),
|
||||
new BoneHeadTail(HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand),
|
||||
new BoneHeadTail(HumanBodyBones.LeftHand, new Vector3(-0.1f, 0, 0)),
|
||||
new BoneHeadTail(HumanBodyBones.LeftShoulder, HumanBodyBones.LeftUpperArm, Vector3.forward),
|
||||
new BoneHeadTail(HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, Vector3.forward),
|
||||
new BoneHeadTail(HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand, Vector3.forward),
|
||||
new BoneHeadTail(HumanBodyBones.LeftHand, new Vector3(-0.1f, 0, 0), Vector3.forward, 0.1f, 0.02f),
|
||||
|
||||
new BoneHeadTail(HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg),
|
||||
new BoneHeadTail(HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot),
|
||||
new BoneHeadTail(HumanBodyBones.LeftFoot, HumanBodyBones.LeftToes),
|
||||
new BoneHeadTail(HumanBodyBones.LeftToes, new Vector3(0, 0, 0.1f)),
|
||||
new BoneHeadTail(HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg, Vector3.left),
|
||||
new BoneHeadTail(HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot, Vector3.left),
|
||||
new BoneHeadTail(HumanBodyBones.LeftFoot, HumanBodyBones.LeftToes, Vector3.left),
|
||||
new BoneHeadTail(HumanBodyBones.LeftToes, new Vector3(0, 0, 0.03f), Vector3.left),
|
||||
|
||||
new BoneHeadTail(HumanBodyBones.RightShoulder, HumanBodyBones.RightUpperArm),
|
||||
new BoneHeadTail(HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm),
|
||||
new BoneHeadTail(HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand),
|
||||
new BoneHeadTail(HumanBodyBones.RightHand, new Vector3(0.1f, 0, 0)),
|
||||
new BoneHeadTail(HumanBodyBones.RightShoulder, HumanBodyBones.RightUpperArm, Vector3.back),
|
||||
new BoneHeadTail(HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, Vector3.back),
|
||||
new BoneHeadTail(HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand, Vector3.back),
|
||||
new BoneHeadTail(HumanBodyBones.RightHand, new Vector3(0.1f, 0, 0), Vector3.back, 0.1f, 0.02f),
|
||||
|
||||
new BoneHeadTail(HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg),
|
||||
new BoneHeadTail(HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot),
|
||||
new BoneHeadTail(HumanBodyBones.RightFoot, HumanBodyBones.RightToes),
|
||||
new BoneHeadTail(HumanBodyBones.RightToes, new Vector3(0, 0, 0.1f)),
|
||||
new BoneHeadTail(HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg, Vector3.left),
|
||||
new BoneHeadTail(HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot, Vector3.left),
|
||||
new BoneHeadTail(HumanBodyBones.RightFoot, HumanBodyBones.RightToes, Vector3.left),
|
||||
new BoneHeadTail(HumanBodyBones.RightToes, new Vector3(0, 0, 0.03f), Vector3.left),
|
||||
};
|
||||
|
||||
public static SkinnedMeshRenderer CreateRenderer(Animator animator)
|
||||
@@ -189,24 +196,24 @@ namespace UniHumanoid
|
||||
var bones = animator.transform.Traverse().ToList();
|
||||
|
||||
var builder = new MeshBuilder();
|
||||
foreach(var headTail in Bones)
|
||||
foreach (var headTail in Bones)
|
||||
{
|
||||
var head = animator.GetBoneTransform(headTail.Head);
|
||||
if (head!=null)
|
||||
if (head != null)
|
||||
{
|
||||
Transform tail = null;
|
||||
if(headTail.Tail!= HumanBodyBones.LastBone)
|
||||
if (headTail.Tail != HumanBodyBones.LastBone)
|
||||
{
|
||||
tail = animator.GetBoneTransform(headTail.Tail);
|
||||
}
|
||||
|
||||
if (tail != null)
|
||||
{
|
||||
builder.AddBone(head.position, tail.position, bones.IndexOf(head), headTail.XWidth, headTail.ZWidth);
|
||||
builder.AddBone(head.position, tail.position, bones.IndexOf(head), headTail.Width, headTail.Height, headTail.XAxis);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AddBone(head.position, head.position + headTail.TailOffset, bones.IndexOf(head), headTail.XWidth, headTail.ZWidth);
|
||||
builder.AddBone(head.position, head.position + headTail.TailOffset, bones.IndexOf(head), headTail.Width, headTail.Height, headTail.XAxis);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -217,8 +224,8 @@ namespace UniHumanoid
|
||||
|
||||
var mesh = builder.CreateMesh();
|
||||
mesh.name = "box-man";
|
||||
mesh.bindposes = bones.Select(x =>
|
||||
x.worldToLocalMatrix * animator.transform.localToWorldMatrix).ToArray();
|
||||
mesh.bindposes = bones.Select(x => x.worldToLocalMatrix * animator.transform.localToWorldMatrix).ToArray();
|
||||
|
||||
var renderer = animator.gameObject.AddComponent<SkinnedMeshRenderer>();
|
||||
renderer.bones = bones.ToArray();
|
||||
renderer.rootBone = animator.GetBoneTransform(HumanBodyBones.Hips);
|
||||
|
||||
@@ -73,6 +73,12 @@ namespace UniVRM10
|
||||
$"{SPEC_DIR}/VRMC_node_constraint-1.0/schema/VRMC_node_constraint.schema.json",
|
||||
"Assets/VRM10/Runtime/Format/Constraints"
|
||||
),
|
||||
|
||||
// VRMC_animation
|
||||
new GenerateInfo(
|
||||
$"{SPEC_DIR}/VRMC_vrm_animation-1.0/schema/VRMC_vrm_animation.schema.json",
|
||||
"Assets/VRM10/Runtime/Format/Animation"
|
||||
),
|
||||
};
|
||||
|
||||
foreach (var arg in args)
|
||||
|
||||
@@ -19,17 +19,19 @@ namespace UniVRM10
|
||||
Transform m_root;
|
||||
Transform m_hips;
|
||||
private readonly Dictionary<HumanBodyBones, BoneInitialRotation> m_bones = new Dictionary<HumanBodyBones, BoneInitialRotation>();
|
||||
private readonly Dictionary<HumanBodyBones, EuclideanTransform> m_worldMap = new Dictionary<HumanBodyBones, EuclideanTransform>();
|
||||
|
||||
public Vector3 HipTPoseWorldPosition => throw new System.NotImplementedException();
|
||||
|
||||
public InitRotationPoseProvider(Transform root, UniHumanoid.Humanoid humanoid)
|
||||
{
|
||||
m_root = root;
|
||||
m_hips = m_bones[HumanBodyBones.Hips].Transform;
|
||||
foreach (var (t, bone) in humanoid.BoneMap)
|
||||
{
|
||||
m_bones.Add(bone, new BoneInitialRotation(t));
|
||||
m_worldMap.Add(bone, new EuclideanTransform(root.localToWorldMatrix * t.localToWorldMatrix));
|
||||
}
|
||||
m_hips = m_bones[HumanBodyBones.Hips].Transform;
|
||||
}
|
||||
|
||||
Quaternion INormalizedPoseProvider.GetNormalizedLocalRotation(HumanBodyBones bone, HumanBodyBones parentBone)
|
||||
@@ -53,13 +55,20 @@ namespace UniVRM10
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
return m_root.worldToLocalMatrix.MultiplyPoint(m_hips.position);
|
||||
}
|
||||
}
|
||||
|
||||
EuclideanTransform? ITPoseProvider.GetWorldTransform(HumanBodyBones bone)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
if (m_worldMap.TryGetValue(bone, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
else
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
Assets/VRM10/Runtime/Format/Animation.meta
Normal file
8
Assets/VRM10/Runtime/Format/Animation.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d15d1d42c630e94faaf48208777a17a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
2504
Assets/VRM10/Runtime/Format/Animation/Deserializer.g.cs
Normal file
2504
Assets/VRM10/Runtime/Format/Animation/Deserializer.g.cs
Normal file
File diff suppressed because it is too large
Load Diff
11
Assets/VRM10/Runtime/Format/Animation/Deserializer.g.cs.meta
Normal file
11
Assets/VRM10/Runtime/Format/Animation/Deserializer.g.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4496eacf38a3897479cfb145617739ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
319
Assets/VRM10/Runtime/Format/Animation/Format.g.cs
Normal file
319
Assets/VRM10/Runtime/Format/Animation/Format.g.cs
Normal file
@@ -0,0 +1,319 @@
|
||||
// This file is generated from JsonSchema. Don't modify this source code.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace UniGLTF.Extensions.VRMC_vrm_animation
|
||||
{
|
||||
|
||||
public class HumanBone
|
||||
{
|
||||
// Dictionary object with extension-specific objects.
|
||||
public object Extensions;
|
||||
|
||||
// Application-specific data.
|
||||
public object Extras;
|
||||
|
||||
// Represents a single glTF node mapped to this humanBone.
|
||||
public int? Node;
|
||||
}
|
||||
|
||||
public class HumanBones
|
||||
{
|
||||
// Dictionary object with extension-specific objects.
|
||||
public object Extensions;
|
||||
|
||||
// Application-specific data.
|
||||
public object Extras;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone Hips;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone Spine;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone Chest;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone UpperChest;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone Neck;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone Head;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone Jaw;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftUpperLeg;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftLowerLeg;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftFoot;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftToes;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightUpperLeg;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightLowerLeg;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightFoot;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightToes;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftShoulder;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftUpperArm;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftLowerArm;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftHand;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightShoulder;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightUpperArm;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightLowerArm;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightHand;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftThumbMetacarpal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftThumbProximal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftThumbDistal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftIndexProximal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftIndexIntermediate;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftIndexDistal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftMiddleProximal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftMiddleIntermediate;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftMiddleDistal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftRingProximal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftRingIntermediate;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftRingDistal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftLittleProximal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftLittleIntermediate;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone LeftLittleDistal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightThumbMetacarpal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightThumbProximal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightThumbDistal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightIndexProximal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightIndexIntermediate;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightIndexDistal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightMiddleProximal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightMiddleIntermediate;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightMiddleDistal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightRingProximal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightRingIntermediate;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightRingDistal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightLittleProximal;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightLittleIntermediate;
|
||||
|
||||
// Represents a single bone of a Humanoid.
|
||||
public HumanBone RightLittleDistal;
|
||||
}
|
||||
|
||||
public class Humanoid
|
||||
{
|
||||
// Dictionary object with extension-specific objects.
|
||||
public object Extensions;
|
||||
|
||||
// Application-specific data.
|
||||
public object Extras;
|
||||
|
||||
// An object which maps humanoid bones to nodes.
|
||||
public HumanBones HumanBones;
|
||||
}
|
||||
|
||||
public class Expression
|
||||
{
|
||||
// Dictionary object with extension-specific objects.
|
||||
public object Extensions;
|
||||
|
||||
// Application-specific data.
|
||||
public object Extras;
|
||||
|
||||
// Represents a single glTF node mapped to this expression.
|
||||
public int? Node;
|
||||
}
|
||||
|
||||
public class Preset
|
||||
{
|
||||
// Represents a single expression.
|
||||
public Expression Happy;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Angry;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Sad;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Relaxed;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Surprised;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Aa;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Ih;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Ou;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Ee;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Oh;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Blink;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression BlinkLeft;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression BlinkRight;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression LookUp;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression LookDown;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression LookLeft;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression LookRight;
|
||||
|
||||
// Represents a single expression.
|
||||
public Expression Neutral;
|
||||
}
|
||||
|
||||
public class Expressions
|
||||
{
|
||||
// Dictionary object with extension-specific objects.
|
||||
public object Extensions;
|
||||
|
||||
// Application-specific data.
|
||||
public object Extras;
|
||||
|
||||
// An object that contains definitions of preset expressions.
|
||||
public Preset Preset;
|
||||
|
||||
// An object that contains definitions of custom expressions.
|
||||
public Dictionary<string, Expression> Custom;
|
||||
}
|
||||
|
||||
public class LookAt
|
||||
{
|
||||
// Dictionary object with extension-specific objects.
|
||||
public object Extensions;
|
||||
|
||||
// Application-specific data.
|
||||
public object Extras;
|
||||
|
||||
// Represents a single glTF node represents the eye gaze point.
|
||||
public int? Node;
|
||||
}
|
||||
|
||||
public class VRMC_vrm_animation
|
||||
{
|
||||
public const string ExtensionName = "VRMC_vrm_animation";
|
||||
|
||||
// Dictionary object with extension-specific objects.
|
||||
public object Extensions;
|
||||
|
||||
// Application-specific data.
|
||||
public object Extras;
|
||||
|
||||
// Specification version of VRMC_vrm_animation
|
||||
public string SpecVersion;
|
||||
|
||||
// An object which describes about humanoid bones.
|
||||
public Humanoid Humanoid;
|
||||
|
||||
// An object which maps expressions to nodes.
|
||||
public Expressions Expressions;
|
||||
|
||||
// An object which maps a eye gaze point to a node.
|
||||
public LookAt LookAt;
|
||||
}
|
||||
}
|
||||
11
Assets/VRM10/Runtime/Format/Animation/Format.g.cs.meta
Normal file
11
Assets/VRM10/Runtime/Format/Animation/Format.g.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f595db5658d457449b2fa63cfdc29c6d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
2194
Assets/VRM10/Runtime/Format/Animation/Serializer.g.cs
Normal file
2194
Assets/VRM10/Runtime/Format/Animation/Serializer.g.cs
Normal file
File diff suppressed because it is too large
Load Diff
11
Assets/VRM10/Runtime/Format/Animation/Serializer.g.cs.meta
Normal file
11
Assets/VRM10/Runtime/Format/Animation/Serializer.g.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1cc771337f6bbf4b932505a7847455a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -11,62 +11,217 @@ using VRMShaders;
|
||||
|
||||
namespace UniVRM10.VRM10Viewer
|
||||
{
|
||||
public class VRM10Motion
|
||||
public interface IMotion : IDisposable
|
||||
{
|
||||
public (INormalizedPoseProvider, ITPoseProvider) ControlRig;
|
||||
(INormalizedPoseProvider, ITPoseProvider) ControlRig { get; }
|
||||
void ShowBoxMan(bool enable);
|
||||
}
|
||||
|
||||
public class BvhMotion : IMotion
|
||||
{
|
||||
UniHumanoid.BvhImporterContext m_context;
|
||||
UniGLTF.RuntimeGltfInstance m_instance;
|
||||
|
||||
public Transform Root => m_context?.Root.transform;
|
||||
|
||||
public VRM10Motion(UniHumanoid.BvhImporterContext context)
|
||||
public SkinnedMeshRenderer m_boxMan;
|
||||
public SkinnedMeshRenderer BoxMan => m_boxMan;
|
||||
(INormalizedPoseProvider, ITPoseProvider) m_controlRig;
|
||||
(INormalizedPoseProvider, ITPoseProvider) IMotion.ControlRig => m_controlRig;
|
||||
public BvhMotion(UniHumanoid.BvhImporterContext context)
|
||||
{
|
||||
m_context = context;
|
||||
var provider = new AnimatorPoseProvider(m_context.Root.transform, m_context.Root.GetComponent<Animator>());
|
||||
ControlRig = (provider, provider);
|
||||
m_controlRig = (provider, provider);
|
||||
|
||||
// create SkinnedMesh for bone visualize
|
||||
var animator = m_context.Root.GetComponent<Animator>();
|
||||
m_boxMan = SkeletonMeshUtility.CreateRenderer(animator);
|
||||
var material = new Material(Shader.Find("Standard"));
|
||||
BoxMan.sharedMaterial = material;
|
||||
var mesh = BoxMan.sharedMesh;
|
||||
mesh.name = "box-man";
|
||||
}
|
||||
|
||||
public VRM10Motion(UniGLTF.RuntimeGltfInstance instance)
|
||||
public static BvhMotion LoadBvhFromText(string source, string path = "tmp.bvh")
|
||||
{
|
||||
var context = new UniHumanoid.BvhImporterContext();
|
||||
context.Parse(path, source);
|
||||
context.Load();
|
||||
return new BvhMotion(context);
|
||||
}
|
||||
public static BvhMotion LoadBvhFromPath(string path)
|
||||
{
|
||||
return LoadBvhFromText(File.ReadAllText(path), path);
|
||||
}
|
||||
|
||||
public void ShowBoxMan(bool enable)
|
||||
{
|
||||
m_boxMan.enabled = enable;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GameObject.Destroy(m_context.Root);
|
||||
}
|
||||
}
|
||||
|
||||
public class VrmAnimation : IMotion
|
||||
{
|
||||
UniGLTF.RuntimeGltfInstance m_instance;
|
||||
public SkinnedMeshRenderer m_boxMan;
|
||||
public SkinnedMeshRenderer BoxMan => m_boxMan;
|
||||
(INormalizedPoseProvider, ITPoseProvider) m_controlRig;
|
||||
(INormalizedPoseProvider, ITPoseProvider) IMotion.ControlRig => m_controlRig;
|
||||
public VrmAnimation(UniGLTF.RuntimeGltfInstance instance)
|
||||
{
|
||||
m_instance = instance;
|
||||
if (instance.GetComponent<Animation>() is Animation animation)
|
||||
{
|
||||
animation.Play();
|
||||
}
|
||||
|
||||
var humanoid = instance.gameObject.AddComponent<Humanoid>();
|
||||
humanoid.AssignBonesFromAnimator();
|
||||
|
||||
var provider = new InitRotationPoseProvider(instance.transform, humanoid);
|
||||
m_controlRig = (provider, provider);
|
||||
|
||||
// create SkinnedMesh for bone visualize
|
||||
var animator = instance.GetComponent<Animator>();
|
||||
m_boxMan = SkeletonMeshUtility.CreateRenderer(animator);
|
||||
var material = new Material(Shader.Find("Standard"));
|
||||
BoxMan.sharedMaterial = material;
|
||||
var mesh = BoxMan.sharedMesh;
|
||||
mesh.name = "box-man";
|
||||
}
|
||||
|
||||
public void ShowBoxMan(bool showBoxMan)
|
||||
public void ShowBoxMan(bool enable)
|
||||
{
|
||||
if (m_context != null)
|
||||
m_boxMan.enabled = enable;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GameObject.Destroy(m_boxMan.gameObject);
|
||||
}
|
||||
|
||||
static int? GetNodeIndex(UniGLTF.Extensions.VRMC_vrm_animation.Humanoid humanoid, HumanBodyBones bone)
|
||||
{
|
||||
switch (bone)
|
||||
{
|
||||
m_context.Root.GetComponent<SkinnedMeshRenderer>().enabled = showBoxMan;
|
||||
case HumanBodyBones.Hips: return humanoid.HumanBones.Hips?.Node;
|
||||
case HumanBodyBones.LeftUpperLeg: return humanoid.HumanBones.LeftUpperLeg?.Node;
|
||||
case HumanBodyBones.RightUpperLeg: return humanoid.HumanBones.RightUpperLeg?.Node;
|
||||
case HumanBodyBones.LeftLowerLeg: return humanoid.HumanBones.LeftLowerLeg?.Node;
|
||||
case HumanBodyBones.RightLowerLeg: return humanoid.HumanBones.RightLowerLeg?.Node;
|
||||
case HumanBodyBones.LeftFoot: return humanoid.HumanBones.LeftFoot?.Node;
|
||||
case HumanBodyBones.RightFoot: return humanoid.HumanBones.RightFoot?.Node;
|
||||
case HumanBodyBones.Spine: return humanoid.HumanBones.Spine?.Node;
|
||||
case HumanBodyBones.Chest: return humanoid.HumanBones.Chest?.Node;
|
||||
case HumanBodyBones.Neck: return humanoid.HumanBones.Neck?.Node;
|
||||
case HumanBodyBones.Head: return humanoid.HumanBones.Head?.Node;
|
||||
case HumanBodyBones.LeftShoulder: return humanoid.HumanBones.LeftShoulder?.Node;
|
||||
case HumanBodyBones.RightShoulder: return humanoid.HumanBones.RightShoulder?.Node;
|
||||
case HumanBodyBones.LeftUpperArm: return humanoid.HumanBones.LeftUpperArm?.Node;
|
||||
case HumanBodyBones.RightUpperArm: return humanoid.HumanBones.RightUpperArm?.Node;
|
||||
case HumanBodyBones.LeftLowerArm: return humanoid.HumanBones.LeftLowerArm?.Node;
|
||||
case HumanBodyBones.RightLowerArm: return humanoid.HumanBones.RightLowerArm?.Node;
|
||||
case HumanBodyBones.LeftHand: return humanoid.HumanBones.LeftHand?.Node;
|
||||
case HumanBodyBones.RightHand: return humanoid.HumanBones.RightHand?.Node;
|
||||
case HumanBodyBones.LeftToes: return humanoid.HumanBones.LeftToes?.Node;
|
||||
case HumanBodyBones.RightToes: return humanoid.HumanBones.RightToes?.Node;
|
||||
// case HumanBodyBones.LeftEye: return humanoid.HumanBones.LeftEye?.Node;
|
||||
// case HumanBodyBones.RightEye: return humanoid.HumanBones.RightEye?.Node;
|
||||
case HumanBodyBones.Jaw: return humanoid.HumanBones.Jaw?.Node;
|
||||
case HumanBodyBones.LeftThumbProximal: return humanoid.HumanBones.LeftThumbMetacarpal?.Node; // Metacarpal
|
||||
case HumanBodyBones.LeftThumbIntermediate: return humanoid.HumanBones.LeftThumbProximal?.Node; // Proximal
|
||||
case HumanBodyBones.LeftThumbDistal: return humanoid.HumanBones.LeftThumbDistal?.Node;
|
||||
case HumanBodyBones.LeftIndexProximal: return humanoid.HumanBones.LeftIndexProximal?.Node;
|
||||
case HumanBodyBones.LeftIndexIntermediate: return humanoid.HumanBones.LeftIndexIntermediate?.Node;
|
||||
case HumanBodyBones.LeftIndexDistal: return humanoid.HumanBones.LeftIndexDistal?.Node;
|
||||
case HumanBodyBones.LeftMiddleProximal: return humanoid.HumanBones.LeftMiddleProximal?.Node;
|
||||
case HumanBodyBones.LeftMiddleIntermediate: return humanoid.HumanBones.LeftMiddleIntermediate?.Node;
|
||||
case HumanBodyBones.LeftMiddleDistal: return humanoid.HumanBones.LeftMiddleDistal?.Node;
|
||||
case HumanBodyBones.LeftRingProximal: return humanoid.HumanBones.LeftRingProximal?.Node;
|
||||
case HumanBodyBones.LeftRingIntermediate: return humanoid.HumanBones.LeftRingIntermediate?.Node;
|
||||
case HumanBodyBones.LeftRingDistal: return humanoid.HumanBones.LeftRingDistal?.Node;
|
||||
case HumanBodyBones.LeftLittleProximal: return humanoid.HumanBones.LeftLittleProximal?.Node;
|
||||
case HumanBodyBones.LeftLittleIntermediate: return humanoid.HumanBones.LeftLittleIntermediate?.Node;
|
||||
case HumanBodyBones.LeftLittleDistal: return humanoid.HumanBones.LeftLittleDistal?.Node;
|
||||
case HumanBodyBones.RightThumbProximal: return humanoid.HumanBones.RightThumbMetacarpal?.Node; // Metacarpal
|
||||
case HumanBodyBones.RightThumbIntermediate: return humanoid.HumanBones.RightThumbProximal?.Node; // Proximal
|
||||
case HumanBodyBones.RightThumbDistal: return humanoid.HumanBones.RightThumbDistal?.Node;
|
||||
case HumanBodyBones.RightIndexProximal: return humanoid.HumanBones.RightIndexProximal?.Node;
|
||||
case HumanBodyBones.RightIndexIntermediate: return humanoid.HumanBones.RightIndexIntermediate?.Node;
|
||||
case HumanBodyBones.RightIndexDistal: return humanoid.HumanBones.RightIndexDistal?.Node;
|
||||
case HumanBodyBones.RightMiddleProximal: return humanoid.HumanBones.RightMiddleProximal?.Node;
|
||||
case HumanBodyBones.RightMiddleIntermediate: return humanoid.HumanBones.RightMiddleIntermediate?.Node;
|
||||
case HumanBodyBones.RightMiddleDistal: return humanoid.HumanBones.RightMiddleDistal?.Node;
|
||||
case HumanBodyBones.RightRingProximal: return humanoid.HumanBones.RightRingProximal?.Node;
|
||||
case HumanBodyBones.RightRingIntermediate: return humanoid.HumanBones.RightRingIntermediate?.Node;
|
||||
case HumanBodyBones.RightRingDistal: return humanoid.HumanBones.RightRingDistal?.Node;
|
||||
case HumanBodyBones.RightLittleProximal: return humanoid.HumanBones.RightLittleProximal?.Node;
|
||||
case HumanBodyBones.RightLittleIntermediate: return humanoid.HumanBones.RightLittleIntermediate?.Node;
|
||||
case HumanBodyBones.RightLittleDistal: return humanoid.HumanBones.RightLittleDistal?.Node;
|
||||
case HumanBodyBones.UpperChest: return humanoid.HumanBones.UpperChest?.Node;
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public static VRM10Motion LoadBvhFromText(string source, string path = "tmp.bvh")
|
||||
static Dictionary<HumanBodyBones, Transform> GetHumanMap(GltfData data, IReadOnlyList<Transform> nodes)
|
||||
{
|
||||
var context = new UniHumanoid.BvhImporterContext();
|
||||
context.Parse(path, source);
|
||||
context.Load();
|
||||
return new VRM10Motion(context);
|
||||
}
|
||||
var humanMap = new Dictionary<HumanBodyBones, Transform>();
|
||||
|
||||
public static VRM10Motion LoadBvhFromPath(string path)
|
||||
{
|
||||
return LoadBvhFromText(File.ReadAllText(path), path);
|
||||
}
|
||||
|
||||
static IEnumerable<Transform> Traverse(Transform t)
|
||||
{
|
||||
yield return t;
|
||||
foreach (Transform child in t)
|
||||
if (data.GLTF.extensions is UniGLTF.glTFExtensionImport extensions)
|
||||
{
|
||||
foreach (var x in Traverse(child))
|
||||
foreach (var kv in extensions.ObjectItems())
|
||||
{
|
||||
yield return x;
|
||||
if (kv.Key.GetString() == "VRMC_vrm_animation")
|
||||
{
|
||||
var animation = UniGLTF.Extensions.VRMC_vrm_animation.GltfDeserializer.Deserialize(kv.Value);
|
||||
foreach (HumanBodyBones bone in UniGLTF.Utils.CachedEnum.GetValues<HumanBodyBones>())
|
||||
{
|
||||
// Debug.Log($"{bone} => {index}");
|
||||
var node = GetNodeIndex(animation.Humanoid, bone);
|
||||
if (node.HasValue)
|
||||
{
|
||||
humanMap.Add(bone, nodes[node.Value]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return humanMap;
|
||||
}
|
||||
|
||||
public static async Task<VrmAnimation> LoadVrmAnimationFromPathAsync(string path)
|
||||
{
|
||||
//
|
||||
// GetHumanoid Mapping
|
||||
//
|
||||
using (GltfData data = new AutoGltfFileParser(path).Parse())
|
||||
using (var loader = new UniGLTF.ImporterContext(data))
|
||||
{
|
||||
loader.InvertAxis = Axes.X;
|
||||
// loader.PositionScaling = 0.01f;
|
||||
var instance = await loader.LoadAsync(new ImmediateCaller());
|
||||
var humanMap = GetHumanMap(data, loader.Nodes);
|
||||
if (humanMap.Count == 0)
|
||||
{
|
||||
throw new ArgumentException("fail to load VRMC_vrm_animation");
|
||||
}
|
||||
var description = AvatarDescription.Create(humanMap);
|
||||
|
||||
//
|
||||
// avatar
|
||||
//
|
||||
var avatar = description.CreateAvatar(instance.Root.transform);
|
||||
avatar.name = "Avatar";
|
||||
// AvatarDescription = description;
|
||||
var animator = instance.gameObject.AddComponent<Animator>();
|
||||
animator.avatar = avatar;
|
||||
|
||||
return new VrmAnimation(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +230,7 @@ RectTransform:
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 11
|
||||
m_RootOrder: 13
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@@ -394,6 +394,127 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 154330167}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &168425994
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 168425995}
|
||||
- component: {fileID: 168425998}
|
||||
- component: {fileID: 168425997}
|
||||
- component: {fileID: 168425996}
|
||||
m_Layer: 5
|
||||
m_Name: OpenMotion
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &168425995
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 168425994}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 1923525315}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 162, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &168425996
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 168425994}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Highlighted
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 168425997}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!114 &168425997
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 168425994}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!222 &168425998
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 168425994}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &175751362
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1097,10 +1218,12 @@ RectTransform:
|
||||
m_Children:
|
||||
- {fileID: 1621794411}
|
||||
- {fileID: 2009818432}
|
||||
- {fileID: 1557052150}
|
||||
- {fileID: 168425995}
|
||||
- {fileID: 224350191}
|
||||
- {fileID: 1791103379}
|
||||
- {fileID: 1311520909}
|
||||
- {fileID: 1557052150}
|
||||
- {fileID: 1767706907}
|
||||
- {fileID: 974864191}
|
||||
- {fileID: 597950322}
|
||||
- {fileID: 935566651}
|
||||
@@ -1595,7 +1718,7 @@ RectTransform:
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 7
|
||||
m_RootOrder: 9
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@@ -1675,7 +1798,7 @@ RectTransform:
|
||||
- {fileID: 154330168}
|
||||
- {fileID: 1954133885}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 13
|
||||
m_RootOrder: 15
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@@ -1761,7 +1884,7 @@ RectTransform:
|
||||
- {fileID: 2010083454}
|
||||
- {fileID: 1081455630}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 9
|
||||
m_RootOrder: 11
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@@ -1816,6 +1939,85 @@ MonoBehaviour:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_IsOn: 1
|
||||
--- !u!1 &642985707
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 642985708}
|
||||
- component: {fileID: 642985710}
|
||||
- component: {fileID: 642985709}
|
||||
m_Layer: 5
|
||||
m_Name: Label
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &642985708
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 642985707}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1767706907}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 9, y: -0.5}
|
||||
m_SizeDelta: {x: -28, y: -3}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &642985709
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 642985707}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 0
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: ShowBoxMan
|
||||
--- !u!222 &642985710
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 642985707}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &644517399
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -2279,6 +2481,82 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 806723448}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &826167455
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 826167456}
|
||||
- component: {fileID: 826167458}
|
||||
- component: {fileID: 826167457}
|
||||
m_Layer: 5
|
||||
m_Name: Background
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &826167456
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 826167455}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 1987265555}
|
||||
m_Father: {fileID: 1767706907}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 10, y: -10}
|
||||
m_SizeDelta: {x: 20, y: 20}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &826167457
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 826167455}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!222 &826167458
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 826167455}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &827174940
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -2914,7 +3192,7 @@ RectTransform:
|
||||
- {fileID: 175751363}
|
||||
- {fileID: 1904789319}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 8
|
||||
m_RootOrder: 10
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@@ -2951,7 +3229,7 @@ RectTransform:
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 6
|
||||
m_RootOrder: 8
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@@ -4114,7 +4392,7 @@ GameObject:
|
||||
- component: {fileID: 1268276257}
|
||||
- component: {fileID: 1268276256}
|
||||
m_Layer: 5
|
||||
m_Name: Version
|
||||
m_Name: VrmVersion
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
@@ -4654,7 +4932,7 @@ RectTransform:
|
||||
- {fileID: 452923209}
|
||||
- {fileID: 2090837017}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 12
|
||||
m_RootOrder: 14
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@@ -4818,7 +5096,7 @@ RectTransform:
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 2
|
||||
m_RootOrder: 6
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@@ -5363,6 +5641,92 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1767669910}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &1767706906
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1767706907}
|
||||
- component: {fileID: 1767706908}
|
||||
m_Layer: 5
|
||||
m_Name: ShowBoxMan
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1767706907
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1767706906}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 826167456}
|
||||
- {fileID: 642985708}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 7
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 160, y: 20}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1767706908
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1767706906}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 826167457}
|
||||
toggleTransition: 1
|
||||
graphic: {fileID: 1987265556}
|
||||
m_Group: {fileID: 0}
|
||||
onValueChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_IsOn: 1
|
||||
--- !u!1 &1767738853
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -5394,7 +5758,7 @@ RectTransform:
|
||||
- {fileID: 62367395}
|
||||
- {fileID: 1037763549}
|
||||
m_Father: {fileID: 339774397}
|
||||
m_RootOrder: 10
|
||||
m_RootOrder: 12
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@@ -5563,30 +5927,30 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_version: {fileID: 1268276256}
|
||||
m_open: {fileID: 2009818433}
|
||||
m_openModel: {fileID: 2009818433}
|
||||
m_openMotion: {fileID: 168425996}
|
||||
m_showBoxMan: {fileID: 1767706908}
|
||||
m_enableLipSync: {fileID: 935566650}
|
||||
m_enableAutoBlink: {fileID: 634488422}
|
||||
m_enableAutoExpression: {fileID: 1767738855}
|
||||
m_useUrpMaterial: {fileID: 1438613465}
|
||||
m_useAsync: {fileID: 602093299}
|
||||
m_src: {fileID: 0}
|
||||
m_target: {fileID: 802105000}
|
||||
Root: {fileID: 0}
|
||||
m_motion: {fileID: 4900000, guid: 08df5151e71aed748b13547492fb8b9a, type: 3}
|
||||
m_texts:
|
||||
m_textModelTitle: {fileID: 1111491925}
|
||||
m_textModelVersion: {fileID: 1045380263}
|
||||
m_textModelAuthor: {fileID: 854014595}
|
||||
m_textModelContact: {fileID: 587234270}
|
||||
m_textModelReference: {fileID: 1181308133}
|
||||
m_textModelTitle: {fileID: 1636340565}
|
||||
m_textModelVersion: {fileID: 2105159133}
|
||||
m_textModelAuthor: {fileID: 827174942}
|
||||
m_textModelContact: {fileID: 1922159877}
|
||||
m_textModelReference: {fileID: 806723450}
|
||||
m_thumbnail: {fileID: 800895694}
|
||||
m_textPermissionAllowed: {fileID: 1322834811}
|
||||
m_textPermissionViolent: {fileID: 1242458544}
|
||||
m_textPermissionSexual: {fileID: 933018279}
|
||||
m_textPermissionCommercial: {fileID: 852999696}
|
||||
m_textPermissionOther: {fileID: 1289294209}
|
||||
m_textDistributionLicense: {fileID: 1476033062}
|
||||
m_textDistributionOther: {fileID: 1104290798}
|
||||
m_textPermissionAllowed: {fileID: 1633219309}
|
||||
m_textPermissionViolent: {fileID: 935554082}
|
||||
m_textPermissionSexual: {fileID: 928757302}
|
||||
m_textPermissionCommercial: {fileID: 773923920}
|
||||
m_textPermissionOther: {fileID: 1172469240}
|
||||
m_textDistributionLicense: {fileID: 1007924637}
|
||||
m_textDistributionOther: {fileID: 1199975014}
|
||||
m_ui:
|
||||
ToggleMotionTPose: {fileID: 1791103380}
|
||||
ToggleMotionBVH: {fileID: 1311520910}
|
||||
@@ -5912,6 +6276,87 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1922159875}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &1923525314
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1923525315}
|
||||
- component: {fileID: 1923525317}
|
||||
- component: {fileID: 1923525316}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1923525315
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1923525314}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 168425995}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1923525316
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1923525314}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: 'Open Motion
|
||||
|
||||
'
|
||||
--- !u!222 &1923525317
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1923525314}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &1954133884
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -6061,7 +6506,9 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Open
|
||||
m_Text: 'Open Model
|
||||
|
||||
'
|
||||
--- !u!222 &1963417401
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -6070,6 +6517,81 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1963417398}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!1 &1987265554
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1987265555}
|
||||
- component: {fileID: 1987265557}
|
||||
- component: {fileID: 1987265556}
|
||||
m_Layer: 5
|
||||
m_Name: Checkmark
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1987265555
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1987265554}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 826167456}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 20, y: 20}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1987265556
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1987265554}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10901, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!222 &1987265557
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1987265554}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &2009818431
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -6083,7 +6605,7 @@ GameObject:
|
||||
- component: {fileID: 2009818434}
|
||||
- component: {fileID: 2009818433}
|
||||
m_Layer: 5
|
||||
m_Name: Open
|
||||
m_Name: OpenModel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
|
||||
@@ -11,12 +11,18 @@ namespace UniVRM10.VRM10Viewer
|
||||
{
|
||||
public class VRM10ViewerUI : MonoBehaviour
|
||||
{
|
||||
[Header("UI")]
|
||||
[SerializeField]
|
||||
Text m_version = default;
|
||||
|
||||
[Header("UI")]
|
||||
[SerializeField]
|
||||
Button m_open = default;
|
||||
Button m_openModel = default;
|
||||
|
||||
[SerializeField]
|
||||
Button m_openMotion = default;
|
||||
|
||||
[SerializeField]
|
||||
Toggle m_showBoxMan = default;
|
||||
|
||||
[SerializeField]
|
||||
Toggle m_enableLipSync = default;
|
||||
@@ -41,14 +47,26 @@ namespace UniVRM10.VRM10Viewer
|
||||
|
||||
GameObject Root = default;
|
||||
|
||||
VRM10Motion m_src = default;
|
||||
IMotion m_src = default;
|
||||
public IMotion Motion
|
||||
{
|
||||
get { return m_src; }
|
||||
set
|
||||
{
|
||||
if (m_src != null)
|
||||
{
|
||||
m_src.Dispose();
|
||||
}
|
||||
m_src = value;
|
||||
}
|
||||
}
|
||||
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
|
||||
[Serializable]
|
||||
class TextFields
|
||||
{
|
||||
[SerializeField, Header("Info")]
|
||||
[SerializeField]
|
||||
Text m_textModelTitle = default;
|
||||
[SerializeField]
|
||||
Text m_textModelVersion = default;
|
||||
@@ -77,6 +95,28 @@ namespace UniVRM10.VRM10Viewer
|
||||
[SerializeField]
|
||||
Text m_textDistributionOther = default;
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
var texts = GameObject.FindObjectsOfType<Text>();
|
||||
m_textModelTitle = texts.First(x => x.name == "Title");
|
||||
m_textModelVersion = texts.First(x => x.name == "Version");
|
||||
m_textModelAuthor = texts.First(x => x.name == "Author");
|
||||
m_textModelContact = texts.First(x => x.name == "Contact");
|
||||
m_textModelReference = texts.First(x => x.name == "Reference");
|
||||
|
||||
m_textPermissionAllowed = texts.First(x => x.name == "AllowedUser");
|
||||
m_textPermissionViolent = texts.First(x => x.name == "Violent");
|
||||
m_textPermissionSexual = texts.First(x => x.name == "Sexual");
|
||||
m_textPermissionCommercial = texts.First(x => x.name == "Commercial");
|
||||
m_textPermissionOther = texts.First(x => x.name == "Other");
|
||||
|
||||
m_textDistributionLicense = texts.First(x => x.name == "LicenseType");
|
||||
m_textDistributionOther = texts.First(x => x.name == "OtherLicense");
|
||||
|
||||
var images = GameObject.FindObjectsOfType<RawImage>();
|
||||
m_thumbnail = images.First(x => x.name == "RawImage");
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
m_textModelTitle.text = "";
|
||||
@@ -151,6 +191,16 @@ namespace UniVRM10.VRM10Viewer
|
||||
[SerializeField]
|
||||
ToggleGroup ToggleMotion = default;
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
var toggles = GameObject.FindObjectsOfType<Toggle>();
|
||||
ToggleMotionTPose = toggles.First(x => x.name == "TPose");
|
||||
ToggleMotionBVH = toggles.First(x => x.name == "BVH");
|
||||
|
||||
var groups = GameObject.FindObjectsOfType<ToggleGroup>();
|
||||
ToggleMotion = groups.First(x => x.name == "_Motion_");
|
||||
}
|
||||
|
||||
public bool IsBvhEnabled
|
||||
{
|
||||
get => ToggleMotion.ActiveToggles().FirstOrDefault() == ToggleMotionBVH;
|
||||
@@ -167,15 +217,22 @@ namespace UniVRM10.VRM10Viewer
|
||||
private void Reset()
|
||||
{
|
||||
var buttons = GameObject.FindObjectsOfType<Button>();
|
||||
m_open = buttons.First(x => x.name == "Open");
|
||||
m_openModel = buttons.First(x => x.name == "OpenModel");
|
||||
m_openMotion = buttons.First(x => x.name == "OpenMotion");
|
||||
|
||||
var toggles = GameObject.FindObjectsOfType<Toggle>();
|
||||
m_showBoxMan = toggles.First(x => x.name == "ShowBoxMan");
|
||||
m_enableLipSync = toggles.First(x => x.name == "EnableLipSync");
|
||||
m_enableAutoBlink = toggles.First(x => x.name == "EnableAutoBlink");
|
||||
m_enableAutoExpression = toggles.First(x => x.name == "EnableAutoExpression");
|
||||
m_useUrpMaterial = toggles.First(x => x.name == "UseUrpMaterial");
|
||||
m_useAsync = toggles.First(x => x.name == "UseAsync");
|
||||
|
||||
var texts = GameObject.FindObjectsOfType<Text>();
|
||||
m_version = texts.First(x => x.name == "Version");
|
||||
m_version = texts.First(x => x.name == "VrmVersion");
|
||||
|
||||
m_texts.Reset();
|
||||
m_ui.Reset();
|
||||
|
||||
m_target = GameObject.FindObjectOfType<VRM10TargetMover>().gameObject;
|
||||
}
|
||||
@@ -185,13 +242,16 @@ namespace UniVRM10.VRM10Viewer
|
||||
private void Start()
|
||||
{
|
||||
m_version.text = string.Format("VRMViewer {0}.{1}",
|
||||
VRMVersion.MAJOR, VRMVersion.MINOR);
|
||||
m_open.onClick.AddListener(OnOpenClicked);
|
||||
VRMVersion.MAJOR, VRMVersion.MINOR);
|
||||
|
||||
m_openModel.onClick.AddListener(OnOpenModelClicked);
|
||||
|
||||
m_openMotion.onClick.AddListener(OnOpenMotionClicked);
|
||||
|
||||
// load initial bvh
|
||||
if (m_motion != null)
|
||||
{
|
||||
m_src = VRM10Motion.LoadBvhFromText(m_motion.text);
|
||||
Motion = BvhMotion.LoadBvhFromText(m_motion.text);
|
||||
}
|
||||
|
||||
string[] cmds = System.Environment.GetCommandLineArgs();
|
||||
@@ -213,13 +273,6 @@ namespace UniVRM10.VRM10Viewer
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.EnableLipSyncValue = m_enableLipSync.isOn;
|
||||
m_loaded.EnableBlinkValue = m_enableAutoBlink.isOn;
|
||||
m_loaded.EnableAutoExpressionValue = m_enableAutoExpression.isOn;
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Tab))
|
||||
{
|
||||
if (Root != null) Root.SetActive(!Root.activeSelf);
|
||||
@@ -233,11 +286,20 @@ namespace UniVRM10.VRM10Viewer
|
||||
}
|
||||
}
|
||||
|
||||
if (Motion != null)
|
||||
{
|
||||
Motion.ShowBoxMan(m_showBoxMan.isOn);
|
||||
}
|
||||
|
||||
if (m_loaded != null)
|
||||
{
|
||||
if (m_ui.IsBvhEnabled && m_src != null)
|
||||
m_loaded.EnableLipSyncValue = m_enableLipSync.isOn;
|
||||
m_loaded.EnableBlinkValue = m_enableAutoBlink.isOn;
|
||||
m_loaded.EnableAutoExpressionValue = m_enableAutoExpression.isOn;
|
||||
|
||||
if (m_ui.IsBvhEnabled && Motion != null)
|
||||
{
|
||||
VRM10Retarget.Retarget(m_src.ControlRig, (m_loaded.ControlRig, m_loaded.ControlRig));
|
||||
VRM10Retarget.Retarget(Motion.ControlRig, (m_loaded.ControlRig, m_loaded.ControlRig));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -246,10 +308,10 @@ namespace UniVRM10.VRM10Viewer
|
||||
}
|
||||
}
|
||||
|
||||
void OnOpenClicked()
|
||||
void OnOpenModelClicked()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = VRM10FileDialogForWindows.FileDialog("open VRM", "vrm", "bvh");
|
||||
var path = VRM10FileDialogForWindows.FileDialog("open VRM", "vrm");
|
||||
#elif UNITY_EDITOR
|
||||
var path = UnityEditor.EditorUtility.OpenFilePanel("Open VRM", "", "vrm");
|
||||
#else
|
||||
@@ -261,12 +323,6 @@ namespace UniVRM10.VRM10Viewer
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
if (ext == ".bvh")
|
||||
{
|
||||
m_src = VRM10Motion.LoadBvhFromPath(path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ext != ".vrm")
|
||||
{
|
||||
Debug.LogWarning($"{path} is not vrm");
|
||||
@@ -276,6 +332,31 @@ namespace UniVRM10.VRM10Viewer
|
||||
LoadModel(path);
|
||||
}
|
||||
|
||||
async void OnOpenMotionClicked()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = VRM10FileDialogForWindows.FileDialog("open Motion", "bvh", "gltf", "glb");
|
||||
#elif UNITY_EDITOR
|
||||
var path = UnityEditor.EditorUtility.OpenFilePanel("Open Motion", "", "bvh");
|
||||
#else
|
||||
var path = Application.dataPath + "/default.bvh";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
if (ext == ".bvh")
|
||||
{
|
||||
Motion = BvhMotion.LoadBvhFromPath(path);
|
||||
return;
|
||||
}
|
||||
|
||||
// gltf, glb etc...
|
||||
Motion = await VrmAnimation.LoadVrmAnimationFromPathAsync(path);
|
||||
}
|
||||
|
||||
static IMaterialDescriptorGenerator GetVrmMaterialDescriptorGenerator(bool useUrp)
|
||||
{
|
||||
if (useUrp)
|
||||
|
||||
Submodule vrm-specification updated: 993a90a5bd...0bcc3d4c56
Reference in New Issue
Block a user