From 9e016736f0d033dbeb2b5bf9f75dff2d4d267fe7 Mon Sep 17 00:00:00 2001 From: "Sergio R. Z. Masson" <97050577+SergioRZMasson@users.noreply.github.com> Date: Tue, 12 Mar 2024 15:21:45 -0300 Subject: [PATCH] Add support for 8 uv channels (#1113) Extended the number of UV channels from 2 to 8. --- Maya/Exporter/BabylonExporter.Mesh.cs | 99 +++++++---- Maya/Exporter/GlobalVertex.cs | 18 ++ .../Babylon2GLTF/GLTFExporter.Mesh.cs | 160 ++++++++++++++++++ .../Babylon2GLTF/GLTFGlobalVertex.cs | 6 + .../BabylonExport.Entities/BabylonMesh.cs | 8 + .../BabylonVertexData.cs | 10 +- .../Extensions/BabylonMeshExtensions.cs | 2 + .../GltfExport.Entities/GLTFMeshPrimitive.cs | 6 + 8 files changed, 274 insertions(+), 35 deletions(-) diff --git a/Maya/Exporter/BabylonExporter.Mesh.cs b/Maya/Exporter/BabylonExporter.Mesh.cs index be3888b8..5d39f4b8 100644 --- a/Maya/Exporter/BabylonExporter.Mesh.cs +++ b/Maya/Exporter/BabylonExporter.Mesh.cs @@ -15,7 +15,7 @@ internal partial class BabylonExporter private MStringArray allMayaInfluenceNames; // the joint names that influence the mesh (joint with 0 weight included) private MDoubleArray allMayaInfluenceWeights; // the joint weights for the vertex (0 weight included) private Dictionary indexByNodeName = new Dictionary(); // contains the node (joint and parents of the current skin) fullPathName and its index - + /// /// /// @@ -496,7 +496,7 @@ private BabylonNode ExportMesh(MDagPath mDagPath, BabylonScene babylonScene) var uvSetNames = new MStringArray(); mFnMesh.getUVSetNames(uvSetNames); - bool[] isUVExportSuccess = new bool[Math.Min(uvSetNames.Count, 2)]; + bool[] isUVExportSuccess = new bool[Math.Min(uvSetNames.Count, 8)]; for (int indexUVSet = 0; indexUVSet < isUVExportSuccess.Length; indexUVSet++) { isUVExportSuccess[indexUVSet] = true; @@ -584,13 +584,36 @@ private BabylonNode ExportMesh(MDagPath mDagPath, BabylonScene babylonScene) // UVs if (uvSetNames.Count > 0 && isUVExportSuccess[0]) { - babylonMesh.uvs = vertices.SelectMany(v => v.UV).ToArray(); } if (uvSetNames.Count > 1 && isUVExportSuccess[1]) { babylonMesh.uvs2 = vertices.SelectMany(v => v.UV2).ToArray(); } + if (uvSetNames.Count > 2 && isUVExportSuccess[2]) + { + babylonMesh.uvs3 = vertices.SelectMany(v => v.UV3).ToArray(); + } + if (uvSetNames.Count > 3 && isUVExportSuccess[3]) + { + babylonMesh.uvs4 = vertices.SelectMany(v => v.UV4).ToArray(); + } + if (uvSetNames.Count > 4 && isUVExportSuccess[4]) + { + babylonMesh.uvs5 = vertices.SelectMany(v => v.UV5).ToArray(); + } + if (uvSetNames.Count > 5 && isUVExportSuccess[5]) + { + babylonMesh.uvs6 = vertices.SelectMany(v => v.UV6).ToArray(); + } + if (uvSetNames.Count > 6 && isUVExportSuccess[6]) + { + babylonMesh.uvs7 = vertices.SelectMany(v => v.UV7).ToArray(); + } + if (uvSetNames.Count > 7 && isUVExportSuccess[7]) + { + babylonMesh.uvs8 = vertices.SelectMany(v => v.UV8).ToArray(); + } babylonMesh.subMeshes = subMeshes.ToArray(); @@ -824,6 +847,37 @@ private void ExtractGeometry(BabylonMesh babylonMesh, MFnMesh mFnMesh, List + /// Extract vertex UV for the given UV channel. + /// + /// + /// The polygon (face) to examine + /// The face-relative (local) vertex id to examine + /// Index of the target UV set. + /// + /// + /// + private float[] ExtractVertexUV(MFnMesh mFnMesh, int polygonId, int vertexIndexLocal, int indexUVSet, MStringArray uvSetNames,ref bool[] isUVExportSuccess) + { + if (uvSetNames.Count > indexUVSet && isUVExportSuccess[indexUVSet]) + { + try + { + float u = 0, v = 0; + mFnMesh.getPolygonUV(polygonId, vertexIndexLocal, ref u, ref v, uvSetNames[indexUVSet]); + return new float[] { u, v }; + } + catch + { + // An exception is raised when a vertex isn't mapped to an UV coordinate + isUVExportSuccess[indexUVSet] = false; + return null; + } + } + + return null; + } + /// /// Extract geometry (position, normal, UVs...) for a specific vertex /// @@ -907,37 +961,14 @@ private GlobalVertex ExtractVertex(MFnMesh mFnMesh, int polygonId, int vertexInd } } - // UV - int indexUVSet = 0; - if (uvSetNames.Count > indexUVSet && isUVExportSuccess[indexUVSet]) - { - try - { - float u = 0, v = 0; - mFnMesh.getPolygonUV(polygonId, vertexIndexLocal, ref u, ref v, uvSetNames[indexUVSet]); - vertex.UV = new float[] { u, v }; - } - catch - { - // An exception is raised when a vertex isn't mapped to an UV coordinate - isUVExportSuccess[indexUVSet] = false; - } - } - indexUVSet = 1; - if (uvSetNames.Count > indexUVSet && isUVExportSuccess[indexUVSet]) - { - try - { - float u = 0, v = 0; - mFnMesh.getPolygonUV(polygonId, vertexIndexLocal, ref u, ref v, uvSetNames[indexUVSet]); - vertex.UV2 = new float[] { u, v }; - } - catch - { - // An exception is raised when a vertex isn't mapped to an UV coordinate - isUVExportSuccess[indexUVSet] = false; - } - } + vertex.UV = ExtractVertexUV(mFnMesh, polygonId, vertexIndexLocal, 0, uvSetNames, ref isUVExportSuccess); // UV + vertex.UV2 = ExtractVertexUV(mFnMesh, polygonId, vertexIndexLocal, 1, uvSetNames, ref isUVExportSuccess); // UV2 + vertex.UV3 = ExtractVertexUV(mFnMesh, polygonId, vertexIndexLocal, 2, uvSetNames, ref isUVExportSuccess); // UV3 + vertex.UV4 = ExtractVertexUV(mFnMesh, polygonId, vertexIndexLocal, 3, uvSetNames, ref isUVExportSuccess); // UV4 + vertex.UV5 = ExtractVertexUV(mFnMesh, polygonId, vertexIndexLocal, 4, uvSetNames, ref isUVExportSuccess); // UV5 + vertex.UV6 = ExtractVertexUV(mFnMesh, polygonId, vertexIndexLocal, 5, uvSetNames, ref isUVExportSuccess); // UV6 + vertex.UV7 = ExtractVertexUV(mFnMesh, polygonId, vertexIndexLocal, 6, uvSetNames, ref isUVExportSuccess); // UV7 + vertex.UV8 = ExtractVertexUV(mFnMesh, polygonId, vertexIndexLocal, 7, uvSetNames, ref isUVExportSuccess); // UV8 // skin if (mFnSkinCluster != null) diff --git a/Maya/Exporter/GlobalVertex.cs b/Maya/Exporter/GlobalVertex.cs index f05437bf..610a34d5 100644 --- a/Maya/Exporter/GlobalVertex.cs +++ b/Maya/Exporter/GlobalVertex.cs @@ -11,6 +11,12 @@ public struct GlobalVertex public float[] Tangent { get; set; } // Vec3 public float[] UV { get; set; } // Vec2 public float[] UV2 { get; set; } // Vec2 + public float[] UV3 { get; set; } // Vec2 + public float[] UV4 { get; set; } // Vec2 + public float[] UV5 { get; set; } // Vec2 + public float[] UV6 { get; set; } // Vec2 + public float[] UV7 { get; set; } // Vec2 + public float[] UV8 { get; set; } // Vec2 public int BonesIndices { get; set; } public float[] Weights { get; set; } // Vec4 public int BonesIndicesExtra { get; set; } @@ -26,6 +32,12 @@ public GlobalVertex(GlobalVertex other) this.Tangent = other.Tangent; this.UV = other.UV; this.UV2 = other.UV2; + this.UV3 = other.UV3; + this.UV4 = other.UV4; + this.UV5 = other.UV5; + this.UV6 = other.UV6; + this.UV7 = other.UV7; + this.UV8 = other.UV8; this.BonesIndices = other.BonesIndices; this.Weights = other.Weights; this.BonesIndicesExtra = other.BonesIndicesExtra; @@ -49,6 +61,12 @@ public override bool Equals(object obj) other.Normal.IsAlmostEqualTo(Normal, Tools.Epsilon) & other.UV.IsAlmostEqualTo(UV, Tools.Epsilon) && other.UV2.IsAlmostEqualTo(UV2, Tools.Epsilon) && + other.UV3.IsAlmostEqualTo(UV3, Tools.Epsilon) && + other.UV4.IsAlmostEqualTo(UV4, Tools.Epsilon) && + other.UV5.IsAlmostEqualTo(UV5, Tools.Epsilon) && + other.UV6.IsAlmostEqualTo(UV6, Tools.Epsilon) && + other.UV7.IsAlmostEqualTo(UV7, Tools.Epsilon) && + other.UV8.IsAlmostEqualTo(UV8, Tools.Epsilon) && other.Weights.IsAlmostEqualTo(Weights, Tools.Epsilon) && other.WeightsExtra.IsAlmostEqualTo(WeightsExtra, Tools.Epsilon) && other.Color.IsAlmostEqualTo(Color, Tools.Epsilon) && diff --git a/SharedProjects/Babylon2GLTF/GLTFExporter.Mesh.cs b/SharedProjects/Babylon2GLTF/GLTFExporter.Mesh.cs index b0236dee..21a98c64 100644 --- a/SharedProjects/Babylon2GLTF/GLTFExporter.Mesh.cs +++ b/SharedProjects/Babylon2GLTF/GLTFExporter.Mesh.cs @@ -35,8 +35,16 @@ private GLTFMesh ExportMesh(BabylonMesh babylonMesh, GLTF gltf, BabylonScene bab logger.RaiseMessage("GLTFExporter.Mesh | Mesh from babylon", 2); // Retreive general data from babylon mesh int nbVertices = meshData.positions.Length / 3; + bool hasUV = meshData.uvs != null && meshData.uvs.Length > 0; bool hasUV2 = meshData.uvs2 != null && meshData.uvs2.Length > 0; + bool hasUV3 = meshData.uvs3 != null && meshData.uvs3.Length > 0; + bool hasUV4 = meshData.uvs4 != null && meshData.uvs4.Length > 0; + bool hasUV5 = meshData.uvs5 != null && meshData.uvs5.Length > 0; + bool hasUV6 = meshData.uvs6 != null && meshData.uvs6.Length > 0; + bool hasUV7 = meshData.uvs7 != null && meshData.uvs7.Length > 0; + bool hasUV8 = meshData.uvs8 != null && meshData.uvs8.Length > 0; + bool hasColor = meshData.colors != null && meshData.colors.Length > 0; bool hasBones = meshData.matricesIndices != null && meshData.matricesIndices.Length > 0; bool hasTangents = meshData.tangents != null && meshData.tangents.Length > 0; @@ -46,8 +54,16 @@ private GLTFMesh ExportMesh(BabylonMesh babylonMesh, GLTF gltf, BabylonScene bab bool hasMetadata = babylonMesh.metadata != null && babylonMesh.metadata.Count > 0; logger.RaiseMessage("GLTFExporter.Mesh | nbVertices=" + nbVertices, 3); + logger.RaiseMessage("GLTFExporter.Mesh | hasUV=" + hasUV, 3); logger.RaiseMessage("GLTFExporter.Mesh | hasUV2=" + hasUV2, 3); + logger.RaiseMessage("GLTFExporter.Mesh | hasUV3=" + hasUV3, 3); + logger.RaiseMessage("GLTFExporter.Mesh | hasUV4=" + hasUV4, 3); + logger.RaiseMessage("GLTFExporter.Mesh | hasUV5=" + hasUV5, 3); + logger.RaiseMessage("GLTFExporter.Mesh | hasUV6=" + hasUV6, 3); + logger.RaiseMessage("GLTFExporter.Mesh | hasUV7=" + hasUV7, 3); + logger.RaiseMessage("GLTFExporter.Mesh | hasUV8=" + hasUV8, 3); + logger.RaiseMessage("GLTFExporter.Mesh | hasColor=" + hasColor, 3); logger.RaiseMessage("GLTFExporter.Mesh | hasBones=" + hasBones, 3); logger.RaiseMessage("GLTFExporter.Mesh | hasBonesExtra=" + hasBonesExtra, 3); @@ -95,6 +111,48 @@ private GLTFMesh ExportMesh(BabylonMesh babylonMesh, GLTF gltf, BabylonScene bab // While for Babylon, it corresponds to the lower left corner of a texture image globalVertex.UV2.Y = 1 - globalVertex.UV2.Y; } + if (hasUV3) + { + globalVertex.UV3 = BabylonVector2.FromArray(meshData.uvs3, indexVertex); + // For glTF, the origin of the UV coordinates (0, 0) corresponds to the upper left corner of a texture image + // While for Babylon, it corresponds to the lower left corner of a texture image + globalVertex.UV3.Y = 1 - globalVertex.UV3.Y; + } + if (hasUV4) + { + globalVertex.UV4 = BabylonVector2.FromArray(meshData.uvs4, indexVertex); + // For glTF, the origin of the UV coordinates (0, 0) corresponds to the upper left corner of a texture image + // While for Babylon, it corresponds to the lower left corner of a texture image + globalVertex.UV4.Y = 1 - globalVertex.UV4.Y; + } + if (hasUV5) + { + globalVertex.UV5 = BabylonVector2.FromArray(meshData.uvs5, indexVertex); + // For glTF, the origin of the UV coordinates (0, 0) corresponds to the upper left corner of a texture image + // While for Babylon, it corresponds to the lower left corner of a texture image + globalVertex.UV5.Y = 1 - globalVertex.UV5.Y; + } + if (hasUV6) + { + globalVertex.UV6 = BabylonVector2.FromArray(meshData.uvs6, indexVertex); + // For glTF, the origin of the UV coordinates (0, 0) corresponds to the upper left corner of a texture image + // While for Babylon, it corresponds to the lower left corner of a texture image + globalVertex.UV6.Y = 1 - globalVertex.UV6.Y; + } + if (hasUV7) + { + globalVertex.UV7 = BabylonVector2.FromArray(meshData.uvs7, indexVertex); + // For glTF, the origin of the UV coordinates (0, 0) corresponds to the upper left corner of a texture image + // While for Babylon, it corresponds to the lower left corner of a texture image + globalVertex.UV7.Y = 1 - globalVertex.UV7.Y; + } + if (hasUV8) + { + globalVertex.UV8 = BabylonVector2.FromArray(meshData.uvs8, indexVertex); + // For glTF, the origin of the UV coordinates (0, 0) corresponds to the upper left corner of a texture image + // While for Babylon, it corresponds to the lower left corner of a texture image + globalVertex.UV8.Y = 1 - globalVertex.UV8.Y; + } if (hasColor) { globalVertex.Color = ArrayExtension.SubArrayFromEntity(meshData.colors, indexVertex, 4); @@ -377,6 +435,108 @@ void clearBoneUnusedIndices(ushort[] indices, float[] weights) accessorUV2s.count = globalVerticesSubMesh.Count; } + // --- UV3 --- + if (hasUV3) + { + var accessorUV3s = GLTFBufferService.Instance.CreateAccessor( + gltf, + GLTFBufferService.Instance.GetBufferViewFloatVec2(gltf, buffer), + "accessorUV3s", + GLTFAccessor.ComponentType.FLOAT, + GLTFAccessor.TypeEnum.VEC2 + ); + meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.TEXCOORD_2.ToString(), accessorUV3s.index); + // Populate accessor + List uvs3 = globalVerticesSubMesh.SelectMany(v => v.UV3.ToArray()).ToList(); + uvs3.ForEach(n => accessorUV3s.bytesList.AddRange(BitConverter.GetBytes(n))); + accessorUV3s.count = globalVerticesSubMesh.Count; + } + + // --- UV4 --- + if (hasUV4) + { + var accessorUV4s = GLTFBufferService.Instance.CreateAccessor( + gltf, + GLTFBufferService.Instance.GetBufferViewFloatVec2(gltf, buffer), + "accessorUV4s", + GLTFAccessor.ComponentType.FLOAT, + GLTFAccessor.TypeEnum.VEC2 + ); + meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.TEXCOORD_3.ToString(), accessorUV4s.index); + // Populate accessor + List uvs4 = globalVerticesSubMesh.SelectMany(v => v.UV4.ToArray()).ToList(); + uvs4.ForEach(n => accessorUV4s.bytesList.AddRange(BitConverter.GetBytes(n))); + accessorUV4s.count = globalVerticesSubMesh.Count; + } + + // --- UV5 --- + if (hasUV5) + { + var accessorUV5s = GLTFBufferService.Instance.CreateAccessor( + gltf, + GLTFBufferService.Instance.GetBufferViewFloatVec2(gltf, buffer), + "accessorUV5s", + GLTFAccessor.ComponentType.FLOAT, + GLTFAccessor.TypeEnum.VEC2 + ); + meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.TEXCOORD_4.ToString(), accessorUV5s.index); + // Populate accessor + List uvs5 = globalVerticesSubMesh.SelectMany(v => v.UV5.ToArray()).ToList(); + uvs5.ForEach(n => accessorUV5s.bytesList.AddRange(BitConverter.GetBytes(n))); + accessorUV5s.count = globalVerticesSubMesh.Count; + } + + // --- UV6 --- + if (hasUV6) + { + var accessorUV6s = GLTFBufferService.Instance.CreateAccessor( + gltf, + GLTFBufferService.Instance.GetBufferViewFloatVec2(gltf, buffer), + "accessorUV6s", + GLTFAccessor.ComponentType.FLOAT, + GLTFAccessor.TypeEnum.VEC2 + ); + meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.TEXCOORD_5.ToString(), accessorUV6s.index); + // Populate accessor + List uvs6 = globalVerticesSubMesh.SelectMany(v => v.UV6.ToArray()).ToList(); + uvs6.ForEach(n => accessorUV6s.bytesList.AddRange(BitConverter.GetBytes(n))); + accessorUV6s.count = globalVerticesSubMesh.Count; + } + + // --- UV7 --- + if (hasUV7) + { + var accessorUV7s = GLTFBufferService.Instance.CreateAccessor( + gltf, + GLTFBufferService.Instance.GetBufferViewFloatVec2(gltf, buffer), + "accessorUV7s", + GLTFAccessor.ComponentType.FLOAT, + GLTFAccessor.TypeEnum.VEC2 + ); + meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.TEXCOORD_6.ToString(), accessorUV7s.index); + // Populate accessor + List uvs7 = globalVerticesSubMesh.SelectMany(v => v.UV7.ToArray()).ToList(); + uvs7.ForEach(n => accessorUV7s.bytesList.AddRange(BitConverter.GetBytes(n))); + accessorUV7s.count = globalVerticesSubMesh.Count; + } + + // --- UV8 --- + if (hasUV8) + { + var accessorUV8s = GLTFBufferService.Instance.CreateAccessor( + gltf, + GLTFBufferService.Instance.GetBufferViewFloatVec2(gltf, buffer), + "accessorUV8s", + GLTFAccessor.ComponentType.FLOAT, + GLTFAccessor.TypeEnum.VEC2 + ); + meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.TEXCOORD_7.ToString(), accessorUV8s.index); + // Populate accessor + List uvs8 = globalVerticesSubMesh.SelectMany(v => v.UV8.ToArray()).ToList(); + uvs8.ForEach(n => accessorUV8s.bytesList.AddRange(BitConverter.GetBytes(n))); + accessorUV8s.count = globalVerticesSubMesh.Count; + } + // --- Bones --- if (hasBones) { diff --git a/SharedProjects/Babylon2GLTF/GLTFGlobalVertex.cs b/SharedProjects/Babylon2GLTF/GLTFGlobalVertex.cs index c1f78007..6f255d83 100644 --- a/SharedProjects/Babylon2GLTF/GLTFGlobalVertex.cs +++ b/SharedProjects/Babylon2GLTF/GLTFGlobalVertex.cs @@ -9,6 +9,12 @@ public class GLTFGlobalVertex public BabylonQuaternion Tangent { get; set; } public BabylonVector2 UV { get; set; } public BabylonVector2 UV2 { get; set; } + public BabylonVector2 UV3 { get; set; } + public BabylonVector2 UV4 { get; set; } + public BabylonVector2 UV5 { get; set; } + public BabylonVector2 UV6 { get; set; } + public BabylonVector2 UV7 { get; set; } + public BabylonVector2 UV8 { get; set; } public float[] Color { get; set; } public ushort[] BonesIndices { get; set; } public ushort[] BonesIndicesExtra { get; set; } diff --git a/SharedProjects/BabylonExport.Entities/BabylonMesh.cs b/SharedProjects/BabylonExport.Entities/BabylonMesh.cs index a66dd6e1..26797cf6 100644 --- a/SharedProjects/BabylonExport.Entities/BabylonMesh.cs +++ b/SharedProjects/BabylonExport.Entities/BabylonMesh.cs @@ -16,6 +16,8 @@ public interface IBabylonMeshData float[] uvs4 { get; set; } float[] uvs5 { get; set; } float[] uvs6 { get; set; } + float[] uvs7 { get; set; } + float[] uvs8 { get; set; } float[] colors { get; set; } int[] matricesIndices { get; set; } int[] matricesIndicesExtra { get; set; } @@ -69,6 +71,12 @@ public class BabylonMesh : BabylonAbstractMesh, IBabylonMeshData [DataMember] public float[] uvs6 { get; set; } + [DataMember] + public float[] uvs7 { get; set; } + + [DataMember] + public float[] uvs8 { get; set; } + [DataMember] public float[] colors { get; set; } diff --git a/SharedProjects/BabylonExport.Entities/BabylonVertexData.cs b/SharedProjects/BabylonExport.Entities/BabylonVertexData.cs index 5b8edd24..c2fc8036 100644 --- a/SharedProjects/BabylonExport.Entities/BabylonVertexData.cs +++ b/SharedProjects/BabylonExport.Entities/BabylonVertexData.cs @@ -42,6 +42,12 @@ public class BabylonVertexData : IBabylonMeshData [DataMember] public float[] uvs6 { get; set; } + + [DataMember] + public float[] uvs7 { get; set; } + + [DataMember] + public float[] uvs8 { get; set; } [DataMember] public float[] colors { get; set; } @@ -71,7 +77,7 @@ public BabylonVertexData(string identifier, IBabylonMeshData data): this(data) public BabylonVertexData(IBabylonMeshData data) { - positions = data.positions; + positions = data.positions; normals = data.normals; tangents = data.tangents; uvs = data.uvs; @@ -80,6 +86,8 @@ public BabylonVertexData(IBabylonMeshData data) uvs4 = data.uvs4; uvs5 = data.uvs5; uvs6 = data.uvs6; + uvs7 = data.uvs7; + uvs8 = data.uvs8; colors = data.colors; matricesIndices = data.matricesIndices; matricesIndicesExtra = data.matricesIndicesExtra; diff --git a/SharedProjects/BabylonExport.Entities/Extensions/BabylonMeshExtensions.cs b/SharedProjects/BabylonExport.Entities/Extensions/BabylonMeshExtensions.cs index a23ee962..6bf79601 100644 --- a/SharedProjects/BabylonExport.Entities/Extensions/BabylonMeshExtensions.cs +++ b/SharedProjects/BabylonExport.Entities/Extensions/BabylonMeshExtensions.cs @@ -43,6 +43,8 @@ public static IBabylonMeshData ClearLocalGeometry(this IBabylonMeshData data) data.uvs4 = null; data.uvs5 = null; data.uvs6 = null; + data.uvs7 = null; + data.uvs8 = null; data.colors = null; data.matricesIndices = null; data.matricesWeights = null; diff --git a/SharedProjects/GltfExport.Entities/GLTFMeshPrimitive.cs b/SharedProjects/GltfExport.Entities/GLTFMeshPrimitive.cs index 43c78473..7b71229c 100644 --- a/SharedProjects/GltfExport.Entities/GLTFMeshPrimitive.cs +++ b/SharedProjects/GltfExport.Entities/GLTFMeshPrimitive.cs @@ -24,6 +24,12 @@ public enum Attribute TANGENT, TEXCOORD_0, TEXCOORD_1, + TEXCOORD_2, + TEXCOORD_3, + TEXCOORD_4, + TEXCOORD_5, + TEXCOORD_6, + TEXCOORD_7, COLOR_0, JOINTS_0, JOINTS_1,