Skip to content

Commit

Permalink
move blendshape target names to mesh, according to KhronosGroup/glTF#…
Browse files Browse the repository at this point in the history
  • Loading branch information
hybridherbst committed Jan 6, 2024
1 parent 99e66cc commit 205bd9a
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 67 deletions.
25 changes: 16 additions & 9 deletions Runtime/Plugins/GLTFSerialization/Schema/GLTFMesh.cs
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
46 changes: 0 additions & 46 deletions Runtime/Plugins/GLTFSerialization/Schema/MeshPrimitive.cs
Expand Up @@ -47,8 +47,6 @@ public class MeshPrimitive : GLTFProperty
/// TODO: Make dictionary key enums?
public List<Dictionary<string, AccessorId>> Targets;

public List<string> TargetNames;

public MeshPrimitive()
{
}
Expand Down Expand Up @@ -91,11 +89,6 @@ public MeshPrimitive(MeshPrimitive meshPrimitive, GLTFRoot gltfRoot) : base(mesh
Targets.Add(target);
}
}

if (meshPrimitive.TargetNames != null)
{
TargetNames = new List<string>(meshPrimitive.TargetNames);
}
}

public static int[] GenerateTriangles(int vertCount)
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);

Expand Down
8 changes: 4 additions & 4 deletions Runtime/Scripts/SceneExporter/ExporterMeshes.cs
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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.
Expand Down
11 changes: 5 additions & 6 deletions Runtime/Scripts/SceneImporter/ImporterAnimation.cs
Expand Up @@ -333,19 +333,18 @@ protected async Task<AnimationClip> 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,
Expand Down
6 changes: 4 additions & 2 deletions Runtime/Scripts/SceneImporter/ImporterMeshes.cs
Expand Up @@ -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,
Expand Down

0 comments on commit 205bd9a

Please sign in to comment.