diff --git a/Assets/VRM/UniHumanoid/Scripts/AvatarDescription.cs b/Assets/VRM/UniHumanoid/Scripts/AvatarDescription.cs index ebb3bceeac..05a3abd6e6 100644 --- a/Assets/VRM/UniHumanoid/Scripts/AvatarDescription.cs +++ b/Assets/VRM/UniHumanoid/Scripts/AvatarDescription.cs @@ -19,12 +19,13 @@ public struct BoneLimit 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), + humanBone = (HumanBodyBones) Enum.Parse(typeof(HumanBodyBones), bone.humanName.Replace(" ", ""), true), boneName = bone.boneName, useDefaultValues = bone.limit.useDefaultValues, min = bone.limit.min, @@ -36,7 +37,13 @@ public static BoneLimit From(HumanBone bone) public static String ToHumanBoneName(HumanBodyBones b) { - foreach (var x in HumanTrait.BoneName) + // 呼び出し毎にGCが発生するのでキャッシュする + if (cashedHumanTraitBoneName == null) + { + cashedHumanTraitBoneName = HumanTrait.BoneName; + } + + foreach (var x in cashedHumanTraitBoneName) { if (x.Replace(" ", "") == b.ToString()) { @@ -80,10 +87,28 @@ public class AvatarDescription : ScriptableObject public HumanDescription ToHumanDescription(Transform root) { + var transforms = root.GetComponentsInChildren(); + 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 = root.Traverse().Select(x => x.ToSkeletonBone()).ToArray(), - human = human.Select(x => x.ToHumanBone()).ToArray(), + skeleton = skeletonBones, + human = humanBones, armStretch = armStretch, legStretch = legStretch, upperArmTwist = upperArmTwist, @@ -154,7 +179,7 @@ public static AvatarDescription CreateFrom(HumanDescription description) return avatarDescription; } - public static AvatarDescription Create(AvatarDescription src=null) + public static AvatarDescription Create(AvatarDescription src = null) { var avatarDescription = ScriptableObject.CreateInstance(); avatarDescription.name = "AvatarDescription"; @@ -178,6 +203,7 @@ public static AvatarDescription Create(AvatarDescription src=null) avatarDescription.upperLegTwist = 0.5f; avatarDescription.lowerLegTwist = 0.5f; } + return avatarDescription; } @@ -235,8 +261,9 @@ public static bool GetHumanDescription(UnityEngine.Object target, ref HumanDescr } } } + return false; } #endif } -} +} \ No newline at end of file diff --git a/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs b/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs index 7f1bd1ef62..5e9b1d0768 100644 --- a/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs +++ b/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs @@ -97,18 +97,17 @@ private void Reset() public void TraverseRenderers(VRMImporterContext context = null) { - Renderers = Traverse(transform) - .Select(x => x.GetComponent()) - .Where(x => x != null) - .Select(x => new RendererFirstPersonFlags + var rendererComponents = transform.GetComponentsInChildren(); + foreach (var renderer in rendererComponents) + { + Renderers.Add(new RendererFirstPersonFlags { - Renderer = x, + Renderer = renderer, FirstPersonFlag = context == null ? FirstPersonFlag.Auto - : GetFirstPersonFlag(context, x) - }) - .ToList() - ; + : GetFirstPersonFlag(context, renderer) + }); + } } static FirstPersonFlag GetFirstPersonFlag(VRMImporterContext context, Renderer r) diff --git a/Assets/VRM/UniVRM/Scripts/Format/glTF_VRM_Humanoid.cs b/Assets/VRM/UniVRM/Scripts/Format/glTF_VRM_Humanoid.cs index ef1527b420..5061ff7e25 100644 --- a/Assets/VRM/UniVRM/Scripts/Format/glTF_VRM_Humanoid.cs +++ b/Assets/VRM/UniVRM/Scripts/Format/glTF_VRM_Humanoid.cs @@ -75,6 +75,7 @@ public static VRMBone FromHumanBodyBone(this HumanBodyBones human) { return EnumUtil.TryParseOrDefault(human.ToString(), VRMBone.unknown); } + public static HumanBodyBones ToHumanBodyBone(this VRMBone bone) { #if UNITY_5_6_OR_NEWER @@ -92,7 +93,8 @@ public static HumanBodyBones ToHumanBodyBone(this VRMBone bone) [JsonSchema(Title = "vrm.humanoid.bone")] public class glTF_VRM_HumanoidBone : JsonSerializableBase { - [JsonSchema(Description = "Human bone name.", EnumValues = new object[] { + [JsonSchema(Description = "Human bone name.", EnumValues = new object[] + { "hips", "leftUpperLeg", "rightUpperLeg", @@ -148,8 +150,9 @@ public class glTF_VRM_HumanoidBone : JsonSerializableBase "rightLittleIntermediate", "rightLittleDistal", "upperChest", - }, EnumSerializationType =EnumSerializationType.AsString)] + }, EnumSerializationType = EnumSerializationType.AsString)] public string bone; + public VRMBone vrmBone { set @@ -183,7 +186,7 @@ public VRMBone vrmBone protected override void SerializeMembers(GLTFJsonFormatter f) { - f.Key("bone"); f.Value((string)bone.ToString()); + f.Key("bone"); f.Value((string) bone.ToString()); f.KeyValue(() => node); f.KeyValue(() => useDefaultValues); if (!useDefaultValues) @@ -281,6 +284,7 @@ public void Apply(UniHumanoid.AvatarDescription desc, List nodes) }; humanBones.Add(found); } + found.node = nodes.FindIndex(y => y.name == x.boneName); found.useDefaultValues = x.useDefaultValues; @@ -301,9 +305,13 @@ public UniHumanoid.AvatarDescription ToDescription(List nodes) description.armStretch = armStretch; description.legStretch = legStretch; description.hasTranslationDoF = hasTranslationDoF; - description.human = humanBones - .Where(x => x.node >= 0 && x.node < nodes.Count) - .Select(x => new UniHumanoid.BoneLimit + + var boneLimits = new UniHumanoid.BoneLimit[humanBones.Count]; + int index = 0; + foreach (var x in humanBones) + { + if (x.node < 0 || x.node >= nodes.Count) continue; + boneLimits[index] = new UniHumanoid.BoneLimit { boneName = nodes[x.node].name, useDefaultValues = x.useDefaultValues, @@ -312,10 +320,13 @@ public UniHumanoid.AvatarDescription ToDescription(List nodes) min = x.min, max = x.max, humanBone = x.vrmBone.ToHumanBodyBone(), - }) - .Where(x => x.humanBone != HumanBodyBones.LastBone) - .ToArray(); + }; + index++; + } + + description.human = boneLimits; + return description; } } -} +} \ No newline at end of file diff --git a/Assets/VRM/UniVRM/Scripts/SpringBone/VRMSpringUtility.cs b/Assets/VRM/UniVRM/Scripts/SpringBone/VRMSpringUtility.cs index 25a9d1bb57..1088022473 100644 --- a/Assets/VRM/UniVRM/Scripts/SpringBone/VRMSpringUtility.cs +++ b/Assets/VRM/UniVRM/Scripts/SpringBone/VRMSpringUtility.cs @@ -7,6 +7,7 @@ using System.Text; #if UNITY_EDITOR using UnityEditor; + #endif @@ -15,7 +16,9 @@ namespace VRM public static class VRMSpringUtility { #if UNITY_EDITOR + #region save + [MenuItem(VRMVersion.MENU + "/SaveSpringBoneToJSON", validate = true)] static bool SaveSpringBoneToJSONIsEnable() { @@ -38,10 +41,10 @@ static bool SaveSpringBoneToJSONIsEnable() static void SaveSpringBoneToJSON() { var path = EditorUtility.SaveFilePanel( - "Save spring to json", - null, - "VRMSpring.json", - "json"); + "Save spring to json", + null, + "VRMSpring.json", + "json"); if (string.IsNullOrEmpty(path)) { return; @@ -54,7 +57,7 @@ static void SaveSpringBoneToJSON() ExportSecondary(root, nodes, spring.colliderGroups.Add, spring.boneGroups.Add - ); + ); File.WriteAllText(path, spring.ToJson()); } @@ -62,6 +65,7 @@ static void SaveSpringBoneToJSON() #endregion #region load + [MenuItem(VRMVersion.MENU + "/LoadSpringBoneFromJSON", true)] static bool LoadSpringBoneFromJSONIsEnable() { @@ -84,9 +88,9 @@ static bool LoadSpringBoneFromJSONIsEnable() static void LoadSpringBoneFromJSON() { var path = EditorUtility.OpenFilePanel( - "Load spring from json", - null, - "json"); + "Load spring from json", + null, + "json"); if (string.IsNullOrEmpty(path)) { return; @@ -101,7 +105,9 @@ static void LoadSpringBoneFromJSON() LoadSecondary(root, nodes, spring); } + #endregion + #endif public static void ExportSecondary(Transform root, List nodes, @@ -127,7 +133,6 @@ public static void ExportSecondary(Transform root, List nodes, offset = x.Offset, radius = x.Radius, }; - }).ToList(); addSecondaryColliderGroup(colliderGroup); @@ -166,10 +171,29 @@ public static void LoadSecondary(Transform root, List nodes, } // clear components - var remove = root.Traverse() - .SelectMany(x => x.GetComponents()) - .Where(x => x is VRMSpringBone || x is VRMSpringBoneColliderGroup) - .ToArray(); + var vrmSpringBones = root.GetComponentsInChildren(); + var vrmSpringBoneColliderGroup = root.GetComponentsInChildren(); + + var length = (vrmSpringBones?.Length ?? 0) + (vrmSpringBoneColliderGroup?.Length ?? 0); + var remove = new Component[length]; + + var index = 0; + if (vrmSpringBones != null) + { + foreach (var vrmSpringBone in vrmSpringBones) + { + remove[index++] = vrmSpringBone; + } + } + + if (vrmSpringBoneColliderGroup != null) + { + foreach (var vrmSpringBoneCollider in vrmSpringBoneColliderGroup) + { + remove[index++] = vrmSpringBoneCollider; + } + } + foreach (var x in remove) { if (Application.isPlaying) @@ -207,17 +231,33 @@ public static void LoadSecondary(Transform root, List nodes, { vrmBoneGroup.m_center = nodes[boneGroup.center]; } + vrmBoneGroup.m_comment = boneGroup.comment; vrmBoneGroup.m_dragForce = boneGroup.dragForce; vrmBoneGroup.m_gravityDir = boneGroup.gravityDir; vrmBoneGroup.m_gravityPower = boneGroup.gravityPower; vrmBoneGroup.m_hitRadius = boneGroup.hitRadius; vrmBoneGroup.m_stiffnessForce = boneGroup.stiffiness; + if (boneGroup.colliderGroups != null && boneGroup.colliderGroups.Any()) { - vrmBoneGroup.ColliderGroups = boneGroup.colliderGroups.Select(x => colliders[x]).ToArray(); + var colliderGroups = new VRMSpringBoneColliderGroup[boneGroup.colliderGroups.Length]; + int i = 0; + foreach (var colliderGroup in boneGroup.colliderGroups) + { + colliderGroups[i] = colliders[colliderGroup]; + } + + vrmBoneGroup.ColliderGroups = colliderGroups; + } + + var boneList = new List(); + foreach (var x in boneGroup.bones) + { + boneList.Add(nodes[x]); } - vrmBoneGroup.RootBones = boneGroup.bones.Select(x => nodes[x]).ToList(); + + vrmBoneGroup.RootBones = boneList; } } else @@ -225,6 +265,5 @@ public static void LoadSecondary(Transform root, List nodes, secondary.gameObject.AddComponent(); } } - } -} +} \ No newline at end of file