diff options
Diffstat (limited to 'Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AvatarDescription.cs')
-rw-r--r-- | Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/AvatarDescription.cs | 269 |
1 files changed, 269 insertions, 0 deletions
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 |