Skip to content

Commit 212fa68

Browse files
aidinabediAdamMitchell-ms
authored andcommitted
Add support for points and lines (#456)
* rename some instances of the word triangles to indices to avoid future invalid assumptions * simplify and optimize triangle face flipping * add support for points, lines and line-strip * if mesh is not triangles, then don't recalculate normals to avoid unnecessary log spam.
1 parent 5bd548c commit 212fa68

File tree

5 files changed

+57
-48
lines changed

5 files changed

+57
-48
lines changed

GLTFSerialization/GLTFSerialization/Schema/MeshPrimitive.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,17 +98,15 @@ public MeshPrimitive(MeshPrimitive meshPrimitive, GLTFRoot gltfRoot) : base(mesh
9898
}
9999
}
100100

101-
public static int[] GenerateTriangles(int vertCount)
101+
public static int[] GenerateIndices(int vertCount)
102102
{
103-
var arr = new int[vertCount];
104-
for (var i = 0; i < vertCount; i+=3)
103+
var indices = new int[vertCount];
104+
for (var i = 0; i < vertCount; i++)
105105
{
106-
arr[i] = i + 2;
107-
arr[i + 1] = i + 1;
108-
arr[i + 2] = i;
106+
indices[i] = i;
109107
}
110108

111-
return arr;
109+
return indices;
112110
}
113111

114112
// Taken from: http://answers.unity3d.com/comments/190515/view.html

UnityGLTF/Assets/UnityGLTF/Scripts/Editor/GLTFImporter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public override void OnImportAsset(AssetImportContext ctx)
9090
{
9191
mesh.normals = new Vector3[0];
9292
}
93-
if (_importNormals == GLTFImporterNormals.Calculate)
93+
if (_importNormals == GLTFImporterNormals.Calculate && mesh.GetTopology(0) == MeshTopology.Triangles)
9494
{
9595
mesh.RecalculateNormals();
9696
}

UnityGLTF/Assets/UnityGLTF/Scripts/Extensions/SchemaExtensions.cs

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -439,39 +439,20 @@ public static Vector4[] ConvertVector4CoordinateSpaceAndCopy(Vector4[] array, GL
439439
}
440440

441441
return returnArray;
442-
}
443-
442+
}
443+
444444
/// <summary>
445445
/// Rewinds the indicies into Unity coordinate space from glTF space
446446
/// </summary>
447447
/// <param name="attributeAccessor">The attribute accessor to modify</param>
448-
public static void FlipFaces(ref AttributeAccessor attributeAccessor)
449-
{
450-
for (int i = 0; i < attributeAccessor.AccessorContent.AsTriangles.Length; i += 3)
451-
{
452-
uint temp = attributeAccessor.AccessorContent.AsUInts[i];
453-
attributeAccessor.AccessorContent.AsUInts[i] = attributeAccessor.AccessorContent.AsUInts[i + 2];
454-
attributeAccessor.AccessorContent.AsUInts[i + 2] = temp;
455-
}
456-
}
457-
458-
/// <summary>
459-
/// Rewinds the indices from glTF space to Unity space
460-
/// </summary>
461-
/// <param name="triangles">The indices to copy and modify</param>
462-
/// <returns>Indices in glTF space that are copied</returns>
463-
public static int[] FlipFacesAndCopy(int[] triangles)
448+
public static void FlipTriangleFaces(int[] indices)
464449
{
465-
int[] returnArr = new int[triangles.Length];
466-
for (int i = 0; i < triangles.Length; i += 3)
450+
for (int i = 0; i < indices.Length; i += 3)
467451
{
468-
int temp = triangles[i];
469-
returnArr[i] = triangles[i + 2];
470-
returnArr[i + 1] = triangles[i + 1];
471-
returnArr[i + 2] = temp;
452+
int temp = indices[i];
453+
indices[i] = indices[i + 2];
454+
indices[i + 2] = temp;
472455
}
473-
474-
return returnArr;
475456
}
476457

477458
public static Matrix4x4 ToUnityMatrix4x4(this GLTF.Math.Matrix4x4 matrix)

UnityGLTF/Assets/UnityGLTF/Scripts/GLTFSceneExporter.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -776,8 +776,12 @@ private MeshPrimitive[] ExportPrimitive(GameObject gameObject, GLTFMesh mesh)
776776
{
777777
var primitive = new MeshPrimitive();
778778

779-
var triangles = meshObj.GetTriangles(submesh);
780-
primitive.Indices = ExportAccessor(SchemaExtensions.FlipFacesAndCopy(triangles), true);
779+
var topology = meshObj.GetTopology(submesh);
780+
var indices = meshObj.GetIndices(submesh);
781+
if (topology == MeshTopology.Triangles) SchemaExtensions.FlipTriangleFaces(indices);
782+
783+
primitive.Mode = GetDrawMode(topology);
784+
primitive.Indices = ExportAccessor(indices, true);
781785

782786
primitive.Attributes = new Dictionary<string, AccessorId>();
783787
primitive.Attributes.Add(SemanticProperties.POSITION, aPosition);
@@ -1964,6 +1968,18 @@ public SamplerId GetSamplerId(GLTFRoot root, Texture textureObj)
19641968

19651969
return null;
19661970
}
1967-
1971+
1972+
protected static DrawMode GetDrawMode(MeshTopology topology)
1973+
{
1974+
switch (topology)
1975+
{
1976+
case MeshTopology.Points: return DrawMode.Points;
1977+
case MeshTopology.Lines: return DrawMode.Lines;
1978+
case MeshTopology.LineStrip: return DrawMode.LineStrip;
1979+
case MeshTopology.Triangles: return DrawMode.Triangles;
1980+
}
1981+
1982+
throw new Exception("glTF does not support Unity mesh topology: " + topology);
1983+
}
19681984
}
19691985
}

