Browse Source

small API fixes

Vicente Penades 6 years ago
parent
commit
b71a2ba2a5

+ 1 - 1
src/SharpGLTF.Toolkit/Geometry/MeshBuilder.cs

@@ -79,7 +79,7 @@ namespace SharpGLTF.Geometry
 
         public IReadOnlyCollection<PrimitiveBuilder<TMaterial, TvG, TvM, TvS>> Primitives => _Primitives.Values;
 
-        IReadOnlyCollection<IPrimitive<TMaterial>> IMeshBuilder<TMaterial>.Primitives => _Primitives.Values;
+        IReadOnlyCollection<IPrimitiveReader<TMaterial>> IMeshBuilder<TMaterial>.Primitives => _Primitives.Values;
 
         #endregion
 

+ 1 - 1
src/SharpGLTF.Toolkit/Geometry/MeshBuilderToolkit.cs

@@ -14,7 +14,7 @@ namespace SharpGLTF.Geometry
 
         IEnumerable<TMaterial> Materials { get; }
 
-        IReadOnlyCollection<IPrimitive<TMaterial>> Primitives { get; }
+        IReadOnlyCollection<IPrimitiveReader<TMaterial>> Primitives { get; }
 
         IPrimitiveBuilder UsePrimitive(TMaterial material, int primitiveVertexCount = 3);
 

+ 117 - 39
src/SharpGLTF.Toolkit/Geometry/PrimitiveBuilder.cs

@@ -6,10 +6,11 @@ using System.Numerics;
 
 using SharpGLTF.Collections;
 using SharpGLTF.Geometry.VertexTypes;
+using System.Collections;
 
 namespace SharpGLTF.Geometry
 {
-    public interface IPrimitive<TMaterial>
+    public interface IPrimitiveReader<TMaterial>
     {
         /// <summary>
         /// Gets the current <typeparamref name="TMaterial"/> instance used by this primitive.
@@ -21,11 +22,6 @@ namespace SharpGLTF.Geometry
         /// </summary>
         int VerticesPerPrimitive { get; }
 
-        /// <summary>
-        /// Gets the total number of vertices
-        /// </summary>
-        int VertexCount { get; }
-
         /// <summary>
         /// Gets the list of <see cref="IVertexBuilder"/> vertices.
         /// </summary>
@@ -39,17 +35,17 @@ namespace SharpGLTF.Geometry
         /// <summary>
         /// Gets the indices of all points, given that <see cref="VerticesPerPrimitive"/> is 1.
         /// </summary>
-        IEnumerable<int> Points { get; }
+        IReadOnlyList<int> Points { get; }
 
         /// <summary>
         /// Gets the indices of all lines, given that <see cref="VerticesPerPrimitive"/> is 2.
         /// </summary>
-        IEnumerable<(int, int)> Lines { get; }
+        IReadOnlyList<(int, int)> Lines { get; }
 
         /// <summary>
         /// Gets the indices of all triangles, given that <see cref="VerticesPerPrimitive"/> is 3.
         /// </summary>
-        IEnumerable<(int, int, int)> Triangles { get; }
+        IReadOnlyList<(int, int, int)> Triangles { get; }
     }
 
     public interface IPrimitiveBuilder
@@ -97,7 +93,7 @@ namespace SharpGLTF.Geometry
     /// <see cref="VertexJoints16x8"/>.
     /// </typeparam>
     [System.Diagnostics.DebuggerDisplay("Primitive {_Material}")]
-    public class PrimitiveBuilder<TMaterial, TvG, TvM, TvS> : IPrimitiveBuilder, IPrimitive<TMaterial>
+    public class PrimitiveBuilder<TMaterial, TvG, TvM, TvS> : IPrimitiveBuilder, IPrimitiveReader<TMaterial>
         where TvG : struct, IVertexGeometry
         where TvM : struct, IVertexMaterial
         where TvS : struct, IVertexSkinning
@@ -109,6 +105,9 @@ namespace SharpGLTF.Geometry
             this._Mesh = mesh;
             this._Material = material;
             this._PrimitiveVertexCount = primitiveVertexCount;
+
+            if (this._PrimitiveVertexCount == 2) _LinesIndices = new LineListWrapper(_Indices);
+            if (this._PrimitiveVertexCount == 3) _TrianglesIndices = new TriangleListWrapper(_Indices);
         }
 
         #endregion
