From 205bd9a82fd29c82f24513edeac3bffaf20dffee Mon Sep 17 00:00:00 2001 From: hybridherbst Date: Sat, 6 Jan 2024 15:16:22 +0100 Subject: [PATCH] move blendshape target names to mesh, according to https://github.com/KhronosGroup/glTF/pull/1631 --- .../GLTFSerialization/Schema/GLTFMesh.cs | 25 ++++++---- .../GLTFSerialization/Schema/MeshPrimitive.cs | 46 ------------------- .../Scripts/SceneExporter/ExporterMeshes.cs | 8 ++-- .../SceneImporter/ImporterAnimation.cs | 11 ++--- .../Scripts/SceneImporter/ImporterMeshes.cs | 6 ++- 5 files changed, 29 insertions(+), 67 deletions(-) diff --git a/Runtime/Plugins/GLTFSerialization/Schema/GLTFMesh.cs b/Runtime/Plugins/GLTFSerialization/Schema/GLTFMesh.cs index ba35dcd6a..6bae59322 100644 --- a/Runtime/Plugins/GLTFSerialization/Schema/GLTFMesh.cs +++ b/Runtime/Plugins/GLTFSerialization/Schema/GLTFMesh.cs @@ -95,15 +95,6 @@ public static GLTFMesh Deserialize(GLTFRoot root, JsonReader reader) } extrasReader.Close(); - - if (mesh.Primitives != null && mesh.TargetNames != null && mesh.TargetNames.Count > 0) - { - foreach (MeshPrimitive mp in mesh.Primitives) - { - if (mp == null) continue; - mp.TargetNames = mesh.TargetNames; - } - } } return mesh; @@ -134,6 +125,22 @@ public override void Serialize(JsonWriter writer) } writer.WriteEndArray(); } + + // GLTF does not support morph target names, serialize in extras for now + // https://github.com/KhronosGroup/glTF/issues/1036 + if (TargetNames != null && TargetNames.Count > 0) + { + writer.WritePropertyName("extras"); + writer.WriteStartObject(); + writer.WritePropertyName("targetNames"); + writer.WriteStartArray(); + foreach (var targetName in TargetNames) + { + writer.WriteValue(targetName); + } + writer.WriteEndArray(); + writer.WriteEndObject(); + } base.Serialize(writer); diff --git a/Runtime/Plugins/GLTFSerialization/Schema/MeshPrimitive.cs b/Runtime/Plugins/GLTFSerialization/Schema/MeshPrimitive.cs index 5a075034f..fe90ab6e4 100644 --- a/Runtime/Plugins/GLTFSerialization/Schema/MeshPrimitive.cs +++ b/Runtime/Plugins/GLTFSerialization/Schema/MeshPrimitive.cs @@ -47,8 +47,6 @@ public class MeshPrimitive : GLTFProperty /// TODO: Make dictionary key enums? public List> Targets; - public List TargetNames; - public MeshPrimitive() { } @@ -91,11 +89,6 @@ public MeshPrimitive(MeshPrimitive meshPrimitive, GLTFRoot gltfRoot) : base(mesh Targets.Add(target); } } - - if (meshPrimitive.TargetNames != null) - { - TargetNames = new List(meshPrimitive.TargetNames); - } } public static int[] GenerateTriangles(int vertCount) @@ -153,30 +146,6 @@ public static MeshPrimitive Deserialize(GLTFRoot root, JsonReader reader) break; } } - - // GLTF does not support morph target names, serialize in extras for now - // https://github.com/KhronosGroup/glTF/issues/1036 - if (primitive.Extras != null) - { - var extrasReader = primitive.Extras.CreateReader(); - extrasReader.Read(); - - while (extrasReader.Read() && extrasReader.TokenType == JsonToken.PropertyName) - { - var extraProperty = extrasReader.Value.ToString(); - switch (extraProperty) - { - case "targetNames": - primitive.TargetNames = extrasReader.ReadStringList(); - break; - default: - extrasReader.Skip(); - break; - } - } - - extrasReader.Close(); - } return primitive; } @@ -230,21 +199,6 @@ public override void Serialize(JsonWriter writer) } writer.WriteEndArray(); } - // GLTF does not support morph target names, serialize in extras for now - // https://github.com/KhronosGroup/glTF/issues/1036 - if (TargetNames != null && TargetNames.Count > 0) - { - writer.WritePropertyName("extras"); - writer.WriteStartObject(); - writer.WritePropertyName("targetNames"); - writer.WriteStartArray(); - foreach (var targetName in TargetNames) - { - writer.WriteValue(targetName); - } - writer.WriteEndArray(); - writer.WriteEndObject(); - } base.Serialize(writer); diff --git a/Runtime/Scripts/SceneExporter/ExporterMeshes.cs b/Runtime/Scripts/SceneExporter/ExporterMeshes.cs index de42b8564..40ffe0923 100644 --- a/Runtime/Scripts/SceneExporter/ExporterMeshes.cs +++ b/Runtime/Scripts/SceneExporter/ExporterMeshes.cs @@ -364,9 +364,9 @@ private void ExportBlendShapes(SkinnedMeshRenderer smr, Mesh meshObj, int submes if (_meshToBlendShapeAccessors.TryGetValue(meshObj, out var data)) { - mesh.Weights = data.weights; primitive.Targets = data.targets; - primitive.TargetNames = data.targetNames; + mesh.Weights = data.weights; + mesh.TargetNames = data.targetNames; return; } @@ -474,14 +474,14 @@ private void ExportBlendShapes(SkinnedMeshRenderer smr, Mesh meshObj, int submes if(weights.Any() && targets.Any()) { mesh.Weights = weights; + mesh.TargetNames = targetNames; primitive.Targets = targets; - primitive.TargetNames = targetNames; } else { mesh.Weights = null; + mesh.TargetNames = null; primitive.Targets = null; - primitive.TargetNames = null; } // cache the exported data; we can re-use it between all submeshes of a mesh. diff --git a/Runtime/Scripts/SceneImporter/ImporterAnimation.cs b/Runtime/Scripts/SceneImporter/ImporterAnimation.cs index 056bb5850..12a56c688 100644 --- a/Runtime/Scripts/SceneImporter/ImporterAnimation.cs +++ b/Runtime/Scripts/SceneImporter/ImporterAnimation.cs @@ -333,19 +333,18 @@ protected async Task ConstructClip(Transform root, int animationI break; case GLTFAnimationChannelPath.weights: - var primitives = channel.Target.Node.Value.Mesh.Value.Primitives; + var mesh = channel.Target.Node.Value.Mesh.Value; + var primitives = mesh.Primitives; if (primitives[0].Targets == null) break; var targetCount = primitives[0].Targets.Count; for (int primitiveIndex = 0; primitiveIndex < primitives.Count; primitiveIndex++) { // see SceneImporter:156 - // blend shapes are always called "Morphtarget" and always have frame weight 100 on import - - var prim = primitives[primitiveIndex]; - var targetNames = prim.TargetNames; + // blend shapes are always called "Morphtarget" + var targetNames = mesh.TargetNames; propertyNames = new string[targetCount]; for (var i = 0; i < targetCount; i++) - propertyNames[i] = _options.ImportBlendShapeNames ? ("blendShape." + (targetNames != null ? targetNames[i] : ("Morphtarget" + i))) : "blendShape."+i.ToString(); + propertyNames[i] = _options.ImportBlendShapeNames ? ("blendShape." + ((targetNames != null && targetNames.Count > i) ? targetNames[i] : ("Morphtarget" + i))) : "blendShape."+i.ToString(); var frameFloats = new float[targetCount]; SetAnimationCurve(clip, relativePath, propertyNames, input, output, diff --git a/Runtime/Scripts/SceneImporter/ImporterMeshes.cs b/Runtime/Scripts/SceneImporter/ImporterMeshes.cs index 565b8ecf0..45b6c5e42 100644 --- a/Runtime/Scripts/SceneImporter/ImporterMeshes.cs +++ b/Runtime/Scripts/SceneImporter/ImporterMeshes.cs @@ -510,10 +510,12 @@ private void AddBlendShapesToMesh(UnityMeshData unityMeshData, int meshIndex, Me { if (unityMeshData.MorphTargetVertices != null) { - var firstPrim = _gltfRoot.Meshes[meshIndex].Primitives[0]; + var gltfMesh = _gltfRoot.Meshes[meshIndex]; + var firstPrim = gltfMesh.Primitives[0]; + // TODO theoretically there could be multiple prims and only one of them has morph targets for (int i = 0; i < firstPrim.Targets.Count; i++) { - var targetName = _options.ImportBlendShapeNames ? (firstPrim.TargetNames != null ? firstPrim.TargetNames[i] : $"Morphtarget{i}") : i.ToString(); + var targetName = _options.ImportBlendShapeNames ? ((gltfMesh.TargetNames != null && gltfMesh.TargetNames.Count > i) ? gltfMesh.TargetNames[i] : $"Morphtarget{i}") : i.ToString(); mesh.AddBlendShapeFrame(targetName, 1f, unityMeshData.MorphTargetVertices[i], unityMeshData.MorphTargetNormals != null ? unityMeshData.MorphTargetNormals[i] : null,