UnityGLTF/Assets/UnityGLTF/Scripts/GLTFSceneImporter.cs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ public class UnityMeshData
4646
public Vector2[] Uv3;
4747
public Vector2[] Uv4;
4848
public Color[] Colors;
49-
public int[] Triangles;
49+
public MeshTopology Topology;
50+
public int[] Indices;
5051
public Vector4[] Tangents;
5152
public BoneWeight[] BoneWeights;
5253
}
@@ -902,11 +903,6 @@ protected void TransformAttributes(ref Dictionary<string, AttributeAccessor> att
902903
AttributeAccessor attributeAccessor = attributeAccessors[SemanticProperties.POSITION];
903904
SchemaExtensions.ConvertVector3CoordinateSpace(ref attributeAccessor, SchemaExtensions.CoordinateSpaceConversionScale);
904905
}
905-
if (attributeAccessors.ContainsKey(SemanticProperties.INDICES))
906-
{
907-
AttributeAccessor attributeAccessor = attributeAccessors[SemanticProperties.INDICES];
908-
SchemaExtensions.FlipFaces(ref attributeAccessor);
909-
}
910906
if (attributeAccessors.ContainsKey(SemanticProperties.NORMAL))
911907
{
912908
AttributeAccessor attributeAccessor = attributeAccessors[SemanticProperties.NORMAL];
@@ -1708,6 +1704,13 @@ protected UnityMeshData ConvertAccessorsToUnityTypes(MeshConstructionData meshCo
17081704

17091705
int vertexCount = (int)primitive.Attributes[SemanticProperties.POSITION].Value.Count;
17101706

1707+
var indices = primitive.Indices != null
1708+
? meshAttributes[SemanticProperties.INDICES].AccessorContent.AsUInts.ToIntArrayRaw()
1709+
: MeshPrimitive.GenerateIndices(vertexCount);
1710+
1711+
var topology = GetTopology(meshConstructionData.Primitive.Mode);
1712+
if (topology == MeshTopology.Triangles) SchemaExtensions.FlipTriangleFaces(indices);
1713+
17111714
return new UnityMeshData
17121715
{
17131716
Vertices = primitive.Attributes.ContainsKey(SemanticProperties.POSITION)
@@ -1738,9 +1741,8 @@ protected UnityMeshData ConvertAccessorsToUnityTypes(MeshConstructionData meshCo
17381741
? meshAttributes[SemanticProperties.Color(0)].AccessorContent.AsColors.ToUnityColorRaw()
17391742
: null,
17401743

1741-
Triangles = primitive.Indices != null
1742-
? meshAttributes[SemanticProperties.INDICES].AccessorContent.AsUInts.ToIntArrayRaw()
1743-
: MeshPrimitive.GenerateTriangles(vertexCount),
1744+
Topology = topology,
1745+
Indices = indices,
17441746

17451747
Tangents = primitive.Attributes.ContainsKey(SemanticProperties.TANGENT)
17461748
? meshAttributes[SemanticProperties.TANGENT].AccessorContent.AsTangents.ToUnityVector4Raw()
@@ -1857,14 +1859,14 @@ protected async Task ConstructUnityMesh(MeshConstructionData meshConstructionDat
18571859
await YieldOnTimeoutAndThrowOnLowMemory();
18581860
mesh.colors = unityMeshData.Colors;
18591861
await YieldOnTimeoutAndThrowOnLowMemory();
1860-
mesh.triangles = unityMeshData.Triangles;
1862+
mesh.SetIndices(unityMeshData.Indices, unityMeshData.Topology, 0);
18611863
await YieldOnTimeoutAndThrowOnLowMemory();
18621864
mesh.tangents = unityMeshData.Tangents;
18631865
await YieldOnTimeoutAndThrowOnLowMemory();
18641866
mesh.boneWeights = unityMeshData.BoneWeights;
18651867
await YieldOnTimeoutAndThrowOnLowMemory();
18661868

1867-
if (!hasNormals)
1869+
if (!hasNormals && unityMeshData.Topology == MeshTopology.Triangles)
18681870
{
18691871
mesh.RecalculateNormals();
18701872
}
@@ -2311,6 +2313,18 @@ protected static string AbsoluteFilePath(string gltfPath)
23112313
return partialPath;
23122314
}
23132315

2316+
protected static MeshTopology GetTopology(DrawMode mode)
2317+
{
2318+
switch (mode) {
2319+
case DrawMode.Points: return MeshTopology.Points;
2320+
case DrawMode.Lines: return MeshTopology.Lines;
2321+
case DrawMode.LineStrip: return MeshTopology.LineStrip;
2322+
case DrawMode.Triangles: return MeshTopology.Triangles;
2323+
}
2324+
2325+
throw new Exception("Unity does not support glTF draw mode: " + mode);
2326+
}
2327+
23142328
/// <summary>
23152329
/// Cleans up any undisposed streams after loading a scene or a node.
23162330
/// </summary>

0 commit comments

Comments
 (0)