@@ -121,20 +120,11 @@ namespace SharpGLTF.Geometry
 
         private readonly int _PrimitiveVertexCount;
 
-        class PrimitiveVertexList : VertexList<VertexBuilder<TvG, TvM, TvS>>, IReadOnlyList<IVertexBuilder>
-        {
-            #pragma warning disable SA1100 // Do not prefix calls with base unless local implementation exists
-            IVertexBuilder IReadOnlyList<IVertexBuilder>.this[int index] => base[index];
-            #pragma warning restore SA1100 // Do not prefix calls with base unless local implementation exists
+        private readonly VertexListWrapper _Vertices = new VertexListWrapper();
 
-            IEnumerator<IVertexBuilder> IEnumerable<IVertexBuilder>.GetEnumerator()
-            {
-                foreach (var item in this) yield return item;
-            }
-        }
-
-        private readonly PrimitiveVertexList _Vertices = new PrimitiveVertexList();
         private readonly List<int> _Indices = new List<int>();
+        private readonly LineListWrapper _LinesIndices;
+        private readonly TriangleListWrapper _TrianglesIndices;
 
         #endregion
 
@@ -152,19 +142,17 @@ namespace SharpGLTF.Geometry
         /// </summary>
         public int VerticesPerPrimitive => _PrimitiveVertexCount;
 
-        public int VertexCount => Vertices.Count;
-
         public IReadOnlyList<VertexBuilder<TvG, TvM, TvS>> Vertices => _Vertices;
 
-        IReadOnlyList<IVertexBuilder> IPrimitive<TMaterial>.Vertices => _Vertices;
+        IReadOnlyList<IVertexBuilder> IPrimitiveReader<TMaterial>.Vertices => _Vertices;
 
         public IReadOnlyList<int> Indices => _Indices;
 
-        public IEnumerable<int> Points => _GetPointIndices();
+        public IReadOnlyList<int> Points => _GetPointIndices();
 
-        public IEnumerable<(int, int)> Lines => _GetLineIndices();
+        public IReadOnlyList<(int, int)> Lines => _GetLineIndices();
 
-        public IEnumerable<(int, int, int)> Triangles => _GetTriangleIndices();
+        public IReadOnlyList<(int, int, int)> Triangles => _GetTriangleIndices();
 
         public Type VertexType => typeof(VertexBuilder<TvG, TvM, TvS>);
 
@@ -382,25 +370,21 @@ namespace SharpGLTF.Geometry
             }
         }
 
-        private IEnumerable<int> _GetPointIndices()
+        private IReadOnlyList<int> _GetPointIndices()
         {
-            if (_PrimitiveVertexCount != 1) return Enumerable.Empty<int>();
+            if (_PrimitiveVertexCount != 1) return Array.Empty<int>();
 
-            return Enumerable.Range(0, _Vertices.Count);
+            return new PointListWrapper(_Vertices);
         }
 
-        private IEnumerable<(int, int)> _GetLineIndices()
+        private IReadOnlyList<(int, int)> _GetLineIndices()
         {
-            if (_PrimitiveVertexCount != 2) return Enumerable.Empty<(int, int)>();
-
-            return Schema2.PrimitiveType.LINES.GetLinesIndices(_Indices.Select(item => (uint)item));
+            return _LinesIndices ?? (IReadOnlyList<(int, int)>)Array.Empty<(int, int)>();
         }
 
-        private IEnumerable<(int, int, int)> _GetTriangleIndices()
+        private IReadOnlyList<(int, int, int)> _GetTriangleIndices()
         {
-            if (_PrimitiveVertexCount != 3) return Enumerable.Empty<(int, int, int)>();
-
-            return Schema2.PrimitiveType.TRIANGLES.GetTrianglesIndices(_Indices.Select(item => (uint)item));
+            return _TrianglesIndices ?? (IReadOnlyList<(int, int, int)>)Array.Empty<(int, int, int)>();
         }
 
         public void TransformVertices(Func<VertexBuilder<TvG, TvM, TvS>, VertexBuilder<TvG, TvM, TvS>> transformFunc)
@@ -409,5 +393,99 @@ namespace SharpGLTF.Geometry
         }
 
         #endregion
