From 7655d4135b5efeff1fd60321089deeb956b31d5a Mon Sep 17 00:00:00 2001 From: Kohei-Yanagida Date: Wed, 28 Aug 2019 19:00:41 +0900 Subject: [PATCH 1/6] add VRM Export Option. Reduce BlendShape Size --- Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs | 11 +++++++---- Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs | 2 +- Assets/VRM/UniGLTF/Scripts/IO/gltfExporter.cs | 8 +++++++- Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs | 8 ++++++-- Assets/VRM/UniVRM/Scripts/Format/VRMExporter.cs | 10 +++++++--- 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs b/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs index a1bec1fae..a54af7f1c 100644 --- a/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs +++ b/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs @@ -106,13 +106,14 @@ namespace UniGLTF static gltfMorphTarget ExportMorphTarget(glTF gltf, int bufferIndex, Mesh mesh, int j, - bool useSparseAccessorForMorphTarget) + bool useSparseAccessorForMorphTarget, + bool exportOnlyBlendShapePosition) { var blendShapeVertices = mesh.vertices; var usePosition = blendShapeVertices != null && blendShapeVertices.Length > 0; var blendShapeNormals = mesh.normals; - var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length; + var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length && exportOnlyBlendShapePosition; var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray(); //var useTangent = usePosition && blendShapeTangents != null && blendShapeTangents.Length == blendShapeVertices.Length; @@ -228,7 +229,8 @@ namespace UniGLTF public static void ExportMeshes(glTF gltf, int bufferIndex, List unityMeshes, List unityMaterials, - bool useSparseAccessorForMorphTarget) + bool useSparseAccessorForMorphTarget, + bool exportOnlyBlendShapePosition) { for (int i = 0; i < unityMeshes.Count; ++i) { @@ -244,7 +246,8 @@ namespace UniGLTF { var morphTarget = ExportMorphTarget(gltf, bufferIndex, mesh, j, - useSparseAccessorForMorphTarget); + useSparseAccessorForMorphTarget, + exportOnlyBlendShapePosition); // // all primitive has same blendShape diff --git a/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs b/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs index b002072fd..2f7d245a0 100644 --- a/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs +++ b/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs @@ -450,7 +450,7 @@ namespace UniGLTF { mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT, blendShape.Positions.ToArray(), - (meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount) ? blendShape.Normals.ToArray() : null, + (meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount && blendShape.Normals.Count() == blendShape.Positions.Count()) ? blendShape.Normals.ToArray() : null, null ); } diff --git a/Assets/VRM/UniGLTF/Scripts/IO/gltfExporter.cs b/Assets/VRM/UniGLTF/Scripts/IO/gltfExporter.cs index 1a4a6e39d..3e5226390 100644 --- a/Assets/VRM/UniGLTF/Scripts/IO/gltfExporter.cs +++ b/Assets/VRM/UniGLTF/Scripts/IO/gltfExporter.cs @@ -60,6 +60,12 @@ namespace UniGLTF set; } + public bool ExportOnlyBlendShapePosition + { + get; + set; + } + public GameObject Copy { get; @@ -240,7 +246,7 @@ namespace UniGLTF return true; }) .ToList(); - MeshExporter.ExportMeshes(gltf, bufferIndex, unityMeshes, Materials, useSparseAccessorForMorphTarget); + MeshExporter.ExportMeshes(gltf, bufferIndex, unityMeshes, Materials, useSparseAccessorForMorphTarget, ExportOnlyBlendShapePosition); Meshes = unityMeshes.Select(x => x.Mesh).ToList(); #endregion diff --git a/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs b/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs index 64a040a05..313c51964 100644 --- a/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs +++ b/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs @@ -6,6 +6,7 @@ using UniGLTF; using System.IO; #if UNITY_EDITOR using UnityEditor; + #endif @@ -26,6 +27,8 @@ namespace VRM public bool UseExperimentalExporter = true; + public bool ReduceBlendshapeSize = false; + public IEnumerable CanExport() { if (Source == null) @@ -152,6 +155,7 @@ namespace VRM { dst.m_center = map[src.m_center]; } + dst.RootBones = src.RootBones.Select(x => map[x]).ToList(); dst.m_hitRadius = src.m_hitRadius; if (src.ColliderGroups != null) @@ -271,7 +275,7 @@ namespace VRM { var sw = System.Diagnostics.Stopwatch.StartNew(); - var vrm = VRMExporter.Export(target); + var vrm = VRMExporter.Export(target, ReduceBlendshapeSize); vrm.extensions.VRM.meta.title = Title; vrm.extensions.VRM.meta.author = Author; @@ -287,4 +291,4 @@ namespace VRM } #endif } -} +} \ No newline at end of file diff --git a/Assets/VRM/UniVRM/Scripts/Format/VRMExporter.cs b/Assets/VRM/UniVRM/Scripts/Format/VRMExporter.cs index a72d0cf6f..8a03bb0db 100644 --- a/Assets/VRM/UniVRM/Scripts/Format/VRMExporter.cs +++ b/Assets/VRM/UniVRM/Scripts/Format/VRMExporter.cs @@ -19,7 +19,7 @@ namespace VRM gltf.extensions.VRM = new glTF_VRM_extensions(); } - public new static glTF Export(GameObject go) + public new static glTF Export(GameObject go, bool exportOnlyBlendShapePosition = false) { var gltf = new glTF(); @@ -27,12 +27,14 @@ namespace VRM { #if VRM_EXPORTER_USE_SPARSE // experimental - UseSparseAccessorForBlendShape=true + UseSparseAccessorForBlendShape = true #endif + ExportOnlyBlendShapePosition = exportOnlyBlendShapePosition }) { _Export(gltf, exporter, go); } + return gltf; } @@ -60,6 +62,7 @@ namespace VRM // use description gltf.extensions.VRM.humanoid.Apply(description, nodes); } + if (isCreated) { GameObject.DestroyImmediate(description); @@ -119,6 +122,7 @@ namespace VRM { gltf.extensions.VRM.meta.texture = TextureIO.ExportTexture(gltf, gltf.buffers.Count - 1, meta.Thumbnail, glTFTextureTypes.Unknown); } + gltf.extensions.VRM.meta.licenseType = meta.LicenseType; gltf.extensions.VRM.meta.otherLicenseUrl = meta.OtherLicenseUrl; gltf.extensions.VRM.meta.reference = meta.Reference; @@ -208,4 +212,4 @@ namespace VRM } } } -} +} \ No newline at end of file From f72917319f7d8966386fddf5710f8e541e12f1e2 Mon Sep 17 00:00:00 2001 From: Kohei-Yanagida Date: Thu, 29 Aug 2019 18:10:02 +0900 Subject: [PATCH 2/6] remove unused blendshape --- Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs | 2 +- .../Scripts/Format/VRMExportSettings.cs | 81 ++++++++++++++++++- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs b/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs index a54af7f1c..8779b17f8 100644 --- a/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs +++ b/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs @@ -113,7 +113,7 @@ namespace UniGLTF var usePosition = blendShapeVertices != null && blendShapeVertices.Length > 0; var blendShapeNormals = mesh.normals; - var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length && exportOnlyBlendShapePosition; + var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length && !exportOnlyBlendShapePosition; var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray(); //var useTangent = usePosition && blendShapeTangents != null && blendShapeTangents.Length == blendShapeVertices.Length; diff --git a/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs b/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs index 313c51964..1c0a3e463 100644 --- a/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs +++ b/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs @@ -27,7 +27,7 @@ namespace VRM public bool UseExperimentalExporter = true; - public bool ReduceBlendshapeSize = false; + public bool ReduceBlendshapeSize = true; public IEnumerable CanExport() { @@ -160,7 +160,8 @@ namespace VRM dst.m_hitRadius = src.m_hitRadius; if (src.ColliderGroups != null) { - dst.ColliderGroups = src.ColliderGroups.Select(x => map[x.transform].GetComponent()).ToArray(); + dst.ColliderGroups = src.ColliderGroups + .Select(x => map[x.transform].GetComponent()).ToArray(); } } } @@ -262,6 +263,7 @@ namespace VRM destroy.Add(target); } } + if (PoseFreeze) { using (new RecordDisposer(target.transform.Traverse().ToArray(), "before normalize")) @@ -273,6 +275,79 @@ namespace VRM } } + // remove unused blendShape + if (ReduceBlendshapeSize) + { + var proxy = target.GetComponent(); + var blendShapClips = proxy.BlendShapeAvatar.Clips; + + var skinMeshedRenderers = target.GetComponentsInChildren(); + + var names = new Dictionary(); + var vs = new Dictionary(); + var ns = new Dictionary(); + var ts = new Dictionary(); + + foreach (SkinnedMeshRenderer smr in skinMeshedRenderers) + { + Mesh mesh = smr.sharedMesh; + if (mesh == null) continue; + if (mesh.blendShapeCount == 0) continue; + + var copyMesh = mesh.Copy(true); + var vCount = copyMesh.vertexCount;names.Clear(); + + vs.Clear(); + ns.Clear(); + ts.Clear(); + + var usedBlendshapeIndexArray = blendShapClips + .SelectMany(clip => clip.Values) + .Where(val => target.transform.Find(val.RelativePath) == smr.transform) + .Select(val => val.Index) + .Distinct() + .ToArray(); + + foreach (var i in usedBlendshapeIndexArray) + { + var name = copyMesh.GetBlendShapeName(i); + var vertices = new Vector3[vCount]; + var normals = new Vector3[vCount]; + var tangents = new Vector3[vCount]; + copyMesh.GetBlendShapeFrameVertices(i, 0, vertices, normals, tangents); + + names.Add(i, name); + vs.Add(i, vertices); + ns.Add(i, normals); + ts.Add(i, tangents); + } + + copyMesh.ClearBlendShapes(); + + foreach (var i in usedBlendshapeIndexArray) + { + copyMesh.AddBlendShapeFrame(names[i], 100f, vs[i], ns[i], ts[i]); + } + + var indexMapper = usedBlendshapeIndexArray + .Select((x, i) => new {x, i}) + .ToDictionary(pair => pair.x, pair => pair.i); + + foreach (var clip in proxy.BlendShapeAvatar.Clips) + { + for (var i = 0; i < clip.Values.Length; ++i) + { + var value = clip.Values[i]; + if (target.transform.Find(value.RelativePath) != smr.transform) continue; + value.Index = indexMapper[value.Index]; + clip.Values[i] = value; + } + } + + smr.sharedMesh = copyMesh; + } + } + { var sw = System.Diagnostics.Stopwatch.StartNew(); var vrm = VRMExporter.Export(target, ReduceBlendshapeSize); @@ -284,6 +359,8 @@ namespace VRM Debug.LogFormat("Export elapsed {0}", sw.Elapsed); } + // PrefabUtility.RevertPrefabInstance(target); + if (path.StartsWithUnityAssetPath()) { AssetDatabase.ImportAsset(path.ToUnityRelativePath()); From b160e4cfb8b4c503b39d36af26e73f0862f466e0 Mon Sep 17 00:00:00 2001 From: Kohei-Yanagida Date: Thu, 29 Aug 2019 22:14:06 +0900 Subject: [PATCH 3/6] fix original blendshap clip changed --- .../Scripts/Format/VRMExportSettings.cs | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs b/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs index 1c0a3e463..720bbca57 100644 --- a/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs +++ b/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs @@ -133,7 +133,7 @@ namespace VRM var dstColliderGroup = dst.gameObject.AddComponent(); dstColliderGroup.Colliders = src.Colliders.Select(y => { - var offset = dst.worldToLocalMatrix.MultiplyPoint(src.transform.localToWorldMatrix.MultiplyPoint(y.Offset)); + var offset =dst.worldToLocalMatrix.MultiplyPoint(src.transform.localToWorldMatrix.MultiplyPoint(y.Offset)); return new VRMSpringBoneColliderGroup.SphereCollider { Offset = offset, @@ -279,29 +279,38 @@ namespace VRM if (ReduceBlendshapeSize) { var proxy = target.GetComponent(); - var blendShapClips = proxy.BlendShapeAvatar.Clips; - var skinMeshedRenderers = target.GetComponentsInChildren(); - + // 元のBlendShapeClipに変更を加えないように複製 + var copyBlendShapeAvatar = GameObject.Instantiate(proxy.BlendShapeAvatar); + var copyBlendShapClips = new List(); + + foreach (var clip in proxy.BlendShapeAvatar.Clips) + { + copyBlendShapClips.Add(GameObject.Instantiate(clip)); + } + + var skinnedMeshRenderers = target.GetComponentsInChildren(); + var names = new Dictionary(); var vs = new Dictionary(); var ns = new Dictionary(); var ts = new Dictionary(); - foreach (SkinnedMeshRenderer smr in skinMeshedRenderers) + foreach (SkinnedMeshRenderer smr in skinnedMeshRenderers) { Mesh mesh = smr.sharedMesh; if (mesh == null) continue; if (mesh.blendShapeCount == 0) continue; var copyMesh = mesh.Copy(true); - var vCount = copyMesh.vertexCount;names.Clear(); - + var vCount = copyMesh.vertexCount; + names.Clear(); + vs.Clear(); ns.Clear(); ts.Clear(); - var usedBlendshapeIndexArray = blendShapClips + var usedBlendshapeIndexArray = copyBlendShapClips .SelectMany(clip => clip.Values) .Where(val => target.transform.Find(val.RelativePath) == smr.transform) .Select(val => val.Index) @@ -323,7 +332,7 @@ namespace VRM } copyMesh.ClearBlendShapes(); - + foreach (var i in usedBlendshapeIndexArray) { copyMesh.AddBlendShapeFrame(names[i], 100f, vs[i], ns[i], ts[i]); @@ -333,7 +342,7 @@ namespace VRM .Select((x, i) => new {x, i}) .ToDictionary(pair => pair.x, pair => pair.i); - foreach (var clip in proxy.BlendShapeAvatar.Clips) + foreach (var clip in copyBlendShapClips) { for (var i = 0; i < clip.Values.Length; ++i) { @@ -344,6 +353,10 @@ namespace VRM } } + copyBlendShapeAvatar.Clips = copyBlendShapClips; + + proxy.BlendShapeAvatar = copyBlendShapeAvatar; + smr.sharedMesh = copyMesh; } } @@ -359,7 +372,7 @@ namespace VRM Debug.LogFormat("Export elapsed {0}", sw.Elapsed); } - // PrefabUtility.RevertPrefabInstance(target); + PrefabUtility.RevertPrefabInstance(target); if (path.StartsWithUnityAssetPath()) { From 62f7fce429786ae0737b615522d7be3a946ab435 Mon Sep 17 00:00:00 2001 From: Kohei-Yanagida Date: Tue, 3 Sep 2019 21:24:00 +0900 Subject: [PATCH 4/6] fix Obsolete Warning --- Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs b/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs index 720bbca57..df4c2d834 100644 --- a/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs +++ b/Assets/VRM/UniVRM/Scripts/Format/VRMExportSettings.cs @@ -372,7 +372,11 @@ namespace VRM Debug.LogFormat("Export elapsed {0}", sw.Elapsed); } +#if UNITY_2018_3_OR_NEWER + PrefabUtility.RevertPrefabInstance(target, InteractionMode.AutomatedAction); +#else PrefabUtility.RevertPrefabInstance(target); +#endif if (path.StartsWithUnityAssetPath()) { From 0aee5e6afe4a295c5d95bb3050cf4ee4a8ee39ab Mon Sep 17 00:00:00 2001 From: Kohei-Yanagida Date: Fri, 20 Sep 2019 19:57:58 +0900 Subject: [PATCH 5/6] revert removing blendshape normals option --- Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs | 3 ++- Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs b/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs index 8779b17f8..7714f455e 100644 --- a/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs +++ b/Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs @@ -113,7 +113,8 @@ namespace UniGLTF var usePosition = blendShapeVertices != null && blendShapeVertices.Length > 0; var blendShapeNormals = mesh.normals; - var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length && !exportOnlyBlendShapePosition; + var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length; + // var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length && !exportOnlyBlendShapePosition; var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray(); //var useTangent = usePosition && blendShapeTangents != null && blendShapeTangents.Length == blendShapeVertices.Length; diff --git a/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs b/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs index 2f7d245a0..b002072fd 100644 --- a/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs +++ b/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs @@ -450,7 +450,7 @@ namespace UniGLTF { mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT, blendShape.Positions.ToArray(), - (meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount && blendShape.Normals.Count() == blendShape.Positions.Count()) ? blendShape.Normals.ToArray() : null, + (meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount) ? blendShape.Normals.ToArray() : null, null ); } From 935913ca132b2e30b9784f77ce17882ff5036f9b Mon Sep 17 00:00:00 2001 From: Kohei-Yanagida Date: Tue, 24 Sep 2019 16:32:25 +0900 Subject: [PATCH 6/6] fix mesh importer --- Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs b/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs index b002072fd..2f7d245a0 100644 --- a/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs +++ b/Assets/VRM/UniGLTF/Scripts/IO/MeshImporter.cs @@ -450,7 +450,7 @@ namespace UniGLTF { mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT, blendShape.Positions.ToArray(), - (meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount) ? blendShape.Normals.ToArray() : null, + (meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount && blendShape.Normals.Count() == blendShape.Positions.Count()) ? blendShape.Normals.ToArray() : null, null ); }