diff options
author | chai <chaifix@163.com> | 2020-10-11 20:00:58 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-10-11 20:00:58 +0800 |
commit | 8b384dffa0d9c63c7a657c6e567c2ddefbf046cd (patch) | |
tree | 3f4d669b73b6622aa49627c4ccb3c78d51a82bde /Assets/ThirdParty/VRM/VRM/UniHumanoid | |
parent | cd3aee8d640f6abcc82802ca7abbcdfa031c20d3 (diff) |
+Saionji show off scene
Diffstat (limited to 'Assets/ThirdParty/VRM/VRM/UniHumanoid')
88 files changed, 7510 insertions, 0 deletions
diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor.meta new file mode 100644 index 00000000..700ef71e --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6dfa46c173ff021418df4bada32ddfe9 +folderAsset: yes +timeCreated: 1517655448 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/BoneMappingEditor.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/BoneMappingEditor.cs new file mode 100644 index 00000000..d94a21aa --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/BoneMappingEditor.cs @@ -0,0 +1,422 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.IO; +using UnityEditor; +using UnityEngine; + + +namespace UniHumanoid +{ + [CustomEditor(typeof(BoneMapping))] + public class BoneMappingEditor : Editor + { + BoneMapping m_target; + + void OnEnable() + { + m_target = (BoneMapping)target; + + var animator = m_target.GetComponent<Animator>(); + if (animator != null) + { + m_bones = EachBoneDefs.Select(x => new Bone( +animator.GetBoneTransform(x.Head), animator.GetBoneTransform(x.Tail))) +.Where(x => x.Head != null && x.Tail != null) +.ToArray(); + } + } + + static GameObject ObjectField(GameObject obj) + { + return (GameObject)EditorGUILayout.ObjectField(obj, typeof(GameObject), true); + } + + static GameObject ObjectField(string label, GameObject obj) + { + return (GameObject)EditorGUILayout.ObjectField(label, obj, typeof(GameObject), true); + } + + const int LABEL_WIDTH = 100; + + static void BoneField(HumanBodyBones bone, GameObject[] bones) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField(bone.ToString(), GUILayout.Width(LABEL_WIDTH)); + bones[(int)bone] = ObjectField(bones[(int)bone]); + EditorGUILayout.EndHorizontal(); + } + + static void BoneField(HumanBodyBones left, HumanBodyBones right, GameObject[] bones) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField(left.ToString().Substring(4), GUILayout.Width(LABEL_WIDTH)); // skip left + bones[(int)left] = ObjectField(bones[(int)left]); + bones[(int)right] = ObjectField(bones[(int)right]); + EditorGUILayout.EndHorizontal(); + } + + bool m_handFoldout; + bool m_settingsFoldout; + + public override void OnInspectorGUI() + { + var bones = m_target.Bones; + if (bones == null) + { + return; + } + + BoneField(HumanBodyBones.Hips, bones); + + if (bones[(int)HumanBodyBones.Hips] == null) + { + EditorGUILayout.HelpBox(@"First, you set hips", MessageType.Warning); + } + else + { + if (GUILayout.Button("Guess bone mapping")) + { + m_target.GuessBoneMapping(); + } + EditorGUILayout.HelpBox(@"Guess bones from hips", MessageType.Info); + + if (GUILayout.Button("Ensure T-Pose")) + { + m_target.EnsureTPose(); + } + EditorGUILayout.HelpBox(@"Arms to Horizontal", MessageType.Info); + + if (GUILayout.Button("Create avatar")) + { + var description = AvatarDescription.Create(m_target.Description); + BoneMapping.SetBonesToDescription(m_target, description); + var avatar = description.CreateAvatarAndSetup(m_target.transform); + if (avatar != null) + { + avatar.name = "avatar"; +#if UNITY_2018_2_OR_NEWER + var prefabRoot = PrefabUtility.GetCorrespondingObjectFromSource(m_target.gameObject); +#else + var prefabRoot = PrefabUtility.GetPrefabParent(m_target.gameObject); +#endif + var prefabPath = AssetDatabase.GetAssetPath(prefabRoot); + + var path = (string.IsNullOrEmpty(prefabPath)) + ? string.Format("Assets/{0}.asset", avatar.name) + : string.Format("{0}/{1}.asset", Path.GetDirectoryName(prefabPath), Path.GetFileNameWithoutExtension(prefabPath)) + ; + path = EditorUtility.SaveFilePanel( + "Save avatar", + Path.GetDirectoryName(path), + string.Format("{0}.avatar.asset", serializedObject.targetObject.name), + "asset"); + var assetPath = HumanPoseTransferEditor.ToAssetPath(path); + if (!string.IsNullOrEmpty(assetPath)) + { + AssetDatabase.CreateAsset(description, assetPath); // overwrite + AssetDatabase.AddObjectToAsset(avatar, assetPath); + + Debug.LogFormat("Create avatar {0}", path); + AssetDatabase.ImportAsset(assetPath); + Selection.activeObject = avatar; + } + else + { + Debug.LogWarning("fail to CreateAvatar"); + } + } + } + EditorGUILayout.HelpBox(@"before create, + +1. Model root transform should reset(origin without rotation) +2. Model forward to Z+(rotate child of model root) +3. Required bones filled +", MessageType.Info); + } + + /* + m_settingsFoldout = EditorGUILayout.Foldout(m_settingsFoldout, "AvatarSettings"); + if (m_settingsFoldout) + { + EditorGUILayout.FloatField("armStretch", m_target.armStretch); + EditorGUILayout.FloatField("legStretch", m_target.legStretch); + EditorGUILayout.FloatField("upperArmTwist", m_target.upperArmTwist); + EditorGUILayout.FloatField("lowerArmTwist", m_target.lowerArmTwist); + EditorGUILayout.FloatField("upperLegTwist", m_target.upperLegTwist); + EditorGUILayout.FloatField("lowerLegTwist", m_target.lowerLegTwist); + EditorGUILayout.FloatField("feetSpacing", m_target.feetSpacing); + EditorGUILayout.Toggle("hasTranslationDoF", m_target.hasTranslationDoF); + //public BoneLimit[] human; + } + */ + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Arm", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH)); + EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.EndHorizontal(); + BoneField(HumanBodyBones.LeftShoulder, HumanBodyBones.RightShoulder, bones); + BoneField(HumanBodyBones.LeftUpperArm, HumanBodyBones.RightUpperArm, bones); + BoneField(HumanBodyBones.LeftLowerArm, HumanBodyBones.RightLowerArm, bones); + BoneField(HumanBodyBones.LeftHand, HumanBodyBones.RightHand, bones); + + EditorGUILayout.LabelField("Body and Head", EditorStyles.boldLabel); + BoneField(HumanBodyBones.Spine, bones); + BoneField(HumanBodyBones.Chest, bones); +#if UNITY_5_6_OR_NEWER + BoneField(HumanBodyBones.UpperChest, bones); +#endif + BoneField(HumanBodyBones.Neck, bones); + BoneField(HumanBodyBones.Head, bones); + BoneField(HumanBodyBones.Jaw, bones); + BoneField(HumanBodyBones.LeftEye, HumanBodyBones.RightEye, bones); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Leg", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH)); + EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.EndHorizontal(); + BoneField(HumanBodyBones.LeftUpperLeg, HumanBodyBones.RightUpperLeg, bones); + BoneField(HumanBodyBones.LeftLowerLeg, HumanBodyBones.RightLowerLeg, bones); + BoneField(HumanBodyBones.LeftFoot, HumanBodyBones.RightFoot, bones); + BoneField(HumanBodyBones.LeftToes, HumanBodyBones.RightToes, bones); + + m_handFoldout = EditorGUILayout.Foldout(m_handFoldout, "Hand"); + if (m_handFoldout) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Thumb", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH)); + EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.EndHorizontal(); + BoneField(HumanBodyBones.LeftThumbProximal, HumanBodyBones.RightThumbProximal, bones); + BoneField(HumanBodyBones.LeftThumbIntermediate, HumanBodyBones.RightThumbIntermediate, bones); + BoneField(HumanBodyBones.LeftThumbDistal, HumanBodyBones.RightThumbDistal, bones); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Index", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH)); + EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.EndHorizontal(); + BoneField(HumanBodyBones.LeftIndexProximal, HumanBodyBones.RightIndexProximal, bones); + BoneField(HumanBodyBones.LeftIndexIntermediate, HumanBodyBones.RightIndexIntermediate, bones); + BoneField(HumanBodyBones.LeftIndexDistal, HumanBodyBones.RightIndexDistal, bones); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Middle", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH)); + EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.EndHorizontal(); + BoneField(HumanBodyBones.LeftMiddleProximal, HumanBodyBones.RightMiddleProximal, bones); + BoneField(HumanBodyBones.LeftMiddleIntermediate, HumanBodyBones.RightMiddleIntermediate, bones); + BoneField(HumanBodyBones.LeftMiddleDistal, HumanBodyBones.RightMiddleDistal, bones); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Ring", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH)); + EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.EndHorizontal(); + BoneField(HumanBodyBones.LeftRingProximal, HumanBodyBones.RightRingProximal, bones); + BoneField(HumanBodyBones.LeftRingIntermediate, HumanBodyBones.RightRingIntermediate, bones); + BoneField(HumanBodyBones.LeftRingDistal, HumanBodyBones.RightRingDistal, bones); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Little", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH)); + EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40)); + EditorGUILayout.EndHorizontal(); + BoneField(HumanBodyBones.LeftLittleProximal, HumanBodyBones.RightLittleProximal, bones); + BoneField(HumanBodyBones.LeftLittleIntermediate, HumanBodyBones.RightLittleIntermediate, bones); + BoneField(HumanBodyBones.LeftLittleDistal, HumanBodyBones.RightLittleDistal, bones); + } + + EditorUtility.SetDirty(m_target); + } + + struct Bone + { + public Transform Head; + public Transform Tail; + + public Bone(Transform head, Transform tail) + { + Head = head; + Tail = tail; + } + + public void Draw() + { + Handles.DrawLine(Head.transform.position, Tail.transform.position); + } + } + + Bone[] m_bones; + + struct BoneDef + { + public HumanBodyBones Head; + public HumanBodyBones Tail; + + public BoneDef(HumanBodyBones head, HumanBodyBones tail) + { + Head = head; + Tail = tail; + } + } + static readonly HumanBodyBones[][] BoneDefs = + { + new HumanBodyBones[] + { + HumanBodyBones.Hips, + HumanBodyBones.Spine, + HumanBodyBones.Chest, + HumanBodyBones.Neck, + HumanBodyBones.Head, + }, + new HumanBodyBones[] + { + HumanBodyBones.Chest, + HumanBodyBones.LeftShoulder, + HumanBodyBones.LeftUpperArm, + HumanBodyBones.LeftLowerArm, + HumanBodyBones.LeftHand, + }, + new HumanBodyBones[] + { + HumanBodyBones.Chest, + HumanBodyBones.RightShoulder, + HumanBodyBones.RightUpperArm, + HumanBodyBones.RightLowerArm, + HumanBodyBones.RightHand, + }, + + new HumanBodyBones[] + { + HumanBodyBones.LeftThumbProximal, + HumanBodyBones.LeftThumbIntermediate, + HumanBodyBones.LeftThumbDistal, + }, + new HumanBodyBones[] + { + HumanBodyBones.LeftIndexProximal, + HumanBodyBones.LeftIndexIntermediate, + HumanBodyBones.LeftIndexDistal, + }, + new HumanBodyBones[] + { + HumanBodyBones.LeftMiddleProximal, + HumanBodyBones.LeftMiddleIntermediate, + HumanBodyBones.LeftMiddleDistal, + }, + new HumanBodyBones[] + { + HumanBodyBones.LeftRingProximal, + HumanBodyBones.LeftRingIntermediate, + HumanBodyBones.LeftRingDistal, + }, + new HumanBodyBones[] + { + HumanBodyBones.LeftLittleProximal, + HumanBodyBones.LeftLittleIntermediate, + HumanBodyBones.LeftLittleDistal, + }, + + new HumanBodyBones[] + { + HumanBodyBones.RightThumbProximal, + HumanBodyBones.RightThumbIntermediate, + HumanBodyBones.RightThumbDistal, + }, + new HumanBodyBones[] + { + HumanBodyBones.RightIndexProximal, + HumanBodyBones.RightIndexIntermediate, + HumanBodyBones.RightIndexDistal, + }, + new HumanBodyBones[] + { + HumanBodyBones.RightMiddleProximal, + HumanBodyBones.RightMiddleIntermediate, + HumanBodyBones.RightMiddleDistal, + }, + new HumanBodyBones[] + { + HumanBodyBones.RightRingProximal, + HumanBodyBones.RightRingIntermediate, + HumanBodyBones.RightRingDistal, + }, + new HumanBodyBones[] + { + HumanBodyBones.RightLittleProximal, + HumanBodyBones.RightLittleIntermediate, + HumanBodyBones.RightLittleDistal, + }, + + new HumanBodyBones[] + { + HumanBodyBones.LeftUpperLeg, + HumanBodyBones.LeftLowerLeg, + HumanBodyBones.LeftFoot, + }, + + new HumanBodyBones[] + { + HumanBodyBones.RightUpperLeg, + HumanBodyBones.RightLowerLeg, + HumanBodyBones.RightFoot, + }, + }; + static IEnumerable<BoneDef> EachBoneDefs + { + get + { + foreach (var x in BoneDefs) + { + var count = x.Length - 1; + for (int i = 0; i < count; ++i) + { + yield return new BoneDef(x[i], x[i + 1]); + } + } + } + } + + void DrawBone(HumanBodyBones bone, GameObject go) + { + if (go == null) + { + return; + } + + Handles.Label(go.transform.position, + go.name + "\n(" + bone.ToString() + ")"); + } + + private void OnSceneGUI() + { + var bones = m_target.Bones; + if (bones != null) + { + for (int i = 0; i < bones.Length; ++i) + { + DrawBone((HumanBodyBones)i, bones[i]); + } + if (m_bones != null) + { + foreach (var x in m_bones) + { + x.Draw(); + } + } + } + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/BoneMappingEditor.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/BoneMappingEditor.cs.meta new file mode 100644 index 00000000..d6a1c6db --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/BoneMappingEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 06b3418a97f8c204da34a849fa86a7c0 +timeCreated: 1516520481 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/HumanPoseTransferEditor.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/HumanPoseTransferEditor.cs new file mode 100644 index 00000000..6a8489a4 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/HumanPoseTransferEditor.cs @@ -0,0 +1,151 @@ +using System; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEngine; + + +namespace UniHumanoid +{ + [CustomEditor(typeof(HumanPoseTransfer))] + public class HumanPoseTransferEditor : Editor + { + //HumanPoseTransfer m_target; + SerializedProperty m_avatarProp; + SerializedProperty m_typeProp; + SerializedProperty m_clipProp; + SerializedProperty m_transferProp; + + static string[] SOURCE_TYPES = ((HumanPoseTransfer.HumanPoseTransferSourceType[]) + Enum.GetValues(typeof(HumanPoseTransfer.HumanPoseTransferSourceType))) + .Select(x => x.ToString()) + .ToArray(); + + private void OnEnable() + { + //m_target = (HumanPoseTransfer)target; + m_typeProp = serializedObject.FindProperty("SourceType"); + m_clipProp = serializedObject.FindProperty("PoseClip"); + m_avatarProp = serializedObject.FindProperty("Avatar"); + m_transferProp = serializedObject.FindProperty("Source"); + } + + public override void OnInspectorGUI() + { + //base.OnInspectorGUI(); + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_avatarProp); + + /* + m_typeProp.intValue = + GUILayout.Toolbar(m_typeProp.intValue, SOURCE_TYPES); + */ + m_typeProp.intValue = + EditorGUILayout.Popup("SourceType", m_typeProp.intValue, SOURCE_TYPES); + + switch ((HumanPoseTransfer.HumanPoseTransferSourceType)m_typeProp.intValue) + { + case HumanPoseTransfer.HumanPoseTransferSourceType.None: + serializedObject.ApplyModifiedProperties(); + break; + + case HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseClip: + PoseClipInspector(); + break; + + case HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer: + PoseHandler(); + break; + } + GUILayout.Space(20); + + // CreatePose + if (GUILayout.Button("Pose to HumanPoseClip")) + { + var path = EditorUtility.SaveFilePanel( + "Save humanpose", + Application.dataPath, + string.Format("{0}.pose.asset", serializedObject.targetObject.name), + "asset"); + var assetPath = ToAssetPath(path); + if (!string.IsNullOrEmpty(path)) + { + var pose = ((HumanPoseTransfer)serializedObject.targetObject).CreatePose(); + + var clip = ScriptableObject.CreateInstance<HumanPoseClip>(); + clip.ApplyPose(ref pose); + + AssetDatabase.CreateAsset(clip, assetPath); + Selection.activeObject = clip; + } + } + + // CreatePose + if (GUILayout.Button("Pose to AnimationClip")) + { + var path = EditorUtility.SaveFilePanel( + "Save animationClip", + Application.dataPath, + string.Format("{0}.pose.anim", serializedObject.targetObject.name), + "anim"); + var assetPath = ToAssetPath(path); + if (!string.IsNullOrEmpty(path)) + { + var pose = ((HumanPoseTransfer)serializedObject.targetObject).CreatePose(); + var clip = AnimationClipUtility.CreateAnimationClipFromHumanPose(pose); + AssetDatabase.CreateAsset(clip, assetPath); + Selection.activeObject = clip; + } + } + } + + public static string ToAssetPath(string src) + { + src = src.Replace("\\", "/"); + var basePath = Path.GetFullPath(Application.dataPath + "/..").Replace("\\", "/"); + if (!src.StartsWith(basePath)) + { + return null; + } + return src.Substring(basePath.Length + 1); + } + + void PoseClipInspector() + { + var old = (HumanPoseClip)m_clipProp.objectReferenceValue; + EditorGUILayout.PropertyField(m_clipProp); + serializedObject.ApplyModifiedProperties(); + + var _target = (HumanPoseTransfer)target; + if (_target.PoseClip != old) + { + //Debug.Log("clip != old"); + if (_target.PoseClip != null) + { + var pose = _target.PoseClip.GetPose(); + _target.SetPose(pose); + } + } + +#if false + if (_target.PoseClip != null) + { + if (GUILayout.Button("Apply PoseClip")) + { + Debug.Log("apply"); + var pose = default(HumanPose); + _target.PoseClip.GetPose(out pose); + _target.SetPose(pose); + } + } +#endif + } + + void PoseHandler() + { + EditorGUILayout.PropertyField(m_transferProp); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/HumanPoseTransferEditor.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/HumanPoseTransferEditor.cs.meta new file mode 100644 index 00000000..0e206056 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/HumanPoseTransferEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: d51cc8ca343beb647bc6d8e23600dd66 +timeCreated: 1519366120 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/MuscleInspectorEditor.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/MuscleInspectorEditor.cs new file mode 100644 index 00000000..c48010c6 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/MuscleInspectorEditor.cs @@ -0,0 +1,352 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEditor.IMGUI.Controls; +using UnityEngine; + + +namespace UniHumanoid +{ + class BoneNode : IEnumerable<BoneNode> + { + public HumanBodyBones Bone { get; private set; } + + public List<BoneNode> Children = new List<BoneNode>(); + + public int[] Muscles; + + public BoneNode(HumanBodyBones bone, params int[] muscles) + { + Bone = bone; + Muscles = muscles; + } + + public IEnumerator<BoneNode> GetEnumerator() + { + throw new NotImplementedException(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + throw new NotImplementedException(); + } + + public void Add(BoneNode child) + { + Children.Add(child); + } + } + + class BoneTreeViewItem : TreeViewItem + { + //HumanBodyBones m_bone; + + public BoneTreeViewItem(int id, int depth, HumanBodyBones bone) : base(id, depth, bone.ToString()) + { + //m_bone = bone; + } + } + + class MuscleTreeViewItem : TreeViewItem + { + public int Muscle + { + get; + private set; + } + + public MuscleTreeViewItem(int id, int depth, int muscle) : base(id, depth, HumanTrait.MuscleName[muscle]) + { + Muscle = muscle; + } + } + + class BoneTreeView : TreeView + { + static BoneNode Skeleton = new BoneNode(HumanBodyBones.Hips) + { + new BoneNode(HumanBodyBones.Spine, 0, 1, 2){ + new BoneNode(HumanBodyBones.Chest, 3, 4, 5){ + new BoneNode(HumanBodyBones.UpperChest, 6, 7, 8){ + new BoneNode(HumanBodyBones.Neck, 9, 10, 11){ + new BoneNode(HumanBodyBones.Head, 12, 13, 14){ + new BoneNode(HumanBodyBones.LeftEye, 15, 16), + new BoneNode(HumanBodyBones.RightEye, 17, 18) + } + }, + new BoneNode(HumanBodyBones.LeftShoulder, 37, 38){ + new BoneNode(HumanBodyBones.LeftUpperArm, 39, 40, 41){ + new BoneNode(HumanBodyBones.LeftLowerArm, 42, 43){ + new BoneNode(HumanBodyBones.LeftHand, 44, 45) + } + } + }, + new BoneNode(HumanBodyBones.RightShoulder, 46, 47){ + new BoneNode(HumanBodyBones.RightUpperArm, 48, 49, 50){ + new BoneNode(HumanBodyBones.RightLowerArm, 51, 52){ + new BoneNode(HumanBodyBones.RightHand, 53, 54) + } + } + } + } + } + }, + new BoneNode(HumanBodyBones.LeftUpperLeg, 21, 22, 23){ + new BoneNode(HumanBodyBones.LeftLowerLeg, 24, 25){ + new BoneNode(HumanBodyBones.LeftFoot, 26, 27){ + new BoneNode(HumanBodyBones.LeftToes, 28) + } + } + }, + new BoneNode(HumanBodyBones.RightUpperLeg, 29, 30, 31){ + new BoneNode(HumanBodyBones.RightLowerLeg, 32, 33){ + new BoneNode(HumanBodyBones.RightFoot, 34, 35){ + new BoneNode(HumanBodyBones.RightToes, 36) + } + } + } + }; + + //Animator m_animator; + HumanPoseHandler m_handler; + HumanPose m_pose; + + bool m_updated; + + public void Begin() + { + m_handler.GetHumanPose(ref m_pose); + } + + public void End() + { + if (m_updated) + { + m_handler.SetHumanPose(ref m_pose); + } + m_updated = false; + } + + public BoneTreeView(TreeViewState treeViewState, MultiColumnHeader header, HumanPoseHandler handler) + : base(treeViewState, header) + { + m_handler = handler; + Reload(); + } + + protected override TreeViewItem BuildRoot() + { + return new TreeViewItem { id = 0, depth = -1 }; + } + + protected override IList<TreeViewItem> BuildRows(TreeViewItem root) + { + var rows = GetRows() ?? new List<TreeViewItem>(200); + + // We use the GameObject instanceIDs as ids for items as we want to + // select the game objects and not the transform components. + rows.Clear(); + + var item = CreateTreeViewItemForBone(HumanBodyBones.Hips); + root.AddChild(item); + rows.Add(item); + + if (IsExpanded(item.id)) + { + AddChildrenRecursive(Skeleton, item, rows); + } + else + { + item.children = CreateChildListForCollapsedParent(); + } + + SetupDepthsFromParentsAndChildren(root); + + return rows; + } + + void AddChildrenRecursive(BoneNode bone, TreeViewItem item, IList<TreeViewItem> rows) + { + int childCount = bone.Children.Count; + item.children = new List<TreeViewItem>(childCount); + if (bone.Muscles != null) + { + foreach (var muscle in bone.Muscles) + { + var childItem = new MuscleTreeViewItem(muscle + 20000, -1, muscle); + item.AddChild(childItem); + rows.Add(childItem); + } + } + + foreach (var child in bone.Children) + { + var childItem = CreateTreeViewItemForBone(child.Bone); + item.AddChild(childItem); + rows.Add(childItem); + + //if (child.Children.Count > 0) + { + if (IsExpanded(childItem.id)) + { + AddChildrenRecursive(child, childItem, rows); + } + else + { + childItem.children = CreateChildListForCollapsedParent(); + } + } + } + } + + static TreeViewItem CreateTreeViewItemForBone(HumanBodyBones bone) + { + return new TreeViewItem((int)bone, -1, Enum.GetName(typeof(HumanBodyBones), bone)); + } + + protected override void RowGUI(RowGUIArgs args) + { + for (int i = 0; i < args.GetNumVisibleColumns(); ++i) + { + CellGUI(args.GetCellRect(i), args.GetColumn(i), ref args); + } + } + + void CellGUI(Rect cellRect, int index, ref RowGUIArgs args) + { + // Center cell rect vertically (makes it easier to place controls, icons etc in the cells) + CenterRectUsingSingleLineHeight(ref cellRect); + + switch (index) + { + case 0: + { + // Default icon and label + args.rowRect = cellRect; + base.RowGUI(args); + } + break; + + case 1: + { + var muscleItem = args.item as MuscleTreeViewItem; + if (muscleItem != null) + { + var muscleIndex = muscleItem.Muscle; + var muscles = m_pose.muscles; + var value = EditorGUI.Slider(cellRect, GUIContent.none, muscles[muscleIndex], -1f, 1f); + if (value != muscles[muscleIndex]) + { + muscles[muscleIndex] = value; + m_updated = true; + } + } + else + { + + } + } + break; + } + } + + public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState() + { + var columns = new[] + { + new MultiColumnHeaderState.Column + { + headerContent = new GUIContent("Name"), + headerTextAlignment = TextAlignment.Left, + width = 250, + minWidth = 60, + autoResize = false, + allowToggleVisibility = false + }, + new MultiColumnHeaderState.Column + { + headerContent = new GUIContent("Muscle value"), + headerTextAlignment = TextAlignment.Left, + width = 110, + minWidth = 60, + autoResize = true + }, + }; + return new MultiColumnHeaderState(columns); + } + } + + + [CustomEditor(typeof(MuscleInspector))] + public class MuscleInspectorEditor : Editor + { + [NonSerialized] bool m_Initialized; + [SerializeField] TreeViewState m_TreeViewState; // Serialized in the window layout file so it survives assembly reloading + //[SerializeField] MultiColumnHeaderState m_MultiColumnHeaderState; + SearchField m_SearchField; + BoneTreeView m_TreeView; + + MuscleInspector m_target; + HumanPoseHandler m_handler; + + + MultiColumnHeader GetHeaderState() + { + //bool firstInit = m_MultiColumnHeaderState == null; + + var headerState = BoneTreeView.CreateDefaultMultiColumnHeaderState(); + /* + if (MultiColumnHeaderState.CanOverwriteSerializedFields(m_MultiColumnHeaderState, headerState)) + { + MultiColumnHeaderState.OverwriteSerializedFields(m_MultiColumnHeaderState, headerState); + } + m_MultiColumnHeaderState = headerState; + */ + var multiColumnHeader = new MultiColumnHeader(headerState); + multiColumnHeader.ResizeToFit(); + return multiColumnHeader; + } + + void OnEnable() + { + var mi = this.target as MuscleInspector; + var animator = mi.GetComponent<Animator>(); + if (animator != null + && animator.avatar != null + && animator.avatar.isValid + && animator.avatar.isHuman + ) + { + Debug.LogFormat("MuscleInspectorEditor.OnEnable"); + m_handler = new HumanPoseHandler(animator.avatar, animator.transform); + + m_TreeView = new BoneTreeView(new TreeViewState(), GetHeaderState(), m_handler); + } + } + + void OnDisable() + { + if (m_handler != null) + { + m_handler.Dispose(); + m_handler = null; + } + } + + public override void OnInspectorGUI() + { + if (m_TreeView == null) + { + EditorGUILayout.HelpBox("Animator required", MessageType.Error); + return; + } + + var rect = GUILayoutUtility.GetRect(0, 10000, 0, m_TreeView.totalHeight); + m_TreeView.Begin(); + m_TreeView.OnGUI(rect); + m_TreeView.End(); + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/MuscleInspectorEditor.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/MuscleInspectorEditor.cs.meta new file mode 100644 index 00000000..101761ba --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/MuscleInspectorEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0d2c3401d1adf41488c19ec4d47386a0 +timeCreated: 1541840728 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests.meta new file mode 100644 index 00000000..3b873064 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fcdf450ca966f85428c238046e51c2ca +folderAsset: yes +timeCreated: 1534750149 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/BvhLoaderTests.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/BvhLoaderTests.cs new file mode 100644 index 00000000..b85976b8 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/BvhLoaderTests.cs @@ -0,0 +1,1360 @@ +using NUnit.Framework; +using UnityEngine; + + +namespace UniHumanoid +{ +#if UNITY_5_6_OR_NEWER + public class BvhLoaderTests + { + #region LOUICE + /// <summary> + /// https://github.com/wspr/bvh-matlab/blob/master/louise.bvh + /// </summary> + const string bvh_louise = @"HIERARCHY +ROOT Hips +{ + OFFSET 0.000000 0.000000 0.000000 + CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation + JOINT Chest + { + OFFSET -0.000000 30.833075 -0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT Neck + { + OFFSET -0.000000 23.115997 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT Head + { + OFFSET -0.000000 10.266666 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -0.000000 15.866669 0.000000 + } + } + } + JOINT LeftCollar + { + OFFSET -0.000000 23.115997 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftShoulder + { + OFFSET 18.666668 -0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftElbow + { + OFFSET 25.298601 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftWrist + { + OFFSET 27.056377 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0.000000 -14.000002 0.000000 + } + } + } + } + } + JOINT RightCollar + { + OFFSET -0.000000 23.115997 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightShoulder + { + OFFSET -18.666668 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightElbow + { + OFFSET -25.298601 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightWrist + { + OFFSET -27.056377 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -0.000000 -14.000002 0.000000 + } + } + } + } + } + } + JOINT LeftHip + { + OFFSET 11.200000 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftKnee + { + OFFSET -0.000000 -43.871983 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftAnkle + { + OFFSET -0.000000 -44.488350 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -0.000000 -4.666667 15.866669 + } + } + } + } + JOINT RightHip + { + OFFSET -11.200000 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightKnee + { + OFFSET -0.000000 -43.871983 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightAnkle + { + OFFSET -0.000000 -44.488350 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -0.000000 -4.666667 15.866669 + } + } + } + } +} +"; + + [Test] + public void GuessBoneMapping_louise() + { + var bvh = Bvh.Parse(bvh_louise); + var detector = new BvhSkeletonEstimator(); + var skeleton = detector.Detect(bvh); + + Assert.AreEqual(0, skeleton.GetBoneIndex(HumanBodyBones.Hips)); + + Assert.AreEqual("Hips", skeleton.GetBoneName(HumanBodyBones.Hips)); + Assert.AreEqual("Chest", skeleton.GetBoneName(HumanBodyBones.Spine)); + Assert.IsNull(skeleton.GetBoneName(HumanBodyBones.Chest)); + Assert.AreEqual("Neck", skeleton.GetBoneName(HumanBodyBones.Neck)); + Assert.AreEqual("Head", skeleton.GetBoneName(HumanBodyBones.Head)); + + Assert.AreEqual("LeftCollar", skeleton.GetBoneName(HumanBodyBones.LeftShoulder)); + Assert.AreEqual("LeftShoulder", skeleton.GetBoneName(HumanBodyBones.LeftUpperArm)); + Assert.AreEqual("LeftElbow", skeleton.GetBoneName(HumanBodyBones.LeftLowerArm)); + Assert.AreEqual("LeftWrist", skeleton.GetBoneName(HumanBodyBones.LeftHand)); + + Assert.AreEqual("RightCollar", skeleton.GetBoneName(HumanBodyBones.RightShoulder)); + Assert.AreEqual("RightShoulder", skeleton.GetBoneName(HumanBodyBones.RightUpperArm)); + Assert.AreEqual("RightElbow", skeleton.GetBoneName(HumanBodyBones.RightLowerArm)); + Assert.AreEqual("RightWrist", skeleton.GetBoneName(HumanBodyBones.RightHand)); + + Assert.AreEqual("LeftHip", skeleton.GetBoneName(HumanBodyBones.LeftUpperLeg)); + Assert.AreEqual("LeftKnee", skeleton.GetBoneName(HumanBodyBones.LeftLowerLeg)); + Assert.AreEqual("LeftAnkle", skeleton.GetBoneName(HumanBodyBones.LeftFoot)); + Assert.IsNull(skeleton.GetBoneName(HumanBodyBones.LeftToes)); + + Assert.AreEqual("RightHip", skeleton.GetBoneName(HumanBodyBones.RightUpperLeg)); + Assert.AreEqual("RightKnee", skeleton.GetBoneName(HumanBodyBones.RightLowerLeg)); + Assert.AreEqual("RightAnkle", skeleton.GetBoneName(HumanBodyBones.RightFoot)); + Assert.IsNull(skeleton.GetBoneName(HumanBodyBones.RightToes)); + } + #endregion + + #region cgspeed + /// <summary> + /// https://sites.google.com/a/cgspeed.com/cgspeed/motion-capture + /// </summary> + const string bvh_cgspeed = @"HIERARCHY +ROOT Hips +{ + OFFSET 0.00000 0.00000 0.00000 + CHANNELS 6 Xposition Yposition Zposition Zrotation Yrotation Xrotation + JOINT LHipJoint + { + OFFSET 0 0 0 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT LeftUpLeg + { + OFFSET 1.64549 -1.70879 0.84566 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT LeftLeg + { + OFFSET 2.24963 -6.18082 0.00000 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT LeftFoot + { + OFFSET 2.71775 -7.46697 0.00000 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT LeftToeBase + { + OFFSET 0.18768 -0.51564 2.24737 + CHANNELS 3 Zrotation Yrotation Xrotation + End Site + { + OFFSET 0.00000 -0.00000 1.15935 + } + } + } + } + } + } + JOINT RHipJoint + { + OFFSET 0 0 0 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT RightUpLeg + { + OFFSET -1.58830 -1.70879 0.84566 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT RightLeg + { + OFFSET -2.25006 -6.18201 0.00000 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT RightFoot + { + OFFSET -2.72829 -7.49593 0.00000 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT RightToeBase + { + OFFSET -0.21541 -0.59185 2.10643 + CHANNELS 3 Zrotation Yrotation Xrotation + End Site + { + OFFSET -0.00000 -0.00000 1.09838 + } + } + } + } + } + } + JOINT LowerBack + { + OFFSET 0 0 0 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT Spine + { + OFFSET 0.03142 2.10496 -0.11038 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT Spine1 + { + OFFSET -0.01863 2.10897 -0.06956 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT Neck + { + OFFSET 0 0 0 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT Neck1 + { + OFFSET -0.02267 1.73238 0.00451 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT Head + { + OFFSET -0.05808 1.54724 -0.61749 + CHANNELS 3 Zrotation Yrotation Xrotation + End Site + { + OFFSET -0.01396 1.71468 -0.21082 + } + } + } + } + JOINT LeftShoulder + { + OFFSET 0 0 0 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT LeftArm + { + OFFSET 3.44898 0.50298 0.21920 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT LeftForeArm + { + OFFSET 5.41917 -0.00000 -0.00000 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT LeftHand + { + OFFSET 2.44373 -0.00000 0.00000 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT LeftFingerBase + { + OFFSET 0 0 0 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT LeftHandIndex1 + { + OFFSET 0.72750 -0.00000 0.00000 + CHANNELS 3 Zrotation Yrotation Xrotation + End Site + { + OFFSET 0.58653 -0.00000 0.00000 + } + } + } + JOINT LThumb + { + OFFSET 0 0 0 + CHANNELS 3 Zrotation Yrotation Xrotation + End Site + { + OFFSET 0.59549 -0.00000 0.59549 + } + } + } + } + } + } + JOINT RightShoulder + { + OFFSET 0 0 0 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT RightArm + { + OFFSET -3.23015 0.55830 0.31051 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT RightForeArm + { + OFFSET -5.58976 -0.00010 0.00014 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT RightHand + { + OFFSET -2.48060 -0.00000 0.00000 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT RightFingerBase + { + OFFSET 0 0 0 + CHANNELS 3 Zrotation Yrotation Xrotation + JOINT RightHandIndex1 + { + OFFSET -0.81601 -0.00000 0.00000 + CHANNELS 3 Zrotation Yrotation Xrotation + End Site + { + OFFSET -0.65789 -0.00000 0.00000 + } + } + } + JOINT RThumb + { + OFFSET 0 0 0 + CHANNELS 3 Zrotation Yrotation Xrotation + End Site + { + OFFSET -0.66793 -0.00000 0.66793 + } + } + } + } + } + } + } + } + } +}" +; + [Test] + public void GuessBoneMapping_cgspeed() + { + var bvh = Bvh.Parse(bvh_cgspeed); + var detector = new BvhSkeletonEstimator(); + var skeleton = detector.Detect(bvh); + + Assert.AreEqual(0, skeleton.GetBoneIndex(HumanBodyBones.Hips)); + + Assert.AreEqual("Hips", skeleton.GetBoneName(HumanBodyBones.Hips)); + Assert.AreEqual("LowerBack", skeleton.GetBoneName(HumanBodyBones.Spine)); + Assert.AreEqual("Spine", skeleton.GetBoneName(HumanBodyBones.Chest)); +#if UNITY_5_6_OR_NEWER + Assert.AreEqual("Spine1", skeleton.GetBoneName(HumanBodyBones.UpperChest)); +#endif + Assert.AreEqual("Neck", skeleton.GetBoneName(HumanBodyBones.Neck)); + Assert.AreEqual("Head", skeleton.GetBoneName(HumanBodyBones.Head)); + + Assert.AreEqual("LeftShoulder", skeleton.GetBoneName(HumanBodyBones.LeftShoulder)); + Assert.AreEqual("LeftArm", skeleton.GetBoneName(HumanBodyBones.LeftUpperArm)); + Assert.AreEqual("LeftForeArm", skeleton.GetBoneName(HumanBodyBones.LeftLowerArm)); + Assert.AreEqual("LeftHand", skeleton.GetBoneName(HumanBodyBones.LeftHand)); + + Assert.AreEqual("RightShoulder", skeleton.GetBoneName(HumanBodyBones.RightShoulder)); + Assert.AreEqual("RightArm", skeleton.GetBoneName(HumanBodyBones.RightUpperArm)); + Assert.AreEqual("RightForeArm", skeleton.GetBoneName(HumanBodyBones.RightLowerArm)); + Assert.AreEqual("RightHand", skeleton.GetBoneName(HumanBodyBones.RightHand)); + + Assert.AreEqual("LeftUpLeg", skeleton.GetBoneName(HumanBodyBones.LeftUpperLeg)); + Assert.AreEqual("LeftLeg", skeleton.GetBoneName(HumanBodyBones.LeftLowerLeg)); + Assert.AreEqual("LeftFoot", skeleton.GetBoneName(HumanBodyBones.LeftFoot)); + Assert.AreEqual("LeftToeBase", skeleton.GetBoneName(HumanBodyBones.LeftToes)); + + Assert.AreEqual("RightUpLeg", skeleton.GetBoneName(HumanBodyBones.RightUpperLeg)); + Assert.AreEqual("RightLeg", skeleton.GetBoneName(HumanBodyBones.RightLowerLeg)); + Assert.AreEqual("RightFoot", skeleton.GetBoneName(HumanBodyBones.RightFoot)); + Assert.AreEqual("RightToeBase", skeleton.GetBoneName(HumanBodyBones.RightToes)); + } + #endregion + + #region mocap + const string bvh_mocap = @"HIERARCHY +ROOT Hips +{ + OFFSET 0.000000 0.000000 0.000000 + CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation + JOINT Spine + { + OFFSET -0.000000 7.509519 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT Spine1 + { + OFFSET -0.000000 18.393364 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT Neck + { + OFFSET -0.000000 20.224955 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT Head + { + OFFSET -0.000000 14.194822 1.831590 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -0.000000 18.315899 0.000000 + } + } + } + JOINT LeftShoulder + { + OFFSET 3.663486 15.569419 -0.490481 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftArm + { + OFFSET 14.246625 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftForeArm + { + OFFSET 25.567986 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftHand + { + OFFSET 29.965693 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 13.736924 0.000000 0.000000 + } + } + } + } + } + JOINT RightShoulder + { + OFFSET -3.661042 15.569419 -0.490481 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightArm + { + OFFSET -14.246625 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightForeArm + { + OFFSET -25.567986 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightHand + { + OFFSET -29.965693 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -13.736924 0.000000 0.000000 + } + } + } + } + } + } + } + JOINT LeftUpLeg + { + OFFSET 9.157949 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftLeg + { + OFFSET -0.000000 -40.189121 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftFoot + { + OFFSET -0.000000 -39.816978 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftToeBase + { + OFFSET -0.000000 -5.952667 13.736924 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -0.000000 0.000000 3.663180 + } + } + } + } + } + JOINT RightUpLeg + { + OFFSET -9.157949 0.000000 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightLeg + { + OFFSET -0.000000 -40.189121 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightFoot + { + OFFSET -0.000000 -39.816978 0.000000 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightToeBase + { + OFFSET -0.000000 -5.952667 13.736924 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -0.000000 0.000000 3.663180 + } + } + } + } + } +} +"; + + [Test] + public void GuessBoneMapping_mocap() + { + var bvh = Bvh.Parse(bvh_mocap); + var detector = new BvhSkeletonEstimator(); + var skeleton = detector.Detect(bvh); + + Assert.AreEqual(0, skeleton.GetBoneIndex(HumanBodyBones.Hips)); + + Assert.AreEqual("Hips", skeleton.GetBoneName(HumanBodyBones.Hips)); + Assert.AreEqual("Spine", skeleton.GetBoneName(HumanBodyBones.Spine)); + Assert.AreEqual("Spine1", skeleton.GetBoneName(HumanBodyBones.Chest)); + + Assert.AreEqual(null, skeleton.GetBoneName(HumanBodyBones.UpperChest)); + + Assert.AreEqual("Neck", skeleton.GetBoneName(HumanBodyBones.Neck)); + Assert.AreEqual("Head", skeleton.GetBoneName(HumanBodyBones.Head)); + + Assert.AreEqual("LeftShoulder", skeleton.GetBoneName(HumanBodyBones.LeftShoulder)); + Assert.AreEqual("LeftArm", skeleton.GetBoneName(HumanBodyBones.LeftUpperArm)); + Assert.AreEqual("LeftForeArm", skeleton.GetBoneName(HumanBodyBones.LeftLowerArm)); + Assert.AreEqual("LeftHand", skeleton.GetBoneName(HumanBodyBones.LeftHand)); + + Assert.AreEqual("RightShoulder", skeleton.GetBoneName(HumanBodyBones.RightShoulder)); + Assert.AreEqual("RightArm", skeleton.GetBoneName(HumanBodyBones.RightUpperArm)); + Assert.AreEqual("RightForeArm", skeleton.GetBoneName(HumanBodyBones.RightLowerArm)); + Assert.AreEqual("RightHand", skeleton.GetBoneName(HumanBodyBones.RightHand)); + + Assert.AreEqual("LeftUpLeg", skeleton.GetBoneName(HumanBodyBones.LeftUpperLeg)); + Assert.AreEqual("LeftLeg", skeleton.GetBoneName(HumanBodyBones.LeftLowerLeg)); + Assert.AreEqual("LeftFoot", skeleton.GetBoneName(HumanBodyBones.LeftFoot)); + Assert.AreEqual("LeftToeBase", skeleton.GetBoneName(HumanBodyBones.LeftToes)); + + Assert.AreEqual("RightUpLeg", skeleton.GetBoneName(HumanBodyBones.RightUpperLeg)); + Assert.AreEqual("RightLeg", skeleton.GetBoneName(HumanBodyBones.RightLowerLeg)); + Assert.AreEqual("RightFoot", skeleton.GetBoneName(HumanBodyBones.RightFoot)); + Assert.AreEqual("RightToeBase", skeleton.GetBoneName(HumanBodyBones.RightToes)); + } + #endregion + + #region mocap2 + const string bvh_mocap2 = @"HIERARCHY +ROOT Hips +{ + OFFSET 0.000000 0.000000 0.000000 + CHANNELS 6 Xposition Yposition Zposition Yrotation Xrotation Zrotation + JOINT Chest + { + OFFSET 0.000000 10.678932 0.006280 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT Chest2 + { + OFFSET 0.000000 10.491159 -0.011408 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT Chest3 + { + OFFSET 0.000000 9.479342 0.000000 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT Chest4 + { + OFFSET 0.000000 9.479342 0.000000 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT Neck + { + OFFSET 0.000000 13.535332 0.000000 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT Head + { + OFFSET 0.000000 8.819083 -0.027129 + CHANNELS 3 Yrotation Xrotation Zrotation + End Site + { + OFFSET 0.000000 16.966594 -0.014170 + } + } + } + JOINT RightCollar + { + OFFSET -3.012546 7.545150 0.000000 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT RightShoulder + { + OFFSET -13.683099 0.000000 0.000000 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT RightElbow + { + OFFSET -26.359998 0.000000 0.000000 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT RightWrist + { + OFFSET -21.746691 0.000000 0.008601 + CHANNELS 3 Yrotation Xrotation Zrotation + End Site + { + OFFSET -16.348058 0.000000 0.000000 + } + } + } + } + } + JOINT LeftCollar + { + OFFSET 3.012546 7.545150 0.000000 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT LeftShoulder + { + OFFSET 13.683099 0.000000 0.000000 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT LeftElbow + { + OFFSET 26.359998 0.000000 0.000000 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT LeftWrist + { + OFFSET 21.746691 0.000000 0.008601 + CHANNELS 3 Yrotation Xrotation Zrotation + End Site + { + OFFSET 16.348058 0.000000 0.000000 + } + } + } + } + } + } + } + } + } + JOINT RightHip + { + OFFSET -8.622479 -0.030774 -0.003140 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT RightKnee + { + OFFSET 0.000000 -37.209160 -0.002630 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT RightAnkle + { + OFFSET 0.000000 -37.343279 -0.058479 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT RightToe + { + OFFSET 0.000000 -8.903465 15.088070 + CHANNELS 3 Yrotation Xrotation Zrotation + End Site + { + OFFSET 0.000000 -1.471739 6.884388 + } + } + } + } + } + JOINT LeftHip + { + OFFSET 8.622479 -0.030774 -0.003140 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT LeftKnee + { + OFFSET 0.000000 -37.209160 -0.002630 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT LeftAnkle + { + OFFSET 0.000000 -37.343279 -0.058479 + CHANNELS 3 Yrotation Xrotation Zrotation + JOINT LeftToe + { + OFFSET 0.000000 -8.903465 15.088070 + CHANNELS 3 Yrotation Xrotation Zrotation + End Site + { + OFFSET 0.000000 -1.471739 6.884388 + } + } + } + } + } +} +"; + + [Test] + public void GuessBoneMapping_mocap2() + { + var bvh = Bvh.Parse(bvh_mocap2); + var detector = new BvhSkeletonEstimator(); + var skeleton = detector.Detect(bvh); + + Assert.AreEqual(0, skeleton.GetBoneIndex(HumanBodyBones.Hips)); + + Assert.AreEqual("Hips", skeleton.GetBoneName(HumanBodyBones.Hips)); + + Assert.AreEqual("Chest", skeleton.GetBoneName(HumanBodyBones.Spine)); + Assert.AreEqual("Chest2", skeleton.GetBoneName(HumanBodyBones.Chest)); + Assert.AreEqual("Chest4", skeleton.GetBoneName(HumanBodyBones.UpperChest)); + + Assert.AreEqual("Neck", skeleton.GetBoneName(HumanBodyBones.Neck)); + Assert.AreEqual("Head", skeleton.GetBoneName(HumanBodyBones.Head)); + + Assert.AreEqual("LeftCollar", skeleton.GetBoneName(HumanBodyBones.LeftShoulder)); + Assert.AreEqual("LeftShoulder", skeleton.GetBoneName(HumanBodyBones.LeftUpperArm)); + Assert.AreEqual("LeftElbow", skeleton.GetBoneName(HumanBodyBones.LeftLowerArm)); + Assert.AreEqual("LeftWrist", skeleton.GetBoneName(HumanBodyBones.LeftHand)); + + Assert.AreEqual("RightCollar", skeleton.GetBoneName(HumanBodyBones.RightShoulder)); + Assert.AreEqual("RightShoulder", skeleton.GetBoneName(HumanBodyBones.RightUpperArm)); + Assert.AreEqual("RightElbow", skeleton.GetBoneName(HumanBodyBones.RightLowerArm)); + Assert.AreEqual("RightWrist", skeleton.GetBoneName(HumanBodyBones.RightHand)); + + Assert.AreEqual("LeftHip", skeleton.GetBoneName(HumanBodyBones.LeftUpperLeg)); + Assert.AreEqual("LeftKnee", skeleton.GetBoneName(HumanBodyBones.LeftLowerLeg)); + Assert.AreEqual("LeftAnkle", skeleton.GetBoneName(HumanBodyBones.LeftFoot)); + Assert.AreEqual("LeftToe", skeleton.GetBoneName(HumanBodyBones.LeftToes)); + + Assert.AreEqual("RightHip", skeleton.GetBoneName(HumanBodyBones.RightUpperLeg)); + Assert.AreEqual("RightKnee", skeleton.GetBoneName(HumanBodyBones.RightLowerLeg)); + Assert.AreEqual("RightAnkle", skeleton.GetBoneName(HumanBodyBones.RightFoot)); + Assert.AreEqual("RightToe", skeleton.GetBoneName(HumanBodyBones.RightToes)); + } + #endregion + + #region mocapdata.com + const string mocapdata_com_hierarchy = @"HIERARCHY +ROOT Hips +{ + OFFSET 17.1116 39.7036 -3.684 + CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation + JOINT LeftHip + { + OFFSET 3.43 2.84217e-014 -2.22045e-015 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftKnee + { + OFFSET 6.75016e-014 -18.47 4.4853e-014 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftAnkle + { + OFFSET 1.52767e-013 -17.95 6.98996e-013 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0 -3.12 0 + } + } + } + } + JOINT RightHip + { + OFFSET -3.43 7.10543e-015 -1.11022e-015 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightKnee + { + OFFSET -1.35003e-013 -18.47 -7.10543e-015 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightAnkle + { + OFFSET -2.92122e-012 -17.95 -3.606e-013 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0 -3.12 0 + } + } + } + } + JOINT Chest + { + OFFSET 7.10543e-015 4.57 -9.32587e-015 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT Chest2 + { + OFFSET 3.55271e-015 6.57 0 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftCollar + { + OFFSET 1.06 4.19 1.76 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftShoulder + { + OFFSET 5.81 -2.84217e-014 -1.17684e-014 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftElbow + { + OFFSET 1.7053e-013 -12.08 2.13163e-014 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftWrist + { + OFFSET 5.96856e-013 -9.82 -6.39488e-014 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0 -7.37 0 + } + } + } + } + } + JOINT RightCollar + { + OFFSET -1.06 4.19 1.76 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightShoulder + { + OFFSET -6.06 -2.13163e-014 -5.32907e-015 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightElbow + { + OFFSET -1.42109e-013 -11.08 1.59872e-014 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightWrist + { + OFFSET -5.32907e-013 -9.82 -1.28342e-013 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0 -7.14001 0 + } + } + } + } + } + JOINT Neck + { + OFFSET 0 4.05 -7.54952e-015 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT Head + { + OFFSET -3.55271e-015 5.19 -1.95399e-014 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0 4.14001 0 + } + } + } + } + } +} +"; + [Test] + public void GuessBoneMapping_mocapdatacom() + { + var bvh = Bvh.Parse(mocapdata_com_hierarchy); + var detector = new BvhSkeletonEstimator(); + var skeleton = detector.Detect(bvh); + + Assert.AreEqual(0, skeleton.GetBoneIndex(HumanBodyBones.Hips)); + + Assert.AreEqual("Hips", skeleton.GetBoneName(HumanBodyBones.Hips)); + Assert.AreEqual("Chest", skeleton.GetBoneName(HumanBodyBones.Spine)); + Assert.AreEqual("Chest2", skeleton.GetBoneName(HumanBodyBones.Chest)); + + Assert.AreEqual("Neck", skeleton.GetBoneName(HumanBodyBones.Neck)); + Assert.AreEqual("Head", skeleton.GetBoneName(HumanBodyBones.Head)); + + Assert.AreEqual("LeftCollar", skeleton.GetBoneName(HumanBodyBones.LeftShoulder)); + Assert.AreEqual("LeftShoulder", skeleton.GetBoneName(HumanBodyBones.LeftUpperArm)); + Assert.AreEqual("LeftElbow", skeleton.GetBoneName(HumanBodyBones.LeftLowerArm)); + Assert.AreEqual("LeftWrist", skeleton.GetBoneName(HumanBodyBones.LeftHand)); + + Assert.AreEqual("RightCollar", skeleton.GetBoneName(HumanBodyBones.RightShoulder)); + Assert.AreEqual("RightShoulder", skeleton.GetBoneName(HumanBodyBones.RightUpperArm)); + Assert.AreEqual("RightElbow", skeleton.GetBoneName(HumanBodyBones.RightLowerArm)); + Assert.AreEqual("RightWrist", skeleton.GetBoneName(HumanBodyBones.RightHand)); + + Assert.AreEqual("LeftHip", skeleton.GetBoneName(HumanBodyBones.LeftUpperLeg)); + Assert.AreEqual("LeftKnee", skeleton.GetBoneName(HumanBodyBones.LeftLowerLeg)); + Assert.AreEqual("LeftAnkle", skeleton.GetBoneName(HumanBodyBones.LeftFoot)); + + Assert.AreEqual("RightHip", skeleton.GetBoneName(HumanBodyBones.RightUpperLeg)); + Assert.AreEqual("RightKnee", skeleton.GetBoneName(HumanBodyBones.RightLowerLeg)); + Assert.AreEqual("RightAnkle", skeleton.GetBoneName(HumanBodyBones.RightFoot)); + } + + const string mocapdatacom_hierarchy_2 = @"HIERARCHY +ROOT reference +{ + OFFSET 0 0 0 + CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation + JOINT Hips + { + OFFSET 18.0689 39.8301 -3.56659 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftHip + { + OFFSET 3.43 0 -2.22045e-016 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftKnee + { + OFFSET 6.03961e-014 -18.47 -2.24487e-013 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftAnkle + { + OFFSET 3.90443e-012 -17.95 -2.54197e-012 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0 -3.12 0 + } + } + } + } + JOINT RightHip + { + OFFSET -3.43 -2.84217e-014 -1.11022e-015 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightKnee + { + OFFSET 2.16716e-013 -18.47 2.24709e-013 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightAnkle + { + OFFSET 5.25446e-012 -17.95 3.2685e-012 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0 -3.12 0 + } + } + } + } + JOINT Chest + { + OFFSET 0 4.57 -2.22045e-016 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT Chest2 + { + OFFSET -7.10543e-015 6.57 0 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftCollar + { + OFFSET 1.06 4.19 1.76 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftShoulder + { + OFFSET 5.81 2.13163e-014 7.54952e-015 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftElbow + { + OFFSET 2.13163e-014 -12.08 8.34888e-014 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT LeftWrist + { + OFFSET 2.98428e-013 -9.82 1.61648e-013 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0 -7.37 0 + } + } + } + } + } + JOINT RightCollar + { + OFFSET -1.06 4.19 1.76 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightShoulder + { + OFFSET -6.06 2.13163e-014 5.77316e-015 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightElbow + { + OFFSET 1.42109e-013 -11.08 -9.05942e-014 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT RightWrist + { + OFFSET 5.7554e-013 -9.82 -1.98952e-013 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0 -7.14001 0 + } + } + } + } + } + JOINT Neck + { + OFFSET 0 4.05 8.88178e-016 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT Head + { + OFFSET -3.55271e-015 5.19 1.06581e-014 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 0 4.14001 0 + } + } + } + } + } + } +} +"; + + [Test] + public void GuessBoneMapping_mocapdatacom_2() + { + var bvh = Bvh.Parse(mocapdatacom_hierarchy_2); + var detector = new BvhSkeletonEstimator(); + var skeleton = detector.Detect(bvh); + + Assert.AreEqual("Hips", skeleton.GetBoneName(HumanBodyBones.Hips)); + Assert.AreEqual("Chest", skeleton.GetBoneName(HumanBodyBones.Spine)); + Assert.AreEqual("Chest2", skeleton.GetBoneName(HumanBodyBones.Chest)); + + Assert.AreEqual("Neck", skeleton.GetBoneName(HumanBodyBones.Neck)); + Assert.AreEqual("Head", skeleton.GetBoneName(HumanBodyBones.Head)); + + Assert.AreEqual("LeftCollar", skeleton.GetBoneName(HumanBodyBones.LeftShoulder)); + Assert.AreEqual("LeftShoulder", skeleton.GetBoneName(HumanBodyBones.LeftUpperArm)); + Assert.AreEqual("LeftElbow", skeleton.GetBoneName(HumanBodyBones.LeftLowerArm)); + Assert.AreEqual("LeftWrist", skeleton.GetBoneName(HumanBodyBones.LeftHand)); + + Assert.AreEqual("RightCollar", skeleton.GetBoneName(HumanBodyBones.RightShoulder)); + Assert.AreEqual("RightShoulder", skeleton.GetBoneName(HumanBodyBones.RightUpperArm)); + Assert.AreEqual("RightElbow", skeleton.GetBoneName(HumanBodyBones.RightLowerArm)); + Assert.AreEqual("RightWrist", skeleton.GetBoneName(HumanBodyBones.RightHand)); + + Assert.AreEqual("LeftHip", skeleton.GetBoneName(HumanBodyBones.LeftUpperLeg)); + Assert.AreEqual("LeftKnee", skeleton.GetBoneName(HumanBodyBones.LeftLowerLeg)); + Assert.AreEqual("LeftAnkle", skeleton.GetBoneName(HumanBodyBones.LeftFoot)); + + Assert.AreEqual("RightHip", skeleton.GetBoneName(HumanBodyBones.RightUpperLeg)); + Assert.AreEqual("RightKnee", skeleton.GetBoneName(HumanBodyBones.RightLowerLeg)); + Assert.AreEqual("RightAnkle", skeleton.GetBoneName(HumanBodyBones.RightFoot)); + } + #endregion + + #region daz_friendly + const string daz_friendly_hierarchy = @"HIERARCHY +ROOT hip +{ + OFFSET 0 0 0 + CHANNELS 6 Xposition Yposition Zposition Zrotation Yrotation Xrotation + JOINT abdomen + { + OFFSET 0 20.6881 -0.73152 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT chest + { + OFFSET 0 11.7043 -0.48768 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT neck + { + OFFSET 0 22.1894 -2.19456 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT head + { + OFFSET -0.24384 7.07133 1.2192 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT leftEye + { + OFFSET 4.14528 8.04674 8.04672 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 1 0 0 + } + } + JOINT rightEye + { + OFFSET -3.6576 8.04674 8.04672 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 1 0 0 + } + } + } + } + JOINT rCollar + { + OFFSET -2.68224 19.2634 -4.8768 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rShldr + { + OFFSET -8.77824 -1.95073 1.46304 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rForeArm + { + OFFSET -28.1742 -1.7115 0.48768 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rHand + { + OFFSET -22.5879 0.773209 7.07136 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rThumb1 + { + OFFSET -1.2192 -0.487915 3.41376 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rThumb2 + { + OFFSET -3.37035 -0.52449 3.41376 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -1.78271 -1.18214 1.43049 + } + } + } + JOINT rIndex1 + { + OFFSET -7.75947 0.938293 5.60832 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rIndex2 + { + OFFSET -2.54057 -0.884171 1.56538 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -1.62519 -0.234802 1.16502 + } + } + } + JOINT rMid1 + { + OFFSET -8.24714 1.18213 3.41376 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rMid2 + { + OFFSET -3.10165 -0.590103 1.0647 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -2.48547 -0.328903 0.83742 + } + } + } + JOINT rRing1 + { + OFFSET -8.82822 0.546677 1.51678 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rRing2 + { + OFFSET -2.60934 -0.819778 -0.0198488 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -2.33842 -0.294052 0.168128 + } + } + } + JOINT rPinky1 + { + OFFSET -8.27202 -0.0477905 -0.4584 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rPinky2 + { + OFFSET -1.82734 -0.647385 -0.700984 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -1.69225 -0.51767 -0.607171 + } + } + } + } + } + } + } + JOINT lCollar + { + OFFSET 2.68224 19.2634 -4.8768 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lShldr + { + OFFSET 8.77824 -1.95073 1.46304 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lForeArm + { + OFFSET 28.1742 -1.7115 0.48768 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lHand + { + OFFSET 22.5879 0.773209 7.07136 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lThumb1 + { + OFFSET 1.2192 -0.487915 3.41376 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lThumb2 + { + OFFSET 3.37035 -0.52449 3.41376 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 1.78271 -1.18214 1.43049 + } + } + } + JOINT lIndex1 + { + OFFSET 7.75947 0.938293 5.60832 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lIndex2 + { + OFFSET 2.54057 -0.884171 1.56538 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 1.62519 -0.234802 1.16502 + } + } + } + JOINT lMid1 + { + OFFSET 8.24714 1.18213 3.41376 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lMid2 + { + OFFSET 3.10165 -0.590103 1.0647 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 2.48547 -0.328903 0.83742 + } + } + } + JOINT lRing1 + { + OFFSET 8.82822 0.546677 1.51678 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lRing2 + { + OFFSET 2.60934 -0.819778 -0.0198488 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 2.33842 -0.294052 0.168128 + } + } + } + JOINT lPinky1 + { + OFFSET 8.27202 -0.0477905 -0.4584 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lPinky2 + { + OFFSET 1.82734 -0.647385 -0.700984 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 1.69225 -0.51767 -0.607171 + } + } + } + } + } + } + } + } + } + JOINT rButtock + { + OFFSET -8.77824 4.35084 1.2192 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rThigh + { + OFFSET 0 -1.70687 -2.19456 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rShin + { + OFFSET 0 -36.8199 0.73152 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT rFoot + { + OFFSET 0.73152 -45.1104 -5.12064 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET -1.1221 -3.69964 12.103 + } + } + } + } + } + JOINT lButtock + { + OFFSET 8.77824 4.35084 1.2192 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lThigh + { + OFFSET 0 -1.70687 -2.19456 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lShin + { + OFFSET 0 -36.8199 0.73152 + CHANNELS 3 Zrotation Xrotation Yrotation + JOINT lFoot + { + OFFSET -0.73152 -45.1104 -5.12064 + CHANNELS 3 Zrotation Xrotation Yrotation + End Site + { + OFFSET 1.1221 -3.69964 12.103 + } + } + } + } + } +}"; + + [Test] + public void GuessBoneMapping_daz_friendly() + { + var bvh = Bvh.Parse(daz_friendly_hierarchy); + var detector = new BvhSkeletonEstimator(); + var skeleton = detector.Detect(bvh); + + Assert.AreEqual("hip", skeleton.GetBoneName(HumanBodyBones.Hips)); + Assert.AreEqual("abdomen", skeleton.GetBoneName(HumanBodyBones.Spine)); + Assert.AreEqual("chest", skeleton.GetBoneName(HumanBodyBones.Chest)); + + Assert.AreEqual("neck", skeleton.GetBoneName(HumanBodyBones.Neck)); + Assert.AreEqual("head", skeleton.GetBoneName(HumanBodyBones.Head)); + + Assert.AreEqual("lCollar", skeleton.GetBoneName(HumanBodyBones.LeftShoulder)); + Assert.AreEqual("lShldr", skeleton.GetBoneName(HumanBodyBones.LeftUpperArm)); + Assert.AreEqual("lForeArm", skeleton.GetBoneName(HumanBodyBones.LeftLowerArm)); + Assert.AreEqual("lHand", skeleton.GetBoneName(HumanBodyBones.LeftHand)); + + Assert.AreEqual("rCollar", skeleton.GetBoneName(HumanBodyBones.RightShoulder)); + Assert.AreEqual("rShldr", skeleton.GetBoneName(HumanBodyBones.RightUpperArm)); + Assert.AreEqual("rForeArm", skeleton.GetBoneName(HumanBodyBones.RightLowerArm)); + Assert.AreEqual("rHand", skeleton.GetBoneName(HumanBodyBones.RightHand)); + + Assert.AreEqual("lThigh", skeleton.GetBoneName(HumanBodyBones.LeftUpperLeg)); + Assert.AreEqual("lShin", skeleton.GetBoneName(HumanBodyBones.LeftLowerLeg)); + Assert.AreEqual("lFoot", skeleton.GetBoneName(HumanBodyBones.LeftFoot)); + + Assert.AreEqual("rThigh", skeleton.GetBoneName(HumanBodyBones.RightUpperLeg)); + Assert.AreEqual("rShin", skeleton.GetBoneName(HumanBodyBones.RightLowerLeg)); + Assert.AreEqual("rFoot", skeleton.GetBoneName(HumanBodyBones.RightFoot)); + } + #endregion + } +#endif +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/BvhLoaderTests.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/BvhLoaderTests.cs.meta new file mode 100644 index 00000000..31c5676b --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/BvhLoaderTests.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 568764cb60017fc44ad4361d5a18b478 +timeCreated: 1534750164 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/UniHumanoid.Editor.Tests.asmdef b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/UniHumanoid.Editor.Tests.asmdef new file mode 100644 index 00000000..6ca95782 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/UniHumanoid.Editor.Tests.asmdef @@ -0,0 +1,15 @@ +{ + "name": "UniHumanoid.Editor.Tests", + "references": [ + "VRM", + "UniHumanoid" + ], + "optionalUnityReferences": [ + "TestAssemblies" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false +}
\ No newline at end of file diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/UniHumanoid.Editor.Tests.asmdef.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/UniHumanoid.Editor.Tests.asmdef.meta new file mode 100644 index 00000000..d28a564e --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/Tests/UniHumanoid.Editor.Tests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a76492d20b4f8464894b3a249f0759af +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/UniHumanoid.Editor.asmdef b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/UniHumanoid.Editor.asmdef new file mode 100644 index 00000000..0acc8574 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/UniHumanoid.Editor.asmdef @@ -0,0 +1,13 @@ +{ + "name": "UniHumanoid.Editor", + "references": [ + "VRM", + "UniHumanoid" + ], + "optionalUnityReferences": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false +}
\ No newline at end of file diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/UniHumanoid.Editor.asmdef.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/UniHumanoid.Editor.asmdef.meta new file mode 100644 index 00000000..597f702e --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/UniHumanoid.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1bd512e806d329b4c9f7fe1abe65e9db +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/bvhAssetPostprocessor.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/bvhAssetPostprocessor.cs new file mode 100644 index 00000000..4f08f26a --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/bvhAssetPostprocessor.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; +using UnityEditor; +using UnityEngine; + + +namespace UniHumanoid +{ + public class bvhAssetPostprocessor : AssetPostprocessor + { + static bool IsStreamingAsset(string path) + { + var baseFullPath = Path.GetFullPath(Application.dataPath + "/..").Replace("\\", "/"); + path = Path.Combine(baseFullPath, path).Replace("\\", "/"); + return path.StartsWith(Application.streamingAssetsPath + "/"); + } + + static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) + { + foreach (string path in importedAssets) + { + if (IsStreamingAsset(path)) + { + Debug.LogFormat("Skip StreamingAssets: {0}", path); + continue; + } + + var ext = Path.GetExtension(path).ToLower(); + if (ext == ".bvh") + { + Debug.LogFormat("ImportBvh: {0}", path); + var context = new BvhImporterContext(); + try + { + context.Parse(path); + context.Load(); + context.SaveAsAsset(); + context.Destroy(false); + } + catch(Exception ex) + { + Debug.LogError(ex); + context.Destroy(true); + } + } + } + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/bvhAssetPostprocessor.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/bvhAssetPostprocessor.cs.meta new file mode 100644 index 00000000..3a58175b --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Editor/bvhAssetPostprocessor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4283558adf39c194cb6c5d66d5a348de +timeCreated: 1517166107 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/LICENSE.md b/Assets/ThirdParty/VRM/VRM/UniHumanoid/LICENSE.md new file mode 100644 index 00000000..3299d454 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 ousttrue + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/LICENSE.md.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/LICENSE.md.meta new file mode 100644 index 00000000..24df7cd3 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/LICENSE.md.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3ea85fd858590174f98cc2cd4c3e083f +timeCreated: 1522228320 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier.meta new file mode 100644 index 00000000..2ecc6b90 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a90ca020c7788804ea91e172fa5efd1a +folderAsset: yes +timeCreated: 1524224672 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandPose.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandPose.cs new file mode 100644 index 00000000..5c94664e --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandPose.cs @@ -0,0 +1,185 @@ +using System; +using UnityEngine; + + +namespace UniHumanoid +{ + public class HandPoseModifier : IPoseModifier + { + public class HandPose + { + [Obsolete("Use ThumbStretch")] + public float ThumbStrech { get { return ThumbStretch; } set { ThumbStretch = value; } } + public float ThumbStretch; + public float ThumbSpread; + + [Obsolete("Use IndexStretch")] + public float IndexStrech { get { return IndexStretch; } set { IndexStretch = value; } } + public float IndexStretch; + public float IndexSpread; + + [Obsolete("Use MiddleStretch")] + public float MiddleStrech { get { return MiddleStretch; } set { MiddleStretch = value; } } + public float MiddleStretch; + public float MiddleSpread; + + [Obsolete("Use RingStretch")] + public float RingStrech { get { return RingStretch; } set { RingStretch = value; } } + public float RingStretch; + public float RingSpread; + + [Obsolete("Use LittleStretch")] + public float LittleStrech { get { return LittleStretch; } set { LittleStretch = value; } } + public float LittleStretch; + public float LittleSpread; + } + public HandPose LeftHandPose + { + get; + set; + } + public HandPose RightHandPose + { + get; + set; + } + + int LeftThumb1Stretched; + int LeftThumb2Stretched; + int LeftThumb3Stretched; + int LeftIndex1Stretched; + int LeftIndex2Stretched; + int LeftIndex3Stretched; + int LeftMiddle1Stretched; + int LeftMiddle2Stretched; + int LeftMiddle3Stretched; + int LeftRing1Stretched; + int LeftRing2Stretched; + int LeftRing3Stretched; + int LeftLittle1Stretched; + int LeftLittle2Stretched; + int LeftLittle3Stretched; + int LeftThumbSpread; + int LeftIndexSpread; + int LeftMiddleSpread; + int LeftRingSpread; + int LeftLittleSpread; + + int RightThumb1Stretched; + int RightThumb2Stretched; + int RightThumb3Stretched; + int RightIndex1Stretched; + int RightIndex2Stretched; + int RightIndex3Stretched; + int RightMiddle1Stretched; + int RightMiddle2Stretched; + int RightMiddle3Stretched; + int RightRing1Stretched; + int RightRing2Stretched; + int RightRing3Stretched; + int RightLittle1Stretched; + int RightLittle2Stretched; + int RightLittle3Stretched; + int RightThumbSpread; + int RightIndexSpread; + int RightMiddleSpread; + int RightRingSpread; + int RightLittleSpread; + + public HandPoseModifier() + { + LeftThumb1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Thumb 1 Stretched"); + LeftThumb2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Thumb 2 Stretched"); + LeftThumb3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Thumb 3 Stretched"); + LeftIndex1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Index 1 Stretched"); + LeftIndex2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Index 2 Stretched"); + LeftIndex3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Index 3 Stretched"); + LeftMiddle1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Middle 1 Stretched"); + LeftMiddle2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Middle 2 Stretched"); + LeftMiddle3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Middle 3 Stretched"); + LeftRing1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Ring 1 Stretched"); + LeftRing2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Ring 2 Stretched"); + LeftRing3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Ring 3 Stretched"); + LeftLittle1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Little 1 Stretched"); + LeftLittle2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Little 2 Stretched"); + LeftLittle3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Little 3 Stretched"); + LeftThumbSpread = Array.IndexOf(HumanTrait.MuscleName, "Left Thumb Spread"); + LeftIndexSpread = Array.IndexOf(HumanTrait.MuscleName, "Left Index Spread"); + LeftMiddleSpread = Array.IndexOf(HumanTrait.MuscleName, "Left Middle Spread"); + LeftRingSpread = Array.IndexOf(HumanTrait.MuscleName, "Left Ring Spread"); + LeftLittleSpread = Array.IndexOf(HumanTrait.MuscleName, "Left Little Spread"); + + RightThumb1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Thumb 1 Stretched"); + RightThumb2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Thumb 2 Stretched"); + RightThumb3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Thumb 3 Stretched"); + RightIndex1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Index 1 Stretched"); + RightIndex2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Index 2 Stretched"); + RightIndex3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Index 3 Stretched"); + RightMiddle1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Middle 1 Stretched"); + RightMiddle2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Middle 2 Stretched"); + RightMiddle3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Middle 3 Stretched"); + RightRing1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Ring 1 Stretched"); + RightRing2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Ring 2 Stretched"); + RightRing3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Ring 3 Stretched"); + RightLittle1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Little 1 Stretched"); + RightLittle2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Little 2 Stretched"); + RightLittle3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Little 3 Stretched"); + RightThumbSpread = Array.IndexOf(HumanTrait.MuscleName, "Right Thumb Spread"); + RightIndexSpread = Array.IndexOf(HumanTrait.MuscleName, "Right Index Spread"); + RightMiddleSpread = Array.IndexOf(HumanTrait.MuscleName, "Right Middle Spread"); + RightRingSpread = Array.IndexOf(HumanTrait.MuscleName, "Right Ring Spread"); + RightLittleSpread = Array.IndexOf(HumanTrait.MuscleName, "Right Little Spread"); + } + + public void Modify(ref HumanPose pose) + { + if (LeftHandPose != null) + { + pose.muscles[this.LeftThumb1Stretched] = LeftHandPose.ThumbStretch; + pose.muscles[this.LeftThumb2Stretched] = LeftHandPose.ThumbStretch; + pose.muscles[this.LeftThumb3Stretched] = LeftHandPose.ThumbStretch; + pose.muscles[this.LeftIndex1Stretched] = LeftHandPose.IndexStretch; + pose.muscles[this.LeftIndex2Stretched] = LeftHandPose.IndexStretch; + pose.muscles[this.LeftIndex3Stretched] = LeftHandPose.IndexStretch; + pose.muscles[this.LeftMiddle1Stretched] = LeftHandPose.MiddleStretch; + pose.muscles[this.LeftMiddle2Stretched] = LeftHandPose.MiddleStretch; + pose.muscles[this.LeftMiddle3Stretched] = LeftHandPose.MiddleStretch; + pose.muscles[this.LeftRing1Stretched] = LeftHandPose.RingStretch; + pose.muscles[this.LeftRing2Stretched] = LeftHandPose.RingStretch; + pose.muscles[this.LeftRing3Stretched] = LeftHandPose.RingStretch; + pose.muscles[this.LeftLittle1Stretched] = LeftHandPose.LittleStretch; + pose.muscles[this.LeftLittle2Stretched] = LeftHandPose.LittleStretch; + pose.muscles[this.LeftLittle3Stretched] = LeftHandPose.LittleStretch; + pose.muscles[this.LeftThumbSpread] = LeftHandPose.ThumbSpread; + pose.muscles[this.LeftIndexSpread] = LeftHandPose.IndexSpread; + pose.muscles[this.LeftMiddleSpread] = LeftHandPose.MiddleSpread; + pose.muscles[this.LeftRingSpread] = LeftHandPose.RingSpread; + pose.muscles[this.LeftLittleSpread] = LeftHandPose.LittleSpread; + } + + if (RightHandPose != null) + { + pose.muscles[this.RightThumb1Stretched] = RightHandPose.ThumbStretch; + pose.muscles[this.RightThumb2Stretched] = RightHandPose.ThumbStretch; + pose.muscles[this.RightThumb3Stretched] = RightHandPose.ThumbStretch; + pose.muscles[this.RightIndex1Stretched] = RightHandPose.IndexStretch; + pose.muscles[this.RightIndex2Stretched] = RightHandPose.IndexStretch; + pose.muscles[this.RightIndex3Stretched] = RightHandPose.IndexStretch; + pose.muscles[this.RightMiddle1Stretched] = RightHandPose.MiddleStretch; + pose.muscles[this.RightMiddle2Stretched] = RightHandPose.MiddleStretch; + pose.muscles[this.RightMiddle3Stretched] = RightHandPose.MiddleStretch; + pose.muscles[this.RightRing1Stretched] = RightHandPose.RingStretch; + pose.muscles[this.RightRing2Stretched] = RightHandPose.RingStretch; + pose.muscles[this.RightRing3Stretched] = RightHandPose.RingStretch; + pose.muscles[this.RightLittle1Stretched] = RightHandPose.LittleStretch; + pose.muscles[this.RightLittle2Stretched] = RightHandPose.LittleStretch; + pose.muscles[this.RightLittle3Stretched] = RightHandPose.LittleStretch; + pose.muscles[this.RightThumbSpread] = RightHandPose.ThumbSpread; + pose.muscles[this.RightIndexSpread] = RightHandPose.IndexSpread; + pose.muscles[this.RightMiddleSpread] = RightHandPose.MiddleSpread; + pose.muscles[this.RightRingSpread] = RightHandPose.RingSpread; + pose.muscles[this.RightLittleSpread] = RightHandPose.LittleSpread; + } + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandPose.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandPose.cs.meta new file mode 100644 index 00000000..a6b02c99 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandPose.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 14d18bc5a296a894eb7154d3f5f0e18b +timeCreated: 1523606797 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandRig.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandRig.cs new file mode 100644 index 00000000..aa3a65fa --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandRig.cs @@ -0,0 +1,103 @@ +using UnityEngine; +using UnityEngine.Serialization; + + +namespace UniHumanoid +{ + public class HandRig : MonoBehaviour + { + [SerializeField] + Animator m_animator; + public Animator Animator + { + get { return m_animator; } + } + + [FormerlySerializedAs("LeftStrech")] + [SerializeField, Range(-1, 1)] + public float LeftStretch; + + [SerializeField, Range(-1, 1)] + public float LeftSpread; + + [FormerlySerializedAs("RightStrech")] + [SerializeField, Range(-1, 1)] + public float RightStretch; + + [SerializeField, Range(-1, 1)] + public float RightSpread; + + private void Reset() + { + m_animator = GetComponent<Animator>(); + } + + HumanPoseHandler m_handler; + public static HumanPoseHandler GetHandler(Animator animator) + { + if (animator == null) + { + return null; + } + if (animator.avatar == null) + { + return null; + } + if (!animator.avatar.isValid + || !animator.avatar.isHuman) + { + return null; + } + return new HumanPoseHandler(animator.avatar, animator.transform); + } + + HandPoseModifier m_updater; + + private void Awake() + { + m_handler = GetHandler(m_animator); + if (m_handler == null) + { + enabled = false; + return; + } + m_updater = new HandPoseModifier(); + } + + HandPoseModifier.HandPose m_leftHand = new HandPoseModifier.HandPose(); + HandPoseModifier.HandPose m_rightHand = new HandPoseModifier.HandPose(); + HumanPose m_pose; + + private void Update() + { + m_leftHand.ThumbStretch = LeftStretch; + m_leftHand.ThumbSpread = LeftSpread; + m_leftHand.IndexStretch = LeftStretch; + m_leftHand.IndexSpread = LeftSpread; + m_leftHand.MiddleStretch = LeftStretch; + m_leftHand.MiddleSpread = LeftSpread; + m_leftHand.RingStretch = LeftStretch; + m_leftHand.RingSpread = LeftSpread; + m_leftHand.LittleStretch = LeftStretch; + m_leftHand.LittleSpread = LeftSpread; + + m_rightHand.ThumbStretch = RightStretch; + m_rightHand.ThumbSpread = RightSpread; + m_rightHand.IndexStretch = RightStretch; + m_rightHand.IndexSpread = RightSpread; + m_rightHand.MiddleStretch = RightStretch; + m_rightHand.MiddleSpread = RightSpread; + m_rightHand.RingStretch = RightStretch; + m_rightHand.RingSpread = RightSpread; + m_rightHand.LittleStretch = RightStretch; + m_rightHand.LittleSpread = RightSpread; + + m_updater.LeftHandPose = m_leftHand; + m_updater.RightHandPose = m_rightHand; + + m_handler.GetHumanPose(ref m_pose); + m_updater.Modify(ref m_pose); + m_handler.SetHumanPose(ref m_pose); + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandRig.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandRig.cs.meta new file mode 100644 index 00000000..2a5cb41f --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/HandRig.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 45d55d80a64783c41ace70d5d81db454 +timeCreated: 1523602613 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/IPoseModifier.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/IPoseModifier.cs new file mode 100644 index 00000000..bcc178dd --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/IPoseModifier.cs @@ -0,0 +1,10 @@ +using UnityEngine; + + +namespace UniHumanoid +{ + public interface IPoseModifier + { + void Modify(ref HumanPose pose); + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/IPoseModifier.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/IPoseModifier.cs.meta new file mode 100644 index 00000000..4e4b1d9d --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/PoseModifier/IPoseModifier.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 973f36da309a48d4ea3c5526a51e957f +timeCreated: 1523606728 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/README.md b/Assets/ThirdParty/VRM/VRM/UniHumanoid/README.md new file mode 100644 index 00000000..2b155952 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/README.md @@ -0,0 +1,77 @@ +# UniHumanoid + +Unity humanoid utility with bvh importer. + +# License + +* [MIT](./LICENSE.md) + +# BVH runtime loader + +```cs +var context = new BvhImporterContext(); +context.Parse(path); +context.Load(); // create Skeleton hierarchy and mesh for visualize +GameObject root = context.Root; +``` + +## RuntimeLoader +* Scenes/RuntimeBvhLoader.unity + +## RuntimeLoader and PoseTransfer +Load BVH and transfer pose to any model with humanoid avatar. + +* Scenes/PoseTransfer.unity + + + + + +# Load bvh and create prefab with AnimationClip + +Drop bvh file to Assets folder. +Then, AssetPostprocessor import bvh file. + +* create a hierarchy prefab +* create a humanoid Avatar +* create a legacy mode AnimationClip +* create a skinned mesh for preview + + + +Instanciate prefab to scene. + + + +That object can play. + +# BoneMapping + +This script help create human avatar from exist GameObject hierarchy. +First, attach this script to root GameObject that has Animator. + +Next, setup below. + +* model position is origin +* model look at +z orientation +* model root node rotation is Quatenion.identity +* Set hips bone. + +press Guess bone mapping. +If fail to guess bone mapping, you can set bones manually. + +Optional, press Ensure T-Pose. +Create avatar. + + + +These humanoids imported by [UniGLTF](https://github.com/ousttrue/UniGLTF) and created human avatar by BoneMapping. + + + +# Download BVH files + +* https://sites.google.com/a/cgspeed.com/cgspeed/motion-capture +* http://mocapdata.com/ +* http://www.thetrailerspark.com/download/Mocap/Packed/EYES-JAPAN/BVH/ + diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/README.md.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/README.md.meta new file mode 100644 index 00000000..832294e8 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/README.md.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: be513cfaa8530114d85f1e8e0f29708a +timeCreated: 1517370218 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Resources.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Resources.meta new file mode 100644 index 00000000..2285cdc6 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Resources.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c61106d290c827b49b7a6e3f6497bd3f +folderAsset: yes +timeCreated: 1519379142 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Resources/T-Pose.pose.asset b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Resources/T-Pose.pose.asset new file mode 100644 index 00000000..d6a055f2 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Resources/T-Pose.pose.asset @@ -0,0 +1,111 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4fdf4ef744a103a4ca01657c00d7fec2, type: 3} + m_Name: T-Pose.pose + m_EditorClassIdentifier: + bodyPosition: {x: 0.0024022944, y: 1.000028, z: 0.0019842784} + bodyRotation: {x: -0, y: 0.000000014901161, z: 0.000000014901161, w: 1} + muscles: + - -0.000000010672161 + - -6.3611094e-16 + - 6.3611094e-16 + - -0.00000055495286 + - 0.00000026851825 + - -0.0000000012914859 + - 0 + - 0 + - 0 + - 0.00000029369042 + - -0.0000005362765 + - 0.00000026918045 + - 0.00000052293626 + - 0.00000012148932 + - 0.0000003683441 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0.5957687 + - -0.018923696 + - 0.2105892 + - 1.0025908 + - -0.13775763 + - -0.002854546 + - -0.020644147 + - -0.0000060816024 + - 0.5957681 + - -0.01892539 + - 0.2106165 + - 1.0025909 + - -0.13777769 + - -0.0028554748 + - -0.020645387 + - -2.0029848e-12 + - 0.0000003415094 + - -0.00000011383648 + - 0.39829093 + - 0.3004907 + - -0.030618805 + - 0.999798 + - 0.03679788 + - -0.0025310651 + - 0.00030608202 + - 6.7851816e-15 + - -0.00000045534588 + - 0.39829168 + - 0.3004914 + - -0.030611247 + - 0.9997984 + - 0.03679079 + - -0.0025303008 + - 0.00030552692 + - -0.68517876 + - 0.4567073 + - 0.64590156 + - 0.6459016 + - 0.66896635 + - -0.40027583 + - 0.8113421 + - 0.81134295 + - 0.66770303 + - -0.62352574 + - 0.8111324 + - 0.811132 + - 0.6683899 + - -0.5698266 + - 0.8116428 + - 0.8116354 + - 0.6692385 + - -0.44004643 + - 0.8082721 + - 0.8082728 + - -0.68401676 + - 0.45769995 + - 0.6457741 + - 0.64577323 + - 0.6689646 + - -0.40025005 + - 0.81134063 + - 0.81134117 + - 0.6677078 + - -0.62352294 + - 0.81113243 + - 0.8111291 + - 0.6683884 + - -0.5698764 + - 0.81164306 + - 0.8116342 + - 0.66924673 + - -0.44011596 + - 0.808278 + - 0.8082771 diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Resources/T-Pose.pose.asset.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Resources/T-Pose.pose.asset.meta new file mode 100644 index 00000000..bbcce4e8 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Resources/T-Pose.pose.asset.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 879e332f84a378c4da3b87af13da3e85 +timeCreated: 1519376738 +licenseType: Free +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes.meta new file mode 100644 index 00000000..dbc08374 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9edc7cfd64210934e817c98db16bdaea +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/HumanBuilderTest.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/HumanBuilderTest.cs new file mode 100644 index 00000000..6c81c802 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/HumanBuilderTest.cs @@ -0,0 +1,149 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + + +namespace UniHumanoid +{ + [RequireComponent(typeof(Animator))] + public class HumanBuilderTest : MonoBehaviour + { + [SerializeField] + Material m_material; + + class SkeletonBuilder + { + Dictionary<HumanBodyBones, Transform> m_skeleton = new Dictionary<HumanBodyBones, Transform>(); + public IDictionary<HumanBodyBones, Transform> Skeleton + { + get { return m_skeleton; } + } + + Dictionary<HumanBodyBones, Vector3> m_boneTail = new Dictionary<HumanBodyBones, Vector3>(); + Transform m_root; + + public SkeletonBuilder(Transform root) + { + m_root = root; + } + + void Add(HumanBodyBones key, Transform parent, Vector3 headPosition, Vector3 tailPosition) + { + var bone = new GameObject(key.ToString()).transform; + bone.SetParent(parent, false); + bone.localPosition = headPosition; + m_skeleton[key] = bone; + m_boneTail[key] = tailPosition; + } + + void Add(HumanBodyBones key, HumanBodyBones parentKey, Vector3 tailPosition) + { + Add(key, m_skeleton[parentKey], m_boneTail[parentKey], tailPosition); + } + + #region Spine + public void AddHips(float height, float len) + { + Add(HumanBodyBones.Hips, m_root, new Vector3(0, height, 0), new Vector3(0, len, 0)); + } + + public void AddSpine(float len) + { + Add(HumanBodyBones.Spine, HumanBodyBones.Hips, new Vector3(0, len, 0)); + } + + public void AddChest(float len) + { + Add(HumanBodyBones.Chest, HumanBodyBones.Spine, new Vector3(0, len, 0)); + } + + public void AddNeck(float len) + { + Add(HumanBodyBones.Neck, HumanBodyBones.Chest, new Vector3(0, len, 0)); + } + + public void AddHead(float len) + { + Add(HumanBodyBones.Head, HumanBodyBones.Neck, new Vector3(0, len, 0)); + } + #endregion + + public void AddArm(float shoulder, float upper, float lower, float hand) + { + Add(HumanBodyBones.LeftShoulder, HumanBodyBones.Chest, new Vector3(-shoulder, 0, 0)); + Add(HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftShoulder, new Vector3(-upper, 0, 0)); + Add(HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftUpperArm, new Vector3(-lower, 0, 0)); + Add(HumanBodyBones.LeftHand, HumanBodyBones.LeftLowerArm, new Vector3(-hand, 0, 0)); + + Add(HumanBodyBones.RightShoulder, HumanBodyBones.Chest, new Vector3(shoulder, 0, 0)); + Add(HumanBodyBones.RightUpperArm, HumanBodyBones.RightShoulder, new Vector3(upper, 0, 0)); + Add(HumanBodyBones.RightLowerArm, HumanBodyBones.RightUpperArm, new Vector3(lower, 0, 0)); + Add(HumanBodyBones.RightHand, HumanBodyBones.RightLowerArm, new Vector3(hand, 0, 0)); + } + + public void AddLeg(float distance, float upper, float lower, float foot, float toe) + { + Add(HumanBodyBones.LeftUpperLeg, m_skeleton[HumanBodyBones.Hips], new Vector3(-distance, 0, 0), new Vector3(0, -upper, 0)); + Add(HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftUpperLeg, new Vector3(0, -lower, 0)); + Add(HumanBodyBones.LeftFoot, HumanBodyBones.LeftLowerLeg, new Vector3(0, -foot, foot)); + Add(HumanBodyBones.LeftToes, HumanBodyBones.LeftFoot, new Vector3(0, 0, toe)); + + Add(HumanBodyBones.RightUpperLeg, m_skeleton[HumanBodyBones.Hips], new Vector3(distance, 0, 0), new Vector3(0, -upper, 0)); + Add(HumanBodyBones.RightLowerLeg, HumanBodyBones.RightUpperLeg, new Vector3(0, -lower, 0)); + Add(HumanBodyBones.RightFoot, HumanBodyBones.RightLowerLeg, new Vector3(0, -foot, foot)); + Add(HumanBodyBones.RightToes, HumanBodyBones.RightFoot, new Vector3(0, 0, toe)); + } + } + + void OnEnable() + { + BuildSkeleton(transform); + } + + private void BuildSkeleton(Transform root) + { + var position = root.position; + root.position = Vector3.zero; + + try + { + // hips -> spine -> chest + var builder = new SkeletonBuilder(root); + builder.AddHips(0.8f, 0.2f); + builder.AddSpine(0.1f); + builder.AddChest(0.2f); + builder.AddNeck(0.1f); + builder.AddHead(0.2f); + builder.AddArm(0.1f, 0.3f, 0.3f, 0.1f); + builder.AddLeg(0.1f, 0.3f, 0.4f, 0.1f, 0.1f); + + var description = AvatarDescription.Create(builder.Skeleton); + var animator = GetComponent<Animator>(); + animator.avatar = description.CreateAvatar(root); + + // create SkinnedMesh for bone visualize + var renderer = SkeletonMeshUtility.CreateRenderer(animator); + + if (m_material == null) + { + m_material = new Material(Shader.Find("Standard")); + } + renderer.sharedMaterial = m_material; + //root.gameObject.AddComponent<BoneMapping>(); + + var transfer = GetComponent<HumanPoseTransfer>(); + if (transfer != null) + { + transfer.Avatar = animator.avatar; + transfer.Setup(); + } + } + finally + { + // restore position + root.position = position; + } + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/HumanBuilderTest.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/HumanBuilderTest.cs.meta new file mode 100644 index 00000000..420a63cd --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/HumanBuilderTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dfdcf658d2da05649974b59b849de74c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/PoseTransfer.unity b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/PoseTransfer.unity new file mode 100644 index 00000000..f9507a2b --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/PoseTransfer.unity @@ -0,0 +1,691 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &406922205 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 406922208} + - component: {fileID: 406922207} + - component: {fileID: 406922206} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &406922206 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 406922205} + m_Enabled: 1 +--- !u!20 &406922207 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 406922205} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &406922208 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 406922205} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &540606465 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 540606468} + - component: {fileID: 540606467} + - component: {fileID: 540606466} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &540606466 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 540606465} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &540606467 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 540606465} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &540606468 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 540606465} + 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: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &745406201 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 745406206} + - component: {fileID: 745406205} + - component: {fileID: 745406204} + - component: {fileID: 745406203} + - component: {fileID: 745406202} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &745406202 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 745406201} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7b994e1476323bf4fbe1ae28bea164f2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_openButton: {fileID: 860463875} + m_dst: {fileID: 948407063} +--- !u!114 &745406203 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 745406201} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &745406204 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 745406201} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &745406205 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 745406201} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &745406206 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 745406201} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 860463874} + m_Father: {fileID: 0} + 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: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &860463873 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 860463874} + - component: {fileID: 860463877} + - component: {fileID: 860463876} + - component: {fileID: 860463875} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &860463874 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860463873} + 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: 2080820046} + m_Father: {fileID: 745406206} + 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: 0, y: 0} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0, y: 1} +--- !u!114 &860463875 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860463873} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + 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_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_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 860463876} + m_OnClick: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &860463876 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860463873} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + 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 +--- !u!222 &860463877 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860463873} + m_CullTransparentMesh: 0 +--- !u!1 &948407059 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 948407062} + - component: {fileID: 948407061} + - component: {fileID: 948407060} + - component: {fileID: 948407063} + m_Layer: 0 + m_Name: Target + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &948407060 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 948407059} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dfdcf658d2da05649974b59b849de74c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_material: {fileID: 2100000, guid: 94b4b45712e88334c9e7c5ecc53c50e6, type: 2} +--- !u!95 &948407061 +Animator: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 948407059} + m_Enabled: 1 + m_Avatar: {fileID: 0} + m_Controller: {fileID: 0} + m_CullingMode: 0 + m_UpdateMode: 0 + m_ApplyRootMotion: 0 + m_LinearVelocityBlending: 0 + m_WarningMessage: + m_HasTransformHierarchy: 1 + m_AllowConstantClipSamplingOptimization: 1 + m_KeepAnimatorControllerStateOnDisable: 0 +--- !u!4 &948407062 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 948407059} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -1, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &948407063 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 948407059} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e5548e4785b76854cbbf3f6d9a8e9c1d, type: 3} + m_Name: + m_EditorClassIdentifier: + SourceType: 0 + Avatar: {fileID: 0} + Source: {fileID: 0} + PoseClip: {fileID: 0} +--- !u!1 &1536726113 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1536726115} + - component: {fileID: 1536726114} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &1536726114 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1536726113} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &1536726115 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1536726113} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &2080820045 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2080820046} + - component: {fileID: 2080820048} + - component: {fileID: 2080820047} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2080820046 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2080820045} + 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: 860463874} + 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 &2080820047 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2080820045} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, 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_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + 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 +--- !u!222 &2080820048 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2080820045} + m_CullTransparentMesh: 0 diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/PoseTransfer.unity.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/PoseTransfer.unity.meta new file mode 100644 index 00000000..04c014c8 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/PoseTransfer.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ae847f673eb3e6f4a95f61b4658b806a +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.cs new file mode 100644 index 00000000..afc3727c --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.cs @@ -0,0 +1,83 @@ +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.UI; +using UniHumanoid; +using System.IO; +using System; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniHumanoid +{ + public class RuntimeBvhLoader : MonoBehaviour + { + [SerializeField] + Button m_openButton = default; + + [SerializeField] + HumanPoseTransfer m_dst = default; + + UnityAction m_onClick; + + private void Awake() + { + m_onClick = new UnityEngine.Events.UnityAction(OnClick); + } + + private void OnEnable() + { + m_openButton.onClick.AddListener(m_onClick); + } + + private void OnDisable() + { + m_openButton.onClick.RemoveListener(m_onClick); + } + + static string m_lastDir; + + public void OnClick() + { +#if UNITY_EDITOR + var path = EditorUtility.OpenFilePanel("open bvh", m_lastDir, "bvh"); + if (String.IsNullOrEmpty(path)) + { + return; + } + m_lastDir = Path.GetDirectoryName(path); +#else + string path=null; +#endif + +#pragma warning disable 4014 + Open(path); +#pragma warning restore 4014 + } + + BvhImporterContext m_context; + + void Open(string path) + { + Debug.LogFormat("Open: {0}", path); + if (m_context != null) + { + m_context.Destroy(true); + m_context = null; + } + + m_context = new BvhImporterContext(); + m_context.Parse(path); + m_context.Load(); + + var src = m_context.Root.AddComponent<HumanPoseTransfer>(); + + if (m_dst != null) + { + m_dst.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer; + m_dst.Source = src; + } + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.cs.meta new file mode 100644 index 00000000..0fae39bc --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b994e1476323bf4fbe1ae28bea164f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.unity b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.unity new file mode 100644 index 00000000..c1e610d8 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.unity @@ -0,0 +1,615 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &406922205 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 406922208} + - component: {fileID: 406922207} + - component: {fileID: 406922206} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &406922206 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 406922205} + m_Enabled: 1 +--- !u!20 &406922207 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 406922205} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &406922208 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 406922205} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &540606465 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 540606468} + - component: {fileID: 540606467} + - component: {fileID: 540606466} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &540606466 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 540606465} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &540606467 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 540606465} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &540606468 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 540606465} + 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: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &745406201 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 745406206} + - component: {fileID: 745406205} + - component: {fileID: 745406204} + - component: {fileID: 745406203} + - component: {fileID: 745406202} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &745406202 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 745406201} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7b994e1476323bf4fbe1ae28bea164f2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_openButton: {fileID: 860463875} + m_dst: {fileID: 0} +--- !u!114 &745406203 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 745406201} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &745406204 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 745406201} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &745406205 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 745406201} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &745406206 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 745406201} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 860463874} + m_Father: {fileID: 0} + 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: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &860463873 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 860463874} + - component: {fileID: 860463877} + - component: {fileID: 860463876} + - component: {fileID: 860463875} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &860463874 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860463873} + 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: 2080820046} + m_Father: {fileID: 745406206} + 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: 0, y: 0} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0, y: 1} +--- !u!114 &860463875 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860463873} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + 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_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_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 860463876} + m_OnClick: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &860463876 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860463873} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + 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 +--- !u!222 &860463877 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 860463873} + m_CullTransparentMesh: 0 +--- !u!1 &1536726113 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1536726115} + - component: {fileID: 1536726114} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &1536726114 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1536726113} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &1536726115 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1536726113} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &2080820045 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2080820046} + - component: {fileID: 2080820048} + - component: {fileID: 2080820047} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2080820046 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2080820045} + 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: 860463874} + 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 &2080820047 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2080820045} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, 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_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + 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 +--- !u!222 &2080820048 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2080820045} + m_CullTransparentMesh: 0 diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.unity.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.unity.meta new file mode 100644 index 00000000..2a3f1964 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/RuntimeBvhLoader.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 99665560be9c32e4d9f7813b076c92ee +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/target.mat b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/target.mat new file mode 100644 index 00000000..1136c07c --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/target.mat @@ -0,0 +1,76 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: target + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.60773194, g: 0.8584906, b: 0.14983091, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/target.mat.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/target.mat.meta new file mode 100644 index 00000000..133fed93 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scenes/target.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 94b4b45712e88334c9e7c5ecc53c50e6 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts.meta new file mode 100644 index 00000000..a7876e5e --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 64819743741f38e43b64a7d6add8cea9 +folderAsset: yes +timeCreated: 1517166088 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AnimationClipUtility.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AnimationClipUtility.cs new file mode 100644 index 00000000..5d06e5f6 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AnimationClipUtility.cs @@ -0,0 +1,134 @@ +using System.Collections.Generic; +using UnityEngine; + + +namespace UniHumanoid +{ + public static class AnimationClipUtility + { + static Dictionary<string, string> TraitPropMap = new Dictionary<string, string> +{ +{"Left Thumb 1 Stretched", "LeftHand.Thumb.1 Stretched"}, +{"Left Thumb Spread", "LeftHand.Thumb Spread"}, +{"Left Thumb 2 Stretched", "LeftHand.Thumb.2 Stretched"}, +{"Left Thumb 3 Stretched", "LeftHand.Thumb.3 Stretched"}, +{"Left Index 1 Stretched", "LeftHand.Index.1 Stretched"}, +{"Left Index Spread", "LeftHand.Index Spread"}, +{"Left Index 2 Stretched", "LeftHand.Index.2 Stretched"}, +{"Left Index 3 Stretched", "LeftHand.Index.3 Stretched"}, +{"Left Middle 1 Stretched", "LeftHand.Middle.1 Stretched"}, +{"Left Middle Spread", "LeftHand.Middle Spread"}, +{"Left Middle 2 Stretched", "LeftHand.Middle.2 Stretched"}, +{"Left Middle 3 Stretched", "LeftHand.Middle.3 Stretched"}, +{"Left Ring 1 Stretched", "LeftHand.Ring.1 Stretched"}, +{"Left Ring Spread", "LeftHand.Ring Spread"}, +{"Left Ring 2 Stretched", "LeftHand.Ring.2 Stretched"}, +{"Left Ring 3 Stretched", "LeftHand.Ring.3 Stretched"}, +{"Left Little 1 Stretched", "LeftHand.Little.1 Stretched"}, +{"Left Little Spread", "LeftHand.Little Spread"}, +{"Left Little 2 Stretched", "LeftHand.Little.2 Stretched"}, +{"Left Little 3 Stretched", "LeftHand.Little.3 Stretched"}, +{"Right Thumb 1 Stretched", "RightHand.Thumb.1 Stretched"}, +{"Right Thumb Spread", "RightHand.Thumb Spread"}, +{"Right Thumb 2 Stretched", "RightHand.Thumb.2 Stretched"}, +{"Right Thumb 3 Stretched", "RightHand.Thumb.3 Stretched"}, +{"Right Index 1 Stretched", "RightHand.Index.1 Stretched"}, +{"Right Index Spread", "RightHand.Index Spread"}, +{"Right Index 2 Stretched", "RightHand.Index.2 Stretched"}, +{"Right Index 3 Stretched", "RightHand.Index.3 Stretched"}, +{"Right Middle 1 Stretched", "RightHand.Middle.1 Stretched"}, +{"Right Middle Spread", "RightHand.Middle Spread"}, +{"Right Middle 2 Stretched", "RightHand.Middle.2 Stretched"}, +{"Right Middle 3 Stretched", "RightHand.Middle.3 Stretched"}, +{"Right Ring 1 Stretched", "RightHand.Ring.1 Stretched"}, +{"Right Ring Spread", "RightHand.Ring Spread"}, +{"Right Ring 2 Stretched", "RightHand.Ring.2 Stretched"}, +{"Right Ring 3 Stretched", "RightHand.Ring.3 Stretched"}, +{"Right Little 1 Stretched", "RightHand.Little.1 Stretched"}, +{"Right Little Spread", "RightHand.Little Spread"}, +{"Right Little 2 Stretched", "RightHand.Little.2 Stretched"}, +{"Right Little 3 Stretched", "RightHand.Little.3 Stretched"}, +}; + + public static AnimationClip CreateAnimationClipFromHumanPose(HumanPose pose) + { + var clip = new AnimationClip(); + + // pos + { + var curve = new AnimationCurve(new Keyframe[] + { + new Keyframe(0, pose.bodyPosition.x), + }); + var muscle = "RootT.x"; + clip.SetCurve(null, typeof(Animator), muscle, curve); + } + { + var curve = new AnimationCurve(new Keyframe[] + { + new Keyframe(0, pose.bodyPosition.y), + }); + var muscle = "RootT.y"; + clip.SetCurve(null, typeof(Animator), muscle, curve); + } + { + var curve = new AnimationCurve(new Keyframe[] + { + new Keyframe(0, pose.bodyPosition.z), + }); + var muscle = "RootT.z"; + clip.SetCurve(null, typeof(Animator), muscle, curve); + } + + // rot + { + var curve = new AnimationCurve(new Keyframe[] + { + new Keyframe(0, pose.bodyRotation.x), + }); + var muscle = "RootQ.x"; + clip.SetCurve(null, typeof(Animator), muscle, curve); + } + { + var curve = new AnimationCurve(new Keyframe[] + { + new Keyframe(0, pose.bodyRotation.y), + }); + var muscle = "RootQ.y"; + clip.SetCurve(null, typeof(Animator), muscle, curve); + } + { + var curve = new AnimationCurve(new Keyframe[] + { + new Keyframe(0, pose.bodyRotation.z), + }); + var muscle = "RootQ.z"; + clip.SetCurve(null, typeof(Animator), muscle, curve); + } + { + var curve = new AnimationCurve(new Keyframe[] + { + new Keyframe(0, pose.bodyRotation.w), + }); + var muscle = "RootQ.w"; + clip.SetCurve(null, typeof(Animator), muscle, curve); + } + + // muscles + for (int i = 0; i < HumanTrait.MuscleCount; ++i) + { + var curve = new AnimationCurve(new Keyframe[] + { + new Keyframe(0, pose.muscles[i]), + }); + var muscle = HumanTrait.MuscleName[i]; + if (TraitPropMap.ContainsKey(muscle)) + { + muscle = TraitPropMap[muscle]; + } + clip.SetCurve(null, typeof(Animator), muscle, curve); + } + return clip; + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AnimationClipUtility.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AnimationClipUtility.cs.meta new file mode 100644 index 00000000..54fb7ef2 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AnimationClipUtility.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: e13984a5449ddb843b03e21c3409df67 +timeCreated: 1516590895 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AvatarDescription.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AvatarDescription.cs new file mode 100644 index 00000000..05a3abd6 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AvatarDescription.cs @@ -0,0 +1,269 @@ +#if UNITY_EDITOR +using UnityEditor; +#endif +using UnityEngine; +using System; +using System.Linq; +using System.Collections.Generic; + + +namespace UniHumanoid +{ + [Serializable] + public struct BoneLimit + { + public HumanBodyBones humanBone; + public string boneName; + public bool useDefaultValues; + public Vector3 min; + public Vector3 max; + public Vector3 center; + public float axisLength; + private static string[] cashedHumanTraitBoneName = null; + + public static BoneLimit From(HumanBone bone) + { + return new BoneLimit + { + humanBone = (HumanBodyBones) Enum.Parse(typeof(HumanBodyBones), bone.humanName.Replace(" ", ""), true), + boneName = bone.boneName, + useDefaultValues = bone.limit.useDefaultValues, + min = bone.limit.min, + max = bone.limit.max, + center = bone.limit.center, + axisLength = bone.limit.axisLength, + }; + } + + public static String ToHumanBoneName(HumanBodyBones b) + { + // 呼び出し毎にGCが発生するのでキャッシュする + if (cashedHumanTraitBoneName == null) + { + cashedHumanTraitBoneName = HumanTrait.BoneName; + } + + foreach (var x in cashedHumanTraitBoneName) + { + if (x.Replace(" ", "") == b.ToString()) + { + return x; + } + } + + throw new KeyNotFoundException(); + } + + public HumanBone ToHumanBone() + { + return new HumanBone + { + boneName = boneName, + humanName = ToHumanBoneName(humanBone), + limit = new HumanLimit + { + useDefaultValues = useDefaultValues, + axisLength = axisLength, + center = center, + max = max, + min = min + }, + }; + } + } + + [Serializable] + public class AvatarDescription : ScriptableObject + { + public float armStretch = 0.05f; + public float legStretch = 0.05f; + public float upperArmTwist = 0.5f; + public float lowerArmTwist = 0.5f; + public float upperLegTwist = 0.5f; + public float lowerLegTwist = 0.5f; + public float feetSpacing = 0; + public bool hasTranslationDoF; + public BoneLimit[] human; + + public HumanDescription ToHumanDescription(Transform root) + { + var transforms = root.GetComponentsInChildren<Transform>(); + var skeletonBones = new SkeletonBone[transforms.Length]; + var index = 0; + foreach (var t in transforms) + { + skeletonBones[index] = t.ToSkeletonBone(); + index++; + } + + var humanBones = new HumanBone[human.Length]; + index = 0; + foreach (var bonelimit in human) + { + humanBones[index] = bonelimit.ToHumanBone(); + index++; + } + + + return new HumanDescription + { + skeleton = skeletonBones, + human = humanBones, + armStretch = armStretch, + legStretch = legStretch, + upperArmTwist = upperArmTwist, + lowerArmTwist = lowerArmTwist, + upperLegTwist = upperLegTwist, + lowerLegTwist = lowerLegTwist, + feetSpacing = feetSpacing, + hasTranslationDoF = hasTranslationDoF, + }; + } + + public Avatar CreateAvatar(Transform root) + { + return AvatarBuilder.BuildHumanAvatar(root.gameObject, ToHumanDescription(root)); + } + + public Avatar CreateAvatarAndSetup(Transform root) + { + var avatar = CreateAvatar(root); + avatar.name = name; + + var animator = root.GetComponent<Animator>(); + if (animator != null) + { + var positionMap = root.Traverse().ToDictionary(x => x, x => x.position); + animator.avatar = avatar; + foreach (var x in root.Traverse()) + { + x.position = positionMap[x]; + } + } + + var transfer = root.GetComponent<HumanPoseTransfer>(); + if (transfer != null) + { + transfer.Avatar = avatar; + } + + return avatar; + } + +#if UNITY_EDITOR + public static AvatarDescription CreateFrom(Avatar avatar) + { + var description = default(HumanDescription); + if (!GetHumanDescription(avatar, ref description)) + { + return null; + } + + return CreateFrom(description); + } +#endif + + public static AvatarDescription CreateFrom(HumanDescription description) + { + var avatarDescription = ScriptableObject.CreateInstance<AvatarDescription>(); + avatarDescription.name = "AvatarDescription"; + avatarDescription.armStretch = description.armStretch; + avatarDescription.legStretch = description.legStretch; + avatarDescription.feetSpacing = description.feetSpacing; + avatarDescription.hasTranslationDoF = description.hasTranslationDoF; + avatarDescription.lowerArmTwist = description.lowerArmTwist; + avatarDescription.lowerLegTwist = description.lowerLegTwist; + avatarDescription.upperArmTwist = description.upperArmTwist; + avatarDescription.upperLegTwist = description.upperLegTwist; + avatarDescription.human = description.human.Select(BoneLimit.From).ToArray(); + return avatarDescription; + } + + public static AvatarDescription Create(AvatarDescription src = null) + { + var avatarDescription = ScriptableObject.CreateInstance<AvatarDescription>(); + avatarDescription.name = "AvatarDescription"; + if (src != null) + { + avatarDescription.armStretch = src.armStretch; + avatarDescription.legStretch = src.legStretch; + avatarDescription.feetSpacing = src.feetSpacing; + avatarDescription.upperArmTwist = src.upperArmTwist; + avatarDescription.lowerArmTwist = src.lowerArmTwist; + avatarDescription.upperLegTwist = src.upperLegTwist; + avatarDescription.lowerLegTwist = src.lowerLegTwist; + } + else + { + avatarDescription.armStretch = 0.05f; + avatarDescription.legStretch = 0.05f; + avatarDescription.feetSpacing = 0.0f; + avatarDescription.lowerArmTwist = 0.5f; + avatarDescription.upperArmTwist = 0.5f; + avatarDescription.upperLegTwist = 0.5f; + avatarDescription.lowerLegTwist = 0.5f; + } + + return avatarDescription; + } + + public static AvatarDescription Create(Transform[] boneTransforms, Skeleton skeleton) + { + return Create(skeleton.Bones.Select( + x => new KeyValuePair<HumanBodyBones, Transform>(x.Key, boneTransforms[x.Value]))); + } + + public static AvatarDescription Create(IEnumerable<KeyValuePair<HumanBodyBones, Transform>> skeleton) + { + var description = Create(); + description.SetHumanBones(skeleton); + return description; + } + + public void SetHumanBones(IEnumerable<KeyValuePair<HumanBodyBones, Transform>> skeleton) + { + human = skeleton.Select(x => + { + return new BoneLimit + { + humanBone = x.Key, + boneName = x.Value.name, + useDefaultValues = true, + }; + }).ToArray(); + } + +#if UNITY_EDITOR + /// <summary> + /// * https://answers.unity.com/questions/612177/how-can-i-access-human-avatar-bone-and-muscle-valu.html + /// </summary> + /// <param name="target"></param> + /// <param name="des"></param> + /// <returns></returns> + public static bool GetHumanDescription(UnityEngine.Object target, ref HumanDescription des) + { + if (target != null) + { + var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(target)); + if (importer != null) + { + Debug.Log("AssetImporter Type: " + importer.GetType()); + ModelImporter modelImporter = importer as ModelImporter; + if (modelImporter != null) + { + des = modelImporter.humanDescription; + Debug.Log("## Cool stuff data by ModelImporter ##"); + return true; + } + else + { + Debug.LogWarning("## Please Select Imported Model in Project View not prefab or other things ##"); + } + } + } + + return false; + } +#endif + } +}
\ No newline at end of file diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AvatarDescription.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AvatarDescription.cs.meta new file mode 100644 index 00000000..3da5dea9 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AvatarDescription.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 976e99d37c093ce4c9b249c81c2cbdd5 +timeCreated: 1520401720 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneGizmoDrawer.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneGizmoDrawer.cs new file mode 100644 index 00000000..66fb10d8 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneGizmoDrawer.cs @@ -0,0 +1,28 @@ +using UnityEngine; + + +namespace UniHumanoid +{ + public class BoneGizmoDrawer : MonoBehaviour + { + const float size = 0.03f; + readonly Vector3 SIZE = new Vector3(size, size, size); + + [SerializeField] + public bool Draw = true; + + void OnDrawGizmos() + { +#if UNITY_EDITOR + if (Draw && transform.parent != null) + { + Gizmos.color = Color.yellow; + Gizmos.DrawCube(transform.position, SIZE); + Gizmos.DrawLine(transform.parent.position, transform.position); + + UnityEditor.Handles.Label(transform.position, name); + } +#endif + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneGizmoDrawer.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneGizmoDrawer.cs.meta new file mode 100644 index 00000000..12ebe910 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneGizmoDrawer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 677492d2843780e40aa2a6c7a6ae8fe6 +timeCreated: 1517332124 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneMapping.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneMapping.cs new file mode 100644 index 00000000..f9233e66 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneMapping.cs @@ -0,0 +1,103 @@ +using UnityEngine; +using System.Linq; +using System; + +namespace UniHumanoid +{ + public class BoneMapping : MonoBehaviour + { + [SerializeField] + public GameObject[] Bones = new GameObject[(int)HumanBodyBones.LastBone]; + + [SerializeField] + public AvatarDescription Description; + + private void Reset() + { + GetBones(); + } + + private void GetBones() + { + Bones = new GameObject[(int)HumanBodyBones.LastBone]; + + var animator = GetComponent<Animator>(); + if (animator != null) + { + if (animator.avatar != null) + { + foreach (HumanBodyBones key in Enum.GetValues(typeof(HumanBodyBones))) + { + if (key == HumanBodyBones.LastBone) + { + break; + } + var transform = animator.GetBoneTransform(key); + if (transform != null) + { + Bones[(int)key] = transform.gameObject; + } + } + } + } + } + + public void GuessBoneMapping() + { + var hips = Bones[(int)HumanBodyBones.Hips]; + if (hips == null) + { + Debug.LogWarning("require hips"); + return; + } + + var estimator = new BvhSkeletonEstimator(); + var skeleton = estimator.Detect(hips.transform); + var bones = hips.transform.Traverse().ToArray(); + for (int i = 0; i < (int)HumanBodyBones.LastBone; ++i) + { + var index = skeleton.GetBoneIndex((HumanBodyBones)i); + if (index >= 0) + { + Bones[i] = bones[index].gameObject; + } + } + } + + public void EnsureTPose() + { + var map = Bones + .Select((x, i) => new { i, x }) + .Where(x => x.x != null) + .ToDictionary(x => (HumanBodyBones)x.i, x => x.x.transform) + ; + { + var left = (map[HumanBodyBones.LeftLowerArm].position - map[HumanBodyBones.LeftUpperArm].position).normalized; + map[HumanBodyBones.LeftUpperArm].rotation = Quaternion.FromToRotation(left, Vector3.left) * map[HumanBodyBones.LeftUpperArm].rotation; + } + { + var right = (map[HumanBodyBones.RightLowerArm].position - map[HumanBodyBones.RightUpperArm].position).normalized; + map[HumanBodyBones.RightUpperArm].rotation = Quaternion.FromToRotation(right, Vector3.right) * map[HumanBodyBones.RightUpperArm].rotation; + } + } + + public static void SetBonesToDescription(BoneMapping mapping, AvatarDescription description) + { + var map = mapping.Bones + .Select((x, i) => new { i, x }) + .Where(x => x.x != null) + .ToDictionary(x => (HumanBodyBones)x.i, x => x.x.transform) + ; + description.SetHumanBones(map); + } + + private void Awake() + { + if (Bones == null + || Bones.All(x => x==null)) + { + GetBones(); + } + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneMapping.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneMapping.cs.meta new file mode 100644 index 00000000..d7f97711 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BoneMapping.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 44f5895a2095a2848ba2c9627a5c1ad9 +timeCreated: 1516520420 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BvhBone.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BvhBone.cs new file mode 100644 index 00000000..8278c217 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BvhBone.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using UnityEngine; + + +namespace UniHumanoid +{ + public class BvhBone : IBone + { + public string Name + { + private set; + get; + } + + public Vector3 SkeletonLocalPosition + { + private set; + get; + } + + public BvhBone(string name, Vector3 position) + { + Name = name; + SkeletonLocalPosition = position; + } + + public override string ToString() + { + return string.Format("<BvhBone: {0}>", Name); + } + + public IBone Parent + { + private set; + get; + } + + List<IBone> _children = new List<IBone>(); + public IList<IBone> Children + { + get { return _children; } + } + + public void Build(Transform t) + { + foreach (Transform child in t) + { + var childBone = new BvhBone(child.name, SkeletonLocalPosition + child.localPosition); + childBone.Parent = this; + _children.Add(childBone); + + childBone.Build(child); + } + } + + public void Build(BvhNode node) + { + foreach (var child in node.Children) + { + var childBone = new BvhBone(child.Name, SkeletonLocalPosition + child.Offset.ToXReversedVector3()); + childBone.Parent = this; + _children.Add(childBone); + + childBone.Build(child); + } + } + + public IEnumerable<BvhBone> Traverse() + { + yield return this; + foreach (var child in Children) + { + foreach (var x in child.Traverse()) + { + yield return (BvhBone)x; + } + } + } + } +}
\ No newline at end of file diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BvhBone.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BvhBone.cs.meta new file mode 100644 index 00000000..a3578e4a --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/BvhBone.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1a88b26726f137419428078debd253f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Extensions.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Extensions.meta new file mode 100644 index 00000000..e559e8cb --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Extensions.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a08328e411d14d8419fc89356b6ddbc4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Extensions/EnumExtensions.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Extensions/EnumExtensions.cs new file mode 100644 index 00000000..8ae5d2df --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Extensions/EnumExtensions.cs @@ -0,0 +1,71 @@ +using UnityEngine; + +namespace UniHumanoid +{ + public static class EnumExtensions + { + public static string ToStringFromEnum(this HumanBodyBones val, bool compareBoneTrait = false) + { + switch (val) + { + case HumanBodyBones.Hips: return "Hips"; + case HumanBodyBones.LeftUpperLeg: return "LeftUpperLeg"; + case HumanBodyBones.RightUpperLeg: return "RightUpperLeg"; + case HumanBodyBones.LeftLowerLeg: return "LeftLowerLeg"; + case HumanBodyBones.RightLowerLeg: return "RightLowerLeg"; + case HumanBodyBones.LeftFoot: return "LeftFoot"; + case HumanBodyBones.RightFoot: return "RightFoot"; + case HumanBodyBones.Spine: return "Spine"; + case HumanBodyBones.Chest: return "Chest"; + case HumanBodyBones.Neck: return "Neck"; + case HumanBodyBones.Head: return "Head"; + case HumanBodyBones.LeftShoulder: return "LeftShoulder"; + case HumanBodyBones.RightShoulder: return "RightShoulder"; + case HumanBodyBones.LeftUpperArm: return "LeftUpperArm"; + case HumanBodyBones.RightUpperArm: return "RightUpperArm"; + case HumanBodyBones.LeftLowerArm: return "LeftLowerArm"; + case HumanBodyBones.RightLowerArm: return "RightLowerArm"; + case HumanBodyBones.LeftHand: return "LeftHand"; + case HumanBodyBones.RightHand: return "RightHand"; + case HumanBodyBones.LeftToes: return "LeftToes"; + case HumanBodyBones.RightToes: return "RightToes"; + case HumanBodyBones.LeftEye: return "LeftEye"; + case HumanBodyBones.RightEye: return "RightEye"; + case HumanBodyBones.Jaw: return "Jaw"; + case HumanBodyBones.LeftThumbProximal: return compareBoneTrait ? "Left Thumb Proximal" : "LeftThumbProximal"; + case HumanBodyBones.LeftThumbIntermediate: return compareBoneTrait ? "Left Thumb Intermediate" : "LeftThumbIntermediate"; + case HumanBodyBones.LeftThumbDistal: return compareBoneTrait ? "Left Thumb Distal" : "LeftThumbDistal"; + case HumanBodyBones.LeftIndexProximal: return compareBoneTrait ? "Left Index Proximal" : "LeftIndexProximal"; + case HumanBodyBones.LeftIndexIntermediate: return compareBoneTrait ? "Left Index Intermediate" : "LeftIndexIntermediate"; + case HumanBodyBones.LeftIndexDistal: return compareBoneTrait ? "Left Index Distal" : "LeftIndexDistal"; + case HumanBodyBones.LeftMiddleProximal: return compareBoneTrait ? "Left Middle Proximal" : "LeftMiddleProximal"; + case HumanBodyBones.LeftMiddleIntermediate: return compareBoneTrait ? "Left Middle Intermediate" : "LeftMiddleIntermediate"; + case HumanBodyBones.LeftMiddleDistal: return compareBoneTrait ? "Left Middle Distal" : "LeftMiddleDistal"; + case HumanBodyBones.LeftRingProximal: return compareBoneTrait ? "Left Ring Proximal" : "LeftRingProximal"; + case HumanBodyBones.LeftRingIntermediate: return compareBoneTrait ? "Left Ring Intermediate" : "LeftRingIntermediate"; + case HumanBodyBones.LeftRingDistal: return compareBoneTrait ? "Left Ring Distal" : "LeftRingDistal"; + case HumanBodyBones.LeftLittleProximal: return compareBoneTrait ? "Left Little Proximal" : "LeftLittleProximal"; + case HumanBodyBones.LeftLittleIntermediate: return compareBoneTrait ? "Left Little Intermediate" : "LeftLittleIntermediate"; + case HumanBodyBones.LeftLittleDistal: return compareBoneTrait ? "Left Little Distal" : "LeftLittleDistal"; + case HumanBodyBones.RightThumbProximal: return compareBoneTrait ? "Right Thumb Proximal" : "RightThumbProximal"; + case HumanBodyBones.RightThumbIntermediate: return compareBoneTrait ? "Right Thumb Intermediate" : "RightThumbIntermediate"; + case HumanBodyBones.RightThumbDistal: return compareBoneTrait ? "Right Thumb Distal" : "RightThumbDistal"; + case HumanBodyBones.RightIndexProximal: return compareBoneTrait ? "Right Index Proximal" : "RightIndexProximal"; + case HumanBodyBones.RightIndexIntermediate: return compareBoneTrait ? "Right Index Intermediate" : "RightIndexIntermediate"; + case HumanBodyBones.RightIndexDistal: return compareBoneTrait ? "Right Index Distal" : "RightIndexDistal"; + case HumanBodyBones.RightMiddleProximal: return compareBoneTrait ? "Right Middle Proximal" : "RightMiddleProximal"; + case HumanBodyBones.RightMiddleIntermediate: return compareBoneTrait ? "Right Middle Intermediate" : "RightMiddleIntermediate"; + case HumanBodyBones.RightMiddleDistal: return compareBoneTrait ? "Right Middle Distal" : "RightMiddleDistal"; + case HumanBodyBones.RightRingProximal: return compareBoneTrait ? "Right Ring Proximal" : "RightRingProximal"; + case HumanBodyBones.RightRingIntermediate: return compareBoneTrait ? "Right Ring Intermediate" : "RightRingIntermediate"; + case HumanBodyBones.RightRingDistal: return compareBoneTrait ? "Right Ring Distal" : "RightRingDistal"; + case HumanBodyBones.RightLittleProximal: return compareBoneTrait ? "Right Little Proximal" : "RightLittleProximal"; + case HumanBodyBones.RightLittleIntermediate: return compareBoneTrait ? "Right Little Intermediate" : "RightLittleIntermediate"; + case HumanBodyBones.RightLittleDistal: return compareBoneTrait ? "Right Little Distal" : "RightLittleDistal"; + case HumanBodyBones.UpperChest: return "UpperChest"; + case HumanBodyBones.LastBone: return "LastBone"; + default: throw new System.InvalidOperationException(); + } + } + } +}
\ No newline at end of file diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Extensions/EnumExtensions.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Extensions/EnumExtensions.cs.meta new file mode 100644 index 00000000..e9fc631d --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Extensions/EnumExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04d0b56405dbe18439be5a95598deb36 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Format.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Format.meta new file mode 100644 index 00000000..3ee3d5db --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Format.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fc31477377367fb48bc85f0864fe33eb +folderAsset: yes +timeCreated: 1517655048 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Format/Bvh.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Format/Bvh.cs new file mode 100644 index 00000000..6c39c3b8 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Format/Bvh.cs @@ -0,0 +1,444 @@ +using System; +using System.Collections.Generic; +using System.IO; +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 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 + { + get; + private set; + } + + public TimeSpan FrameTime + { + get; + private set; + } + + public ChannelCurve[] Channels + { + get; + private set; + } + + int m_frames; + public int FrameCount + { + get { return m_frames; } + } + + public struct PathWithProperty + { + public string Path; + public string Property; + public bool IsLocation; + } + + public bool TryGetPathWithPropertyFromChannel(ChannelCurve channel, out PathWithProperty pathWithProp) + { + var index = Channels.ToList().IndexOf(channel); + if (index == -1) + { + pathWithProp = default(PathWithProperty); + return false; + } + + foreach(var node in Root.Traverse()) + { + for(int i=0; i<node.Channels.Length; ++i, --index) + { + if (index == 0) + { + pathWithProp = new PathWithProperty + { + Path=GetPath(node), + Property=node.Channels[i].ToProperty(), + IsLocation=node.Channels[i].IsLocation(), + }; + return true; + } + } + } + + throw new BvhException("channel is not found"); + } + + public string GetPath(BvhNode node) + { + var list = new List<string>() { node.Name }; + + var current = node; + while (current!=null) + { + current = GetParent(current); + if (current != null) + { + list.Insert(0, current.Name); + } + } + + return String.Join("/", list.ToArray()); + } + + BvhNode GetParent(BvhNode node) + { + foreach(var x in Root.Traverse()) + { + if (x.Children.Contains(node)) + { + return x; + } + } + + return null; + } + + public ChannelCurve GetChannel(BvhNode target, Channel channel) + { + var index = 0; + foreach (var node in Root.Traverse()) + { + for (int i = 0; i < node.Channels.Length; ++i, ++index) + { + if(node==target && node.Channels[i] == channel) + { + return Channels[index]; + } + } + } + + throw new BvhException("channel is not found"); + } + + public override string ToString() + { + return string.Format("{0}nodes, {1}channels, {2}frames, {3:0.00}seconds" + , Root.Traverse().Count() + , Channels.Length + , m_frames + , m_frames * FrameTime.TotalSeconds); + } + + public Bvh(BvhNode root, int frames, float seconds) + { + Root = root; + FrameTime = TimeSpan.FromSeconds(seconds); + m_frames = frames; + var channelCount = Root.Traverse() + .Where(x => x.Channels!=null) + .Select(x => x.Channels.Length) + .Sum(); + Channels = Enumerable.Range(0, channelCount) + .Select(x => new ChannelCurve(frames)) + .ToArray() + ; + } + + public void ParseFrame(int frame, string line) + { + var split = line.Trim().Split().Where(x => !string.IsNullOrEmpty(x)).ToArray(); + if (split.Length != Channels.Length) + { + throw new BvhException("frame key count is not match channel count"); + } + for(int i=0; i<Channels.Length; ++i) + { + Channels[i].SetKey(frame, float.Parse(split[i], System.Globalization.CultureInfo.InvariantCulture)); + } + } + + public static Bvh Parse(string src) + { + using (var r = new StringReader(src)) + { + if (r.ReadLine() != "HIERARCHY") + { + throw new BvhException("not start with HIERARCHY"); + } + + var root = ParseNode(r); + if (root == null) + { + return null; + } + + var frames = 0; + var frameTime = 0.0f; + if (r.ReadLine() == "MOTION") + { + var frameSplit = r.ReadLine().Split(':'); + if (frameSplit[0] != "Frames") + { + throw new BvhException("Frames is not found"); + } + frames = int.Parse(frameSplit[1]); + + var frameTimeSplit = r.ReadLine().Split(':'); + if (frameTimeSplit[0] != "Frame Time") + { + throw new BvhException("Frame Time is not found"); + } + frameTime = float.Parse(frameTimeSplit[1], System.Globalization.CultureInfo.InvariantCulture); + } + + var bvh = new Bvh(root, frames, frameTime); + + for(int i=0; i<frames; ++i) + { + var line = r.ReadLine(); + bvh.ParseFrame(i, line); + } + + return bvh; + } + } + + static BvhNode ParseNode(StringReader r, int level = 0) + { + var firstline = r.ReadLine().Trim(); + var split = firstline.Split(); + if (split.Length != 2) + { + if (split.Length == 1) + { + if(split[0] == "}") + { + return null; + } + } + throw new BvhException(String.Format("split to {0}({1})", split.Length, firstline)); + } + + BvhNode node = null; + if (split[0] == "ROOT") + { + if (level != 0) + { + throw new BvhException("nested ROOT"); + } + node = new BvhNode(split[1]); + } + else if (split[0] == "JOINT") + { + if (level == 0) + { + throw new BvhException("should ROOT, but JOINT"); + } + node = new BvhNode(split[1]); + } + else if (split[0] == "End") + { + if (level == 0) + { + throw new BvhException("End in level 0"); + } + node = new EndSite(); + } + else + { + throw new BvhException("unknown type: " + split[0]); + } + + if(r.ReadLine().Trim() != "{") + { + throw new BvhException("'{' is not found"); + } + + node.Parse(r); + + // child nodes + while (true) + { + var child = ParseNode(r, level + 1); + if (child == null) + { + break; + } + + if(!(child is EndSite)) + { + node.Children.Add(child); + } + } + + return node; + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Format/Bvh.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Format/Bvh.cs.meta new file mode 100644 index 00000000..c0b63aa8 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Format/Bvh.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2e7bf08c7b7056e4ea1f50b1e008cb7e +timeCreated: 1517166478 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseClip.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseClip.cs new file mode 100644 index 00000000..bed31795 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseClip.cs @@ -0,0 +1,33 @@ +using UnityEngine; + + +namespace UniHumanoid +{ + public class HumanPoseClip : ScriptableObject + { + public const string TPoseResourcePath = "T-Pose.pose"; + + public Vector3 bodyPosition; + + public Quaternion bodyRotation; + + public float[] muscles; + + public HumanPose GetPose() + { + return new HumanPose + { + bodyPosition = bodyPosition, + bodyRotation = bodyRotation, + muscles = muscles + }; + } + + public void ApplyPose(ref HumanPose pose) + { + bodyPosition = pose.bodyPosition; + bodyRotation = pose.bodyRotation; + muscles = (float[])pose.muscles.Clone(); + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseClip.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseClip.cs.meta new file mode 100644 index 00000000..3d120849 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseClip.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 4fdf4ef744a103a4ca01657c00d7fec2 +timeCreated: 1517760105 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseTransfer.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseTransfer.cs new file mode 100644 index 00000000..8597a27b --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseTransfer.cs @@ -0,0 +1,143 @@ +using UnityEngine; + + +namespace UniHumanoid +{ + public class HumanPoseTransfer : MonoBehaviour + { + public enum HumanPoseTransferSourceType + { + None, + HumanPoseTransfer, + HumanPoseClip, + } + + [SerializeField] + public HumanPoseTransferSourceType SourceType; + + [SerializeField] + public Avatar Avatar; + + #region Standalone + public HumanPose CreatePose() + { + var handler = new HumanPoseHandler(Avatar, transform); + var pose = default(HumanPose); + handler.GetHumanPose(ref pose); + return pose; + } + public void SetPose(HumanPose pose) + { + SetPose(Avatar, transform, pose); + } + public static void SetPose(Avatar avatar, Transform transform, HumanPose pose) + { + var handler = new HumanPoseHandler(avatar, transform); + handler.SetHumanPose(ref pose); + } + public static void SetTPose(Avatar avatar, Transform transform) + { + var humanPoseClip = Resources.Load<HumanPoseClip>(HumanPoseClip.TPoseResourcePath); + var pose = humanPoseClip.GetPose(); + HumanPoseTransfer.SetPose(avatar, transform, pose); + } + #endregion + + private void Reset() + { + var animator = GetComponent<Animator>(); + if (animator != null) + { + Avatar = animator.avatar; + } + } + + [SerializeField] + public HumanPoseTransfer Source; + + [SerializeField] + public HumanPoseClip PoseClip; + + [ContextMenu("Set T-Pose")] + void SetTPose() + { + if (Avatar == null) return; + SetTPose(Avatar, transform); + } + + HumanPoseHandler m_handler; + public void OnEnable() + { + var animator = GetComponent<Animator>(); + if (animator != null) + { + Avatar = animator.avatar; + } + + Setup(); + } + + public void Setup() + { + if (Avatar == null) + { + return; + } + m_handler = new HumanPoseHandler(Avatar, transform); + } + + HumanPose m_pose; + + int m_lastFrameCount = -1; + + public bool GetPose(int frameCount, ref HumanPose pose) + { + if (PoseClip != null) + { + pose = PoseClip.GetPose(); + return true; + } + + if (m_handler == null) + { + pose = m_pose; + return false; + } + + if (frameCount != m_lastFrameCount) + { + m_handler.GetHumanPose(ref m_pose); + m_lastFrameCount = frameCount; + } + pose = m_pose; + return true; + } + + private void Update() + { + switch (SourceType) + { + case HumanPoseTransferSourceType.None: + break; + + case HumanPoseTransferSourceType.HumanPoseTransfer: + if (Source != null && m_handler != null) + { + if (Source.GetPose(Time.frameCount, ref m_pose)) + { + m_handler.SetHumanPose(ref m_pose); + } + } + break; + + case HumanPoseTransferSourceType.HumanPoseClip: + if (PoseClip != null) + { + var pose = PoseClip.GetPose(); + m_handler.SetHumanPose(ref pose); + } + break; + } + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseTransfer.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseTransfer.cs.meta new file mode 100644 index 00000000..d1dbf424 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseTransfer.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: e5548e4785b76854cbbf3f6d9a8e9c1d +timeCreated: 1517666226 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IBone.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IBone.cs new file mode 100644 index 00000000..4d038a86 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IBone.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using UnityEngine; + + +namespace UniHumanoid +{ + public interface IBone + { + string Name { get; } + Vector3 SkeletonLocalPosition { get; } + IBone Parent { get; } + IList<IBone> Children { get; } + } + + public static class IBoneExtensions + { + public static IEnumerable<IBone> Traverse(this IBone self) + { + yield return self; + foreach (var child in self.Children) + { + foreach (var x in child.Traverse()) + { + yield return x; + } + } + } + + public static Vector3 CenterOfDescendant(this IBone self) + { + var sum = Vector3.zero; + int i = 0; + foreach (var x in self.Traverse()) + { + sum += x.SkeletonLocalPosition; + ++i; + } + return sum / i; + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IBone.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IBone.cs.meta new file mode 100644 index 00000000..4a8df933 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IBone.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c9c2e3ee9fe29a84cb902e54a90c5dec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO.meta new file mode 100644 index 00000000..9a8d776b --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e07bcccfa1de56943ab8e18f8791740d +folderAsset: yes +timeCreated: 1517655053 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhAnimationClip.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhAnimationClip.cs new file mode 100644 index 00000000..ea644f5c --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhAnimationClip.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + + +namespace UniHumanoid +{ + public static class BvhAnimation + { + class CurveSet + { + BvhNode Node; + Func<float, float, float, Quaternion> EulerToRotation; + public CurveSet(BvhNode node) + { + Node = node; + } + + public ChannelCurve PositionX; + public ChannelCurve PositionY; + public ChannelCurve PositionZ; + public Vector3 GetPosition(int i) + { + return new Vector3( + PositionX.Keys[i], + PositionY.Keys[i], + PositionZ.Keys[i]); + } + + public ChannelCurve RotationX; + public ChannelCurve RotationY; + public ChannelCurve RotationZ; + public Quaternion GetRotation(int i) + { + if (EulerToRotation == null) + { + EulerToRotation = Node.GetEulerToRotation(); + } + return EulerToRotation( + RotationX.Keys[i], + RotationY.Keys[i], + RotationZ.Keys[i] + ); + } + + static void AddCurve(Bvh bvh, AnimationClip clip, ChannelCurve ch, float scaling) + { + if (ch == null) return; + var pathWithProp = default(Bvh.PathWithProperty); + bvh.TryGetPathWithPropertyFromChannel(ch, out pathWithProp); + var curve = new AnimationCurve(); + for (int i = 0; i < bvh.FrameCount; ++i) + { + var time = (float)(i * bvh.FrameTime.TotalSeconds); + var value = ch.Keys[i] * scaling; + curve.AddKey(time, value); + } + clip.SetCurve(pathWithProp.Path, typeof(Transform), pathWithProp.Property, curve); + } + + public void AddCurves(Bvh bvh, AnimationClip clip, float scaling) + { + AddCurve(bvh, clip, PositionX, -scaling); + AddCurve(bvh, clip, PositionY, scaling); + AddCurve(bvh, clip, PositionZ, scaling); + + var pathWithProp = default(Bvh.PathWithProperty); + bvh.TryGetPathWithPropertyFromChannel(RotationX, out pathWithProp); + + // rotation + var curveX = new AnimationCurve(); + var curveY = new AnimationCurve(); + var curveZ = new AnimationCurve(); + var curveW = new AnimationCurve(); + for (int i = 0; i < bvh.FrameCount; ++i) + { + var time = (float)(i * bvh.FrameTime.TotalSeconds); + var q = GetRotation(i).ReverseX(); + curveX.AddKey(time, q.x); + curveY.AddKey(time, q.y); + curveZ.AddKey(time, q.z); + curveW.AddKey(time, q.w); + } + clip.SetCurve(pathWithProp.Path, typeof(Transform), "localRotation.x", curveX); + clip.SetCurve(pathWithProp.Path, typeof(Transform), "localRotation.y", curveY); + clip.SetCurve(pathWithProp.Path, typeof(Transform), "localRotation.z", curveZ); + clip.SetCurve(pathWithProp.Path, typeof(Transform), "localRotation.w", curveW); + } + } + + public static AnimationClip CreateAnimationClip(Bvh bvh, float scaling) + { + var clip = new AnimationClip(); + clip.legacy = true; + + var curveMap = new Dictionary<BvhNode, CurveSet>(); + + int j = 0; + foreach (var node in bvh.Root.Traverse()) + { + var set = new CurveSet(node); + curveMap[node] = set; + + for (int i = 0; i < node.Channels.Length; ++i, ++j) + { + 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; + default: throw new Exception(); + } + } + } + + foreach (var set in curveMap) + { + set.Value.AddCurves(bvh, clip, scaling); + } + + clip.EnsureQuaternionContinuity(); + + return clip; + } + + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhAnimationClip.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhAnimationClip.cs.meta new file mode 100644 index 00000000..0348a6a9 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhAnimationClip.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 45951aadbd5e6b34282cd17ee163f58b +timeCreated: 1517655805 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporter.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporter.cs new file mode 100644 index 00000000..488b10a6 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporter.cs @@ -0,0 +1,15 @@ +using System; + + +namespace UniHumanoid +{ + public static class BvhImporter + { + [Obsolete("use BvhImporter.Parse(path), then BvhImporter.Load()")] + public static void Import(BvhImporterContext context) + { + context.Parse(context.Path); + context.Load(); + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporter.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporter.cs.meta new file mode 100644 index 00000000..335ced19 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporter.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: da8ccd6cbe1692448872063195e5c71b +timeCreated: 1517655539 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporterContext.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporterContext.cs new file mode 100644 index 00000000..f7acb3a1 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporterContext.cs @@ -0,0 +1,235 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEngine; +using System.IO; +using System.Text; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniHumanoid +{ + [Obsolete("use BvhImporterContext")] + public class ImporterContext: BvhImporterContext + { + } + + public class BvhImporterContext + { + #region Source + String m_path; + public String Path + { + get { return m_path; } + set + { + if (m_path == value) return; + m_path = value; + } + } + public String Source; // source + public Bvh Bvh; + #endregion + + #region Imported + public GameObject Root; + public List<Transform> Nodes = new List<Transform>(); + public AnimationClip Animation; + public AvatarDescription AvatarDescription; + public Avatar Avatar; + public Mesh Mesh; + public Material Material; + #endregion + + #region Load + [Obsolete("use Load(path)")] + public void Parse() + { + Parse(Path); + } + + public void Parse(string path) + { + Path = path; + Source = File.ReadAllText(Path, Encoding.UTF8); + Bvh = Bvh.Parse(Source); + } + + public void Load() + { + // + // build hierarchy + // + Root = new GameObject(System.IO.Path.GetFileNameWithoutExtension(Path)); + var hips = BuildHierarchy(Root.transform, Bvh.Root, 1.0f); + var skeleton = Skeleton.Estimate(hips); + var description = AvatarDescription.Create(hips.Traverse().ToArray(), skeleton); + + // + // scaling. reposition + // + float scaling = 1.0f; + { + //var foot = animator.GetBoneTransform(HumanBodyBones.LeftFoot); + var foot = hips.Traverse().Skip(skeleton.GetBoneIndex(HumanBodyBones.LeftFoot)).First(); + var hipHeight = hips.position.y - foot.position.y; + // hips height to a meter + scaling = 1.0f / hipHeight; + foreach (var x in Root.transform.Traverse()) + { + x.localPosition *= scaling; + } + + var scaledHeight = hipHeight * scaling; + 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 + // + Animation = BvhAnimation.CreateAnimationClip(Bvh, scaling); + Animation.name = Root.name; + Animation.legacy = true; + Animation.wrapMode = WrapMode.Loop; + + var animation = Root.AddComponent<Animation>(); + animation.AddClip(Animation, Animation.name); + 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"; + } + + static Transform BuildHierarchy(Transform parent, BvhNode node, float toMeter) + { + var go = new GameObject(node.Name); + go.transform.localPosition = node.Offset.ToXReversedVector3() * toMeter; + go.transform.SetParent(parent, false); + + //var gizmo = go.AddComponent<BoneGizmoDrawer>(); + //gizmo.Draw = true; + + foreach (var child in node.Children) + { + BuildHierarchy(go.transform, child, toMeter); + } + + return go.transform; + } + #endregion + +#if UNITY_EDITOR + protected virtual string GetPrefabPath() + { + var dir = System.IO.Path.GetDirectoryName(Path); + var name = System.IO.Path.GetFileNameWithoutExtension(Path); + var prefabPath = string.Format("{0}/{1}.prefab", dir, name); + if (!Application.isPlaying && File.Exists(prefabPath)) + { + // already exists + if (IsOwn(prefabPath)) + { + //Debug.LogFormat("already exist. own: {0}", prefabPath); + } + else + { + // but unknown prefab + var unique = AssetDatabase.GenerateUniqueAssetPath(prefabPath); + //Debug.LogFormat("already exist: {0} => {1}", prefabPath, unique); + prefabPath = unique; + } + } + return prefabPath; + } + + #region Assets + IEnumerable<UnityEngine.Object> GetSubAssets(string path) + { + return AssetDatabase.LoadAllAssetsAtPath(path); + } + + protected virtual bool IsOwn(string path) + { + foreach (var x in GetSubAssets(path)) + { + //if (x is Transform) continue; + if (x is GameObject) continue; + if (x is Component) continue; + if (AssetDatabase.IsSubAsset(x)) + { + return true; + } + } + return false; + } + + IEnumerable<UnityEngine.Object> ObjectsForSubAsset() + { + if (Animation != null) yield return Animation; + if (AvatarDescription != null) yield return AvatarDescription; + if (Avatar != null) yield return Avatar; + if (Mesh != null) yield return Mesh; + if (Material != null) yield return Material; + } + + public void SaveAsAsset() + { + var path = GetPrefabPath(); + if (File.Exists(path)) + { + // clear SubAssets + foreach (var x in GetSubAssets(path).Where(x => !(x is GameObject) && !(x is Component))) + { + GameObject.DestroyImmediate(x, true); + } + } + + // Add SubAsset + foreach (var o in ObjectsForSubAsset()) + { + AssetDatabase.AddObjectToAsset(o, path); + } + + // Create or update Main Asset + Debug.LogFormat("create prefab: {0}", path); + PrefabUtility.SaveAsPrefabAssetAndConnect(Root, path, InteractionMode.AutomatedAction); + + AssetDatabase.ImportAsset(path); + } + #endregion +#endif + + public void Destroy(bool destroySubAssets) + { + if (Root != null) GameObject.DestroyImmediate(Root); + if (destroySubAssets) + { +#if UNITY_EDITOR + foreach (var o in ObjectsForSubAsset()) + { + UnityEngine.Object.DestroyImmediate(o, true); + } +#endif + } + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporterContext.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporterContext.cs.meta new file mode 100644 index 00000000..79a8c6e7 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/BvhImporterContext.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6c6231d0aafc9554ca596f35e8f395c4 +timeCreated: 1521112950 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions.meta new file mode 100644 index 00000000..69f5a007 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9f2cfbad0949d5840879540d0fce61fe +folderAsset: yes +timeCreated: 1517655230 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/BvhExtensions.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/BvhExtensions.cs new file mode 100644 index 00000000..2b80293f --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/BvhExtensions.cs @@ -0,0 +1,45 @@ +using System; +using System.Linq; +using UnityEngine; + + +namespace UniHumanoid +{ + public static class BvhExtensions + { + 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(); + + return (x, y, z) => + { + var xRot = Quaternion.Euler(x, 0, 0); + var yRot = Quaternion.Euler(0, y, 0); + var zRot = Quaternion.Euler(0, 0, z); + + var r = Quaternion.identity; + foreach (var ch in order) + { + switch (ch) + { + case Channel.Xrotation: r = r * xRot; break; + case Channel.Yrotation: r = r * yRot; break; + case Channel.Zrotation: r = r * zRot; break; + default: throw new BvhException("no rotation"); + } + } + return r; + }; + } + + public static Vector3 ToVector3(this Single3 s3) + { + return new Vector3(s3.x, s3.y, s3.z); + } + + public static Vector3 ToXReversedVector3(this Single3 s3) + { + return new Vector3(-s3.x, s3.y, s3.z); + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/BvhExtensions.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/BvhExtensions.cs.meta new file mode 100644 index 00000000..a078ba97 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/BvhExtensions.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 30d4db9a01d6aee4db9a77d762e608f6 +timeCreated: 1517655238 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/UnityExtensions.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/UnityExtensions.cs new file mode 100644 index 00000000..413918d3 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/UnityExtensions.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using UnityEngine; + + +namespace UniHumanoid +{ + public static class UnityExtensions + { + public static Quaternion ReverseX(this Quaternion quaternion) + { + float angle; + Vector3 axis; + quaternion.ToAngleAxis(out angle, out axis); + + return Quaternion.AngleAxis(-angle, new Vector3(-axis.x, axis.y, axis.z)); + } + + public static IEnumerable<Transform> GetChildren(this Transform parent) + { + foreach (Transform child in parent) + { + yield return child; + } + } + + public static IEnumerable<Transform> Traverse(this Transform parent) + { + yield return parent; + + foreach (Transform child in parent) + { + foreach (Transform descendant in Traverse(child)) + { + yield return descendant; + } + } + } + + public static SkeletonBone ToSkeletonBone(this Transform t) + { + var sb = new SkeletonBone(); + sb.name = t.name; + sb.position = t.localPosition; + sb.rotation = t.localRotation; + sb.scale = t.localScale; + return sb; + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/UnityExtensions.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/UnityExtensions.cs.meta new file mode 100644 index 00000000..918c91cd --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/IO/Extensions/UnityExtensions.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 6c4a2b80b74e499428637f36774bbdcf +timeCreated: 1517666834 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleDebug.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleDebug.cs new file mode 100644 index 00000000..b03b9dd2 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleDebug.cs @@ -0,0 +1,105 @@ +using System; +using System.Linq; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniHumanoid +{ + public class MuscleDebug : MonoBehaviour + { + Avatar GetAvatar() + { + var animator = GetComponent<Animator>(); + if (animator != null && animator.avatar != null) + { + return animator.avatar; + } + + var transfer = GetComponent<HumanPoseTransfer>(); + if (transfer != null && transfer.Avatar != null) + { + return transfer.Avatar; + } + + return null; + } + + HumanPoseHandler m_handler; + + public HumanPose m_pose; + + [Serializable] + public struct Muscle + { + public int Index; + public string Name; + public float Value; + } + + public Vector3 BodyPosition; + + public Muscle[] Muscles; + + private void OnEnable() + { + var avatar = GetAvatar(); + if (avatar == null) + { + enabled = false; + return; + } + + m_handler = new HumanPoseHandler(avatar, transform); + + Muscles = HumanTrait.MuscleName.Select((x, i) => + { + return new Muscle + { + Index = i, + Name = x, + }; + }) + .ToArray() + ; + } + + private void OnDisable() + { + } + + private void Update() + { + m_handler.GetHumanPose(ref m_pose); + + BodyPosition = m_pose.bodyPosition; + + for (int i = 0; i < m_pose.muscles.Length; ++i) + { + Muscles[i].Value = m_pose.muscles[i]; + } + } + } + +#if UNITY_EDITOR + [CustomPropertyDrawer(typeof(MuscleDebug.Muscle))] + public class MuscleDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, + SerializedProperty property, GUIContent label) + { + var nameProp = property.FindPropertyRelative("Name"); + var valueProp = property.FindPropertyRelative("Value"); + /* + var label = string.Format("{0}: {1}", + nameProp.stringValue, + valueProp.floatValue + ); + */ + EditorGUI.LabelField(position, nameProp.stringValue, string.Format("{0:0.00}", valueProp.floatValue)); + } + } +#endif +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleDebug.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleDebug.cs.meta new file mode 100644 index 00000000..0740b686 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleDebug.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 14aaa52c3da53004ea85dbb38e9e4698 +timeCreated: 1521114691 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleInspector.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleInspector.cs new file mode 100644 index 00000000..181fa3ee --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleInspector.cs @@ -0,0 +1,11 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +namespace UniHumanoid +{ + public class MuscleInspector : MonoBehaviour + { + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleInspector.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleInspector.cs.meta new file mode 100644 index 00000000..e952b54f --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/MuscleInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d2cc8a27b7978e54d9226bc91e53a502 +timeCreated: 1541840537 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Skeleton.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Skeleton.cs new file mode 100644 index 00000000..7680d464 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Skeleton.cs @@ -0,0 +1,92 @@ +using System.Collections.Generic; +using UnityEngine; + + +namespace UniHumanoid +{ + /// <summary> + /// Mapping HumanBodyBones to BoneIndex + /// </summary> + public struct Skeleton + { + Dictionary<HumanBodyBones, int> m_indexMap; + public Dictionary<HumanBodyBones, int> Bones + { + get { return m_indexMap; } + } + public int GetBoneIndex(HumanBodyBones bone) + { + int index; + if (m_indexMap.TryGetValue(bone, out index)) + { + return index; + } + else + { + return -1; + } + } + +#if UNITY_EDITOR + /// <summary> + /// For UnitTest + /// </summary> + Dictionary<HumanBodyBones, string> m_nameMap; + /// <summary> + /// ForTest + /// </summary> + /// <param name="bone"></param> + /// <returns></returns> + public string GetBoneName(HumanBodyBones bone) + { + string name; + if (m_nameMap.TryGetValue(bone, out name)) + { + return name; + } + else + { + return null; + } + } +#endif + + public static Skeleton Estimate(Transform hips) + { + var estimator = new BvhSkeletonEstimator(); + return estimator.Detect(hips); + } + + /// <summary> + /// Register bone's HumanBodyBones + /// </summary> + /// <param name="bone"></param> + /// <param name="bones"></param> + /// <param name="b"></param> + public void Set(HumanBodyBones bone, IList<IBone> bones, IBone b) + { + if (b != null) + { + Set(bone, bones.IndexOf(b), b.Name); + } + } + + public void Set(HumanBodyBones bone, int index, string name) + { + if (m_indexMap == null) + { + m_indexMap = new Dictionary<HumanBodyBones, int>(); + } + m_indexMap[bone] = index; + +#if UNITY_EDITOR + if (m_nameMap == null) + { + m_nameMap = new Dictionary<HumanBodyBones, string>(); + } + m_nameMap[bone] = name; +#endif + } + + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Skeleton.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Skeleton.cs.meta new file mode 100644 index 00000000..292da5e2 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/Skeleton.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 883d8b6e07cbda24384ce65d613d128e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonEstimator.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonEstimator.cs new file mode 100644 index 00000000..850212ed --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonEstimator.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + + +namespace UniHumanoid +{ + public interface ISkeletonDetector + { + Skeleton Detect(IList<IBone> bones); + } + + + public class BvhSkeletonEstimator : ISkeletonDetector + { + static IBone GetRoot(IList<IBone> bones) + { + var hips = bones.Where(x => x.Parent == null).ToArray(); + if (hips.Length != 1) + { + throw new System.Exception("Require unique root"); + } + return hips[0]; + } + + static IBone SelectBone(Func<IBone, IBone, IBone> selector, IList<IBone> bones) + { + if (bones == null || bones.Count == 0) throw new Exception("no bones"); + var current = bones[0]; + for (var i = 1; i < bones.Count; ++i) + { + current = selector(current, bones[i]); + } + return current; + } + + static void GetSpineAndHips(IBone hips, out IBone spine, out IBone leg_L, out IBone leg_R) + { + if (hips.Children.Count != 3) throw new System.Exception("Hips require 3 children"); + spine = SelectBone((l, r) => l.CenterOfDescendant().y > r.CenterOfDescendant().y ? l : r, hips.Children); + leg_L = SelectBone((l, r) => l.CenterOfDescendant().x < r.CenterOfDescendant().x ? l : r, hips.Children); + leg_R = SelectBone((l, r) => l.CenterOfDescendant().x > r.CenterOfDescendant().x ? l : r, hips.Children); + } + + static void GetNeckAndArms(IBone chest, out IBone neck, out IBone arm_L, out IBone arm_R) + { + if (chest.Children.Count != 3) throw new System.Exception("Chest require 3 children"); + neck = SelectBone((l, r) => l.CenterOfDescendant().y > r.CenterOfDescendant().y ? l : r, chest.Children); + arm_L = SelectBone((l, r) => l.CenterOfDescendant().x < r.CenterOfDescendant().x ? l : r, chest.Children); + arm_R = SelectBone((l, r) => l.CenterOfDescendant().x > r.CenterOfDescendant().x ? l : r, chest.Children); + } + + struct Arm + { + public IBone Shoulder; + public IBone UpperArm; + public IBone LowerArm; + public IBone Hand; + } + + Arm GetArm(IBone shoulder) + { + var bones = shoulder.Traverse().ToArray(); + switch (bones.Length) + { + case 0: + case 1: + case 2: + case 3: + throw new NotImplementedException(); + + default: + return new Arm + { + Shoulder = bones[0], + UpperArm = bones[1], + LowerArm = bones[2], + Hand = bones[3], + }; + } + } + + struct Leg + { + public IBone UpperLeg; + public IBone LowerLeg; + public IBone Foot; + public IBone Toes; + } + + Leg GetLeg(IBone leg) + { + var bones = leg.Traverse().Where(x => !x.Name.ToLower().Contains("buttock")).ToArray(); + switch (bones.Length) + { + case 0: + case 1: + case 2: + throw new NotImplementedException(); + + case 3: + return new Leg + { + UpperLeg = bones[0], + LowerLeg = bones[1], + Foot = bones[2], + }; + + default: + return new Leg + { + UpperLeg = bones[bones.Length - 4], + LowerLeg = bones[bones.Length - 3], + Foot = bones[bones.Length - 2], + Toes = bones[bones.Length - 1], + }; + } + } + + public Skeleton Detect(IList<IBone> bones) + { + // + // search bones + // + var root = GetRoot(bones); + var hips = root.Traverse().First(x => x.Children.Count == 3); + + IBone spine, hip_L, hip_R; + GetSpineAndHips(hips, out spine, out hip_L, out hip_R); + var legLeft = GetLeg(hip_L); + var legRight = GetLeg(hip_R); + + var spineToChest = new List<IBone>(); + foreach(var x in spine.Traverse()) + { + spineToChest.Add(x); + if (x.Children.Count == 3) break; + } + + IBone neck, shoulder_L, shoulder_R; + GetNeckAndArms(spineToChest.Last(), out neck, out shoulder_L, out shoulder_R); + var armLeft = GetArm(shoulder_L); + var armRight = GetArm(shoulder_R); + + var neckToHead = neck.Traverse().ToArray(); + + // + // set result + // + var skeleton = new Skeleton(); + skeleton.Set(HumanBodyBones.Hips, bones, hips); + + switch (spineToChest.Count) + { + case 0: + throw new Exception(); + + case 1: + skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]); + break; + + case 2: + skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]); + skeleton.Set(HumanBodyBones.Chest, bones, spineToChest[1]); + break; + +#if UNITY_5_6_OR_NEWER + case 3: + skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]); + skeleton.Set(HumanBodyBones.Chest, bones, spineToChest[1]); + skeleton.Set(HumanBodyBones.UpperChest, bones, spineToChest[2]); + break; +#endif + + default: + skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]); +#if UNITY_5_6_OR_NEWER + skeleton.Set(HumanBodyBones.Chest, bones, spineToChest[1]); + skeleton.Set(HumanBodyBones.UpperChest, bones, spineToChest.Last()); +#else + skeleton.Set(HumanBodyBones.Chest, bones, spineToChest.Last()); +#endif + break; + } + + switch (neckToHead.Length) + { + case 0: + throw new Exception(); + + case 1: + skeleton.Set(HumanBodyBones.Head, bones, neckToHead[0]); + break; + + case 2: + skeleton.Set(HumanBodyBones.Neck, bones, neckToHead[0]); + skeleton.Set(HumanBodyBones.Head, bones, neckToHead[1]); + break; + + default: + skeleton.Set(HumanBodyBones.Neck, bones, neckToHead[0]); + skeleton.Set(HumanBodyBones.Head, bones, neckToHead.Where(x => x.Parent.Children.Count==1).Last()); + break; + } + + skeleton.Set(HumanBodyBones.LeftUpperLeg, bones, legLeft.UpperLeg); + skeleton.Set(HumanBodyBones.LeftLowerLeg, bones, legLeft.LowerLeg); + skeleton.Set(HumanBodyBones.LeftFoot, bones, legLeft.Foot); + skeleton.Set(HumanBodyBones.LeftToes, bones, legLeft.Toes); + + skeleton.Set(HumanBodyBones.RightUpperLeg, bones, legRight.UpperLeg); + skeleton.Set(HumanBodyBones.RightLowerLeg, bones, legRight.LowerLeg); + skeleton.Set(HumanBodyBones.RightFoot, bones, legRight.Foot); + skeleton.Set(HumanBodyBones.RightToes, bones, legRight.Toes); + + skeleton.Set(HumanBodyBones.LeftShoulder, bones, armLeft.Shoulder); + skeleton.Set(HumanBodyBones.LeftUpperArm, bones, armLeft.UpperArm); + skeleton.Set(HumanBodyBones.LeftLowerArm, bones, armLeft.LowerArm); + skeleton.Set(HumanBodyBones.LeftHand, bones, armLeft.Hand); + + skeleton.Set(HumanBodyBones.RightShoulder, bones, armRight.Shoulder); + skeleton.Set(HumanBodyBones.RightUpperArm, bones, armRight.UpperArm); + skeleton.Set(HumanBodyBones.RightLowerArm, bones, armRight.LowerArm); + skeleton.Set(HumanBodyBones.RightHand, bones, armRight.Hand); + + return skeleton; + } + + public Skeleton Detect(Bvh bvh) + { + var root = new BvhBone(bvh.Root.Name, Vector3.zero); + root.Build(bvh.Root); + return Detect(root.Traverse().Select(x => (IBone)x).ToList()); + } + + public Skeleton Detect(Transform t) + { + var root = new BvhBone(t.name, Vector3.zero); + root.Build(t); + return Detect(root.Traverse().Select(x => (IBone)x).ToList()); + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonEstimator.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonEstimator.cs.meta new file mode 100644 index 00000000..6969f98f --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonEstimator.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4f0d2728cd7343f4ab2e7f7c2b961d5c +timeCreated: 1534751085 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonMeshUtility.cs b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonMeshUtility.cs new file mode 100644 index 00000000..053a36dd --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonMeshUtility.cs @@ -0,0 +1,232 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + + +namespace UniHumanoid +{ + public static class SkeletonMeshUtility + { + 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) + { + 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); + } + + void AddBox(Vector3 center, Vector3 xaxis, Vector3 yaxis, Vector3 zaxis, int boneIndex) + { + 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); + } + + void AddQuad(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, int boneIndex, bool reverse=false) + { + var i = m_positions.Count; + m_positions.Add(v0); + m_positions.Add(v1); + m_positions.Add(v2); + m_positions.Add(v3); + + var bw = new BoneWeight + { + 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); + m_indices.Add(i + 2); + + m_indices.Add(i + 2); + m_indices.Add(i + 3); + m_indices.Add(i); + } + } + + public Mesh CreateMesh() + { + var mesh = new Mesh(); + mesh.SetVertices(m_positions); + mesh.boneWeights = m_boneWeights.ToArray(); + mesh.triangles = m_indices.ToArray(); + mesh.RecalculateNormals(); + mesh.RecalculateBounds(); + return mesh; + } + } + + struct BoneHeadTail + { + public HumanBodyBones Head; + public HumanBodyBones Tail; + public Vector3 TailOffset; + public float XWidth; + public float ZWidth; + + public BoneHeadTail(HumanBodyBones head, HumanBodyBones tail, float xWidth = 0.05f, float zWidth = 0.05f) + { + Head = head; + Tail = tail; + TailOffset = Vector3.zero; + XWidth = xWidth; + ZWidth = zWidth; + } + + public BoneHeadTail(HumanBodyBones head, Vector3 tailOffset, float xWidth = 0.05f, float zWidth = 0.05f) + { + Head = head; + Tail = HumanBodyBones.LastBone; + TailOffset = tailOffset; + XWidth = xWidth; + ZWidth = zWidth; + } + } + + 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.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.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.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.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)), + }; + + public static SkinnedMeshRenderer CreateRenderer(Animator animator) + { + //var bodyBones = (HumanBodyBones[])Enum.GetValues(typeof(HumanBodyBones)); + var bones = animator.transform.Traverse().ToList(); + + var builder = new MeshBuilder(); + foreach(var headTail in Bones) + { + var head = animator.GetBoneTransform(headTail.Head); + if (head!=null) + { + Transform tail = null; + 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); + } + else + { + builder.AddBone(head.position, head.position + headTail.TailOffset, bones.IndexOf(head), headTail.XWidth, headTail.ZWidth); + } + } + else + { + Debug.LogWarningFormat("{0} not found", headTail.Head); + } + } + + var mesh = builder.CreateMesh(); + mesh.name = "box-man"; + 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); + renderer.sharedMesh = mesh; + //var bounds = new Bounds(Vector3.zero, mesh.bounds.size); + //renderer.localBounds = bounds; + return renderer; + } + } +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonMeshUtility.cs.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonMeshUtility.cs.meta new file mode 100644 index 00000000..a3cf3125 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/SkeletonMeshUtility.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 92bf6005e8d6db94b8b55c67caea9ddd +timeCreated: 1522346056 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/UniHumanoid.asmdef b/Assets/ThirdParty/VRM/VRM/UniHumanoid/UniHumanoid.asmdef new file mode 100644 index 00000000..444db545 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/UniHumanoid.asmdef @@ -0,0 +1,3 @@ +{ + "name": "UniHumanoid" +} diff --git a/Assets/ThirdParty/VRM/VRM/UniHumanoid/UniHumanoid.asmdef.meta b/Assets/ThirdParty/VRM/VRM/UniHumanoid/UniHumanoid.asmdef.meta new file mode 100644 index 00000000..495819e5 --- /dev/null +++ b/Assets/ThirdParty/VRM/VRM/UniHumanoid/UniHumanoid.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b7aa47b240b57de44a4b2021c143c9bf +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: |