+
+        #region helper types
+
+        sealed class VertexListWrapper : VertexList<VertexBuilder<TvG, TvM, TvS>>, IReadOnlyList<IVertexBuilder>
+        {
+            #pragma warning disable SA1100 // Do not prefix calls with base unless local implementation exists
+            IVertexBuilder IReadOnlyList<IVertexBuilder>.this[int index] => base[index];
+            #pragma warning restore SA1100 // Do not prefix calls with base unless local implementation exists
+
+            IEnumerator<IVertexBuilder> IEnumerable<IVertexBuilder>.GetEnumerator()
+            {
+                foreach (var item in this) yield return item;
+            }
+        }
+
+        struct PointListWrapper : IReadOnlyList<int>
+        {
+            public PointListWrapper(IReadOnlyList<IVertexBuilder> vertices)
+            {
+                _Vertices = vertices;
+            }
+
+            private readonly IReadOnlyList<IVertexBuilder> _Vertices;
+
+            public int this[int index] => index;
+
+            public int Count => _Vertices.Count;
+
+            public IEnumerator<int> GetEnumerator() { return Enumerable.Range(0, _Vertices.Count).GetEnumerator(); }
+
+            IEnumerator IEnumerable.GetEnumerator() { return Enumerable.Range(0, _Vertices.Count).GetEnumerator(); }
+        }
+
+        sealed class LineListWrapper : IReadOnlyList<(int, int)>
+        {
+            public LineListWrapper(List<int> source) { _Indices = source; }
+
+            private readonly IList<int> _Indices;
+
+            public (int, int) this[int index]
+            {
+                get
+                {
+                    index *= 2;
+                    return (_Indices[index + 0], _Indices[index + 1]);
+                }
+            }
+
+            public int Count => _Indices.Count / 2;
+
+            public IEnumerator<(int, int)> GetEnumerator()
+            {
+                var c = this.Count;
+                for (int i = 0; i < c; ++i) yield return this[i];
+            }
+
+            IEnumerator IEnumerable.GetEnumerator()
+            {
+                var c = this.Count;
+                for (int i = 0; i < c; ++i) yield return this[i];
+            }
+        }
+
+        sealed class TriangleListWrapper : IReadOnlyList<(int, int, int)>
+        {
+            public TriangleListWrapper(List<int> source) { _Indices = source; }
+
+            private readonly List<int> _Indices;
+
+            public (int, int, int) this[int index]
+            {
+                get
+                {
+                    index *= 3;
+                    return (_Indices[index + 0], _Indices[index + 1], _Indices[index + 2]);
+                }
+            }
+
+            public int Count => _Indices.Count / 3;
+
+            public IEnumerator<(int, int, int)> GetEnumerator()
+            {
+                var c = this.Count;
+                for (int i = 0; i < c; ++i) yield return this[i];
+            }
+
+            IEnumerator IEnumerable.GetEnumerator()
+            {
+                var c = this.Count;
+                for (int i = 0; i < c; ++i) yield return this[i];
+            }
+        }
+
+        #endregion
     }
 }

+ 11 - 3
src/SharpGLTF.Toolkit/Scenes/SceneBuilder.Schema2.cs

@@ -175,6 +175,8 @@ namespace SharpGLTF.Scenes
         {
             if (srcScene == null) return null;
 
+            // Process armatures
+
             var dstNodes = new Dictionary<Node, NodeBuilder>();
 
             foreach (var srcArmature in srcScene.VisualChildren)
@@ -187,12 +189,18 @@ namespace SharpGLTF.Scenes
 
             var dstScene = new SceneBuilder();
 
-            // process meshes
-            var srcMeshInstances = Node.Flatten(srcScene).Where(item => item.Mesh != null).ToList();
+            // process mesh instances
+            var srcMeshInstances = Node.Flatten(srcScene)
+                .Where(item => item.Mesh != null)
+                .ToList();
+
             _AddMeshInstances(dstScene, dstNodes, srcMeshInstances);
 
             // process cameras
-            var srcCameraInstances = Node.Flatten(srcScene).Where(item => item.Camera != null).ToList();
+            var srcCameraInstances = Node.Flatten(srcScene)
+                .Where(item => item.Camera != null)
+                .ToList();
+
             _AddCameraInstances(dstScene, dstNodes, srcCameraInstances);
 
             return dstScene;