Skip to content

Commit

Permalink
Add support for points and lines (#456)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
aidinabedi authored and AdamMitchell-ms committed Jun 24, 2019
1 parent 5bd548c commit 212fa68
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 48 deletions.
12 changes: 5 additions & 7 deletions GLTFSerialization/GLTFSerialization/Schema/MeshPrimitive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,15 @@ public MeshPrimitive(MeshPrimitive meshPrimitive, GLTFRoot gltfRoot) : base(mesh
}
}

public static int[] GenerateTriangles(int vertCount)
public static int[] GenerateIndices(int vertCount)
{
var arr = new int[vertCount];
for (var i = 0; i < vertCount; i+=3)
var indices = new int[vertCount];
for (var i = 0; i < vertCount; i++)
{
arr[i] = i + 2;
arr[i + 1] = i + 1;
arr[i + 2] = i;
indices[i] = i;
}

return arr;
return indices;
}

// Taken from: http://answers.unity3d.com/comments/190515/view.html
Expand Down
2 changes: 1 addition & 1 deletion UnityGLTF/Assets/UnityGLTF/Scripts/Editor/GLTFImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public override void OnImportAsset(AssetImportContext ctx)
{
mesh.normals = new Vector3[0];
}
if (_importNormals == GLTFImporterNormals.Calculate)
if (_importNormals == GLTFImporterNormals.Calculate && mesh.GetTopology(0) == MeshTopology.Triangles)
{
mesh.RecalculateNormals();
}
Expand Down
33 changes: 7 additions & 26 deletions UnityGLTF/Assets/UnityGLTF/Scripts/Extensions/SchemaExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -439,39 +439,20 @@ public static Vector4[] ConvertVector4CoordinateSpaceAndCopy(Vector4[] array, GL
}

return returnArray;
}

}

/// <summary>
/// Rewinds the indicies into Unity coordinate space from glTF space
/// </summary>
/// <param name="attributeAccessor">The attribute accessor to modify</param>
public static void FlipFaces(ref AttributeAccessor attributeAccessor)
{
for (int i = 0; i < attributeAccessor.AccessorContent.AsTriangles.Length; i += 3)
{
uint temp = attributeAccessor.AccessorContent.AsUInts[i];
attributeAccessor.AccessorContent.AsUInts[i] = attributeAccessor.AccessorContent.AsUInts[i + 2];
attributeAccessor.AccessorContent.AsUInts[i + 2] = temp;
}
}

/// <summary>
/// Rewinds the indices from glTF space to Unity space
/// </summary>
/// <param name="triangles">The indices to copy and modify</param>
/// <returns>Indices in glTF space that are copied</returns>
public static int[] FlipFacesAndCopy(int[] triangles)
public static void FlipTriangleFaces(int[] indices)
{
int[] returnArr = new int[triangles.Length];
for (int i = 0; i < triangles.Length; i += 3)
for (int i = 0; i < indices.Length; i += 3)
{
int temp = triangles[i];
returnArr[i] = triangles[i + 2];
returnArr[i + 1] = triangles[i + 1];
returnArr[i + 2] = temp;
int temp = indices[i];
indices[i] = indices[i + 2];
indices[i + 2] = temp;
}

return returnArr;
}

public static Matrix4x4 ToUnityMatrix4x4(this GLTF.Math.Matrix4x4 matrix)
Expand Down
22 changes: 19 additions & 3 deletions UnityGLTF/Assets/UnityGLTF/Scripts/GLTFSceneExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -776,8 +776,12 @@ private MeshPrimitive[] ExportPrimitive(GameObject gameObject, GLTFMesh mesh)
{
var primitive = new MeshPrimitive();

var triangles = meshObj.GetTriangles(submesh);
primitive.Indices = ExportAccessor(SchemaExtensions.FlipFacesAndCopy(triangles), true);
var topology = meshObj.GetTopology(submesh);
var indices = meshObj.GetIndices(submesh);
if (topology == MeshTopology.Triangles) SchemaExtensions.FlipTriangleFaces(indices);

primitive.Mode = GetDrawMode(topology);
primitive.Indices = ExportAccessor(indices, true);

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

return null;
}


protected static DrawMode GetDrawMode(MeshTopology topology)
{
switch (topology)
{
case MeshTopology.Points: return DrawMode.Points;
case MeshTopology.Lines: return DrawMode.Lines;
case MeshTopology.LineStrip: return DrawMode.LineStrip;
case MeshTopology.Triangles: return DrawMode.Triangles;
}

throw new Exception("glTF does not support Unity mesh topology: " + topology);
}
}
}
36 changes: 25 additions & 11 deletions UnityGLTF/Assets/UnityGLTF/Scripts/GLTFSceneImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public class UnityMeshData
public Vector2[] Uv3;
public Vector2[] Uv4;
public Color[] Colors;
public int[] Triangles;
public MeshTopology Topology;
public int[] Indices;
public Vector4[] Tangents;
public BoneWeight[] BoneWeights;
}
Expand Down Expand Up @@ -902,11 +903,6 @@ protected void TransformAttributes(ref Dictionary<string, AttributeAccessor> att
AttributeAccessor attributeAccessor = attributeAccessors[SemanticProperties.POSITION];
SchemaExtensions.ConvertVector3CoordinateSpace(ref attributeAccessor, SchemaExtensions.CoordinateSpaceConversionScale);
}
if (attributeAccessors.ContainsKey(SemanticProperties.INDICES))
{
AttributeAccessor attributeAccessor = attributeAccessors[SemanticProperties.INDICES];
SchemaExtensions.FlipFaces(ref attributeAccessor);
}
if (attributeAccessors.ContainsKey(SemanticProperties.NORMAL))
{
AttributeAccessor attributeAccessor = attributeAccessors[SemanticProperties.NORMAL];
Expand Down Expand Up @@ -1708,6 +1704,13 @@ protected UnityMeshData ConvertAccessorsToUnityTypes(MeshConstructionData meshCo

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

var indices = primitive.Indices != null
? meshAttributes[SemanticProperties.INDICES].AccessorContent.AsUInts.ToIntArrayRaw()
: MeshPrimitive.GenerateIndices(vertexCount);

var topology = GetTopology(meshConstructionData.Primitive.Mode);
if (topology == MeshTopology.Triangles) SchemaExtensions.FlipTriangleFaces(indices);

return new UnityMeshData
{
Vertices = primitive.Attributes.ContainsKey(SemanticProperties.POSITION)
Expand Down Expand Up @@ -1738,9 +1741,8 @@ protected UnityMeshData ConvertAccessorsToUnityTypes(MeshConstructionData meshCo
? meshAttributes[SemanticProperties.Color(0)].AccessorContent.AsColors.ToUnityColorRaw()
: null,

Triangles = primitive.Indices != null
? meshAttributes[SemanticProperties.INDICES].AccessorContent.AsUInts.ToIntArrayRaw()
: MeshPrimitive.GenerateTriangles(vertexCount),
Topology = topology,
Indices = indices,

Tangents = primitive.Attributes.ContainsKey(SemanticProperties.TANGENT)
? meshAttributes[SemanticProperties.TANGENT].AccessorContent.AsTangents.ToUnityVector4Raw()
Expand Down Expand Up @@ -1857,14 +1859,14 @@ protected async Task ConstructUnityMesh(MeshConstructionData meshConstructionDat
await YieldOnTimeoutAndThrowOnLowMemory();
mesh.colors = unityMeshData.Colors;
await YieldOnTimeoutAndThrowOnLowMemory();
mesh.triangles = unityMeshData.Triangles;
mesh.SetIndices(unityMeshData.Indices, unityMeshData.Topology, 0);
await YieldOnTimeoutAndThrowOnLowMemory();
mesh.tangents = unityMeshData.Tangents;
await YieldOnTimeoutAndThrowOnLowMemory();
mesh.boneWeights = unityMeshData.BoneWeights;
await YieldOnTimeoutAndThrowOnLowMemory();

if (!hasNormals)
if (!hasNormals && unityMeshData.Topology == MeshTopology.Triangles)
{
mesh.RecalculateNormals();
}
Expand Down Expand Up @@ -2311,6 +2313,18 @@ protected static string AbsoluteFilePath(string gltfPath)
return partialPath;
}

protected static MeshTopology GetTopology(DrawMode mode)
{
switch (mode) {
case DrawMode.Points: return MeshTopology.Points;
case DrawMode.Lines: return MeshTopology.Lines;
case DrawMode.LineStrip: return MeshTopology.LineStrip;
case DrawMode.Triangles: return MeshTopology.Triangles;
}

throw new Exception("Unity does not support glTF draw mode: " + mode);
}

/// <summary>
/// Cleans up any undisposed streams after loading a scene or a node.
/// </summary>
Expand Down

0 comments on commit 212fa68

Please sign in to comment.