Browse Source

Api review and more docs

Vicente Penades 6 years ago
parent
commit
46e7f006fd

+ 2 - 0
SharpGLTF.ruleset

@@ -29,7 +29,9 @@
     <Rule Id="SA1512" Action="None" />
     <Rule Id="SA1516" Action="None" />	
     <Rule Id="SA1515" Action="None" />
+    <Rule Id="SA1600" Action="None" />
     <Rule Id="SA1601" Action="None" />
+    <Rule Id="SA1602" Action="None" />
     <Rule Id="SA1625" Action="None" />
     <Rule Id="SA1629" Action="None" />
     <Rule Id="SA1633" Action="None" />

+ 2 - 2
build/SharpGLTF.CodeGen/SharpGLTF.CodeGen.csproj

@@ -8,8 +8,8 @@
 
   <ItemGroup>
     <PackageReference Include="LibGit2Sharp" Version="0.26.0" />
-    <PackageReference Include="NJsonSchema.CodeGeneration" Version="9.13.23" />
-    <PackageReference Include="NJsonSchema.CodeGeneration.CSharp" Version="9.13.23" />
+    <PackageReference Include="NJsonSchema.CodeGeneration" Version="9.13.26" />
+    <PackageReference Include="NJsonSchema.CodeGeneration.CSharp" Version="9.13.26" />
   </ItemGroup>
 
 </Project>

+ 56 - 0
src/SharpGLTF.Toolkit/Geometry/PackedMeshBuilder.cs

@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SharpGLTF.Geometry
+{
+    using Schema2;
+
+    class PackedMeshBuilder<TMaterial>
+    {
+        public PackedMeshBuilder(string name) { _MeshName = name; }
+
+        private readonly string _MeshName;
+        private readonly List<PackedPrimitiveBuilder<TMaterial>> _Primitives = new List<PackedPrimitiveBuilder<TMaterial>>();
+
+        public void AddPrimitive(TMaterial material, Memory.MemoryAccessor[] vrtAccessors, Memory.MemoryAccessor idxAccessor)
+        {
+            var p = new PackedPrimitiveBuilder<TMaterial>(material, vrtAccessors, idxAccessor);
+            _Primitives.Add(p);
+        }
+
+        public Mesh CreateSchema2Mesh(ModelRoot root, Func<TMaterial, Material> materialEvaluator)
+        {
+            var dstMesh = root.CreateMesh(_MeshName);
+
+            foreach (var p in _Primitives)
+            {
+                p.CopyToMesh(dstMesh, materialEvaluator);
+            }
+
+            return dstMesh;
+        }
+    }
+
+    class PackedPrimitiveBuilder<TMaterial>
+    {
+        internal PackedPrimitiveBuilder(TMaterial material, Memory.MemoryAccessor[] vrtAccessors, Memory.MemoryAccessor idxAccessor)
+        {
+            _Material = material;
+            _VertexAccessors = vrtAccessors;
+            _IndexAccessors = idxAccessor;
+        }
+
+        private readonly TMaterial _Material;
+        private readonly Memory.MemoryAccessor[] _VertexAccessors;
+        private readonly Memory.MemoryAccessor _IndexAccessors;
+
+        internal void CopyToMesh(Mesh dstMesh, Func<TMaterial, Material> materialEvaluator)
+        {
+            dstMesh.CreatePrimitive()
+                        .WithMaterial(materialEvaluator(_Material))
+                        .WithVertexAccessors(_VertexAccessors)
+                        .WithIndicesAccessor(PrimitiveType.TRIANGLES, _IndexAccessors);
+        }
+    }
+}

+ 23 - 26
src/SharpGLTF.Toolkit/Geometry/SkinnedMeshBuilder.cs

@@ -7,13 +7,13 @@ namespace SharpGLTF.Geometry
 {
     using Collections;
 
-    public class SkinnedPrimitiveBuilder<TMaterial, TVertex, TSkin>
+    public class SkinnedPrimitiveBuilder<TMaterial, TVertex, TJoints>
         where TVertex : struct, VertexTypes.IVertex
-        where TSkin : struct, VertexTypes.IVertexJoints
+        where TJoints : struct, VertexTypes.IJoints
     {
         #region lifecycle
 
-        internal SkinnedPrimitiveBuilder(SkinnedMeshBuilder<TMaterial, TVertex, TSkin> mesh, TMaterial material)
+        internal SkinnedPrimitiveBuilder(SkinnedMeshBuilder<TMaterial, TVertex, TJoints> mesh, TMaterial material)
         {
             this._Mesh = mesh;
             this._Material = material;
@@ -23,22 +23,22 @@ namespace SharpGLTF.Geometry
 
         #region data
 
-        private readonly SkinnedMeshBuilder<TMaterial, TVertex, TSkin> _Mesh;
+        private readonly SkinnedMeshBuilder<TMaterial, TVertex, TJoints> _Mesh;
 
         private readonly TMaterial _Material;
 
-        private readonly VertexColumn<(TVertex, TSkin)> _Vertices = new VertexColumn<(TVertex, TSkin)>();
+        private readonly VertexColumn<(TVertex, TJoints)> _Vertices = new VertexColumn<(TVertex, TJoints)>();
         private readonly List<int> _Indices = new List<int>();
 
         #endregion
 
         #region properties
 
-        public SkinnedMeshBuilder<TMaterial, TVertex, TSkin> Mesh => _Mesh;
+        public SkinnedMeshBuilder<TMaterial, TVertex, TJoints> Mesh => _Mesh;
 
         public TMaterial Material => _Material;
 
-        public IReadOnlyList<(TVertex, TSkin)> Vertices => _Vertices;
+        public IReadOnlyList<(TVertex, TJoints)> Vertices => _Vertices;
 
         public IReadOnlyList<int> Indices => _Indices;
 
@@ -57,7 +57,7 @@ namespace SharpGLTF.Geometry
 
         #region API
 
-        public void AddTriangle((TVertex, TSkin) a, (TVertex, TSkin) b, (TVertex, TSkin) c)
+        public void AddTriangle((TVertex, TJoints) a, (TVertex, TJoints) b, (TVertex, TJoints) c)
         {
             var aa = _Vertices.Use(a);
             var bb = _Vertices.Use(b);
@@ -76,9 +76,9 @@ namespace SharpGLTF.Geometry
         #endregion
     }
 
-    public class SkinnedMeshBuilder<TMaterial, TVertex, TSkin>
+    public class SkinnedMeshBuilder<TMaterial, TVertex, TJoints>
         where TVertex : struct, VertexTypes.IVertex
-        where TSkin : struct, VertexTypes.IVertexJoints
+        where TJoints : struct, VertexTypes.IJoints
     {
         #region lifecycle
 
@@ -91,7 +91,7 @@ namespace SharpGLTF.Geometry
 
         #region data
 
-        private readonly Dictionary<TMaterial, SkinnedPrimitiveBuilder<TMaterial, TVertex, TSkin>> _Primitives = new Dictionary<TMaterial, SkinnedPrimitiveBuilder<TMaterial, TVertex, TSkin>>();
+        private readonly Dictionary<TMaterial, SkinnedPrimitiveBuilder<TMaterial, TVertex, TJoints>> _Primitives = new Dictionary<TMaterial, SkinnedPrimitiveBuilder<TMaterial, TVertex, TJoints>>();
 
         #endregion
 
@@ -99,13 +99,13 @@ namespace SharpGLTF.Geometry
 
         public string Name { get; set; }
 
-        public IReadOnlyCollection<SkinnedPrimitiveBuilder<TMaterial, TVertex, TSkin>> Primitives => _Primitives.Values;
+        public IReadOnlyCollection<SkinnedPrimitiveBuilder<TMaterial, TVertex, TJoints>> Primitives => _Primitives.Values;
 
         #endregion
 
         #region API
 
-        public void AddPolygon(TMaterial material, params (TVertex, TSkin)[] points)
+        public void AddPolygon(TMaterial material, params (TVertex, TJoints)[] points)
         {
             for (int i = 2; i < points.Length; ++i)
             {
@@ -113,11 +113,11 @@ namespace SharpGLTF.Geometry
             }
         }
 
-        public void AddTriangle(TMaterial material, (TVertex, TSkin) a, (TVertex, TSkin) b, (TVertex, TSkin) c)
+        public void AddTriangle(TMaterial material, (TVertex, TJoints) a, (TVertex, TJoints) b, (TVertex, TJoints) c)
         {
-            if (!_Primitives.TryGetValue(material, out SkinnedPrimitiveBuilder<TMaterial, TVertex, TSkin> primitive))
+            if (!_Primitives.TryGetValue(material, out SkinnedPrimitiveBuilder<TMaterial, TVertex, TJoints> primitive))
             {
-                primitive = new SkinnedPrimitiveBuilder<TMaterial, TVertex, TSkin>(this, material);
+                primitive = new SkinnedPrimitiveBuilder<TMaterial, TVertex, TJoints>(this, material);
                 _Primitives[material] = primitive;
             }
 
@@ -126,19 +126,19 @@ namespace SharpGLTF.Geometry
 
         public IEnumerable<(int, int, int)> GetTriangles(TMaterial material)
         {
-            if (_Primitives.TryGetValue(material, out SkinnedPrimitiveBuilder<TMaterial, TVertex, TSkin> primitive)) return primitive.Triangles;
+            if (_Primitives.TryGetValue(material, out SkinnedPrimitiveBuilder<TMaterial, TVertex, TJoints> primitive)) return primitive.Triangles;
 
             return Enumerable.Empty<(int, int, int)>();
         }
 
         public IReadOnlyList<int> GetIndices(TMaterial material)
         {
-            if (_Primitives.TryGetValue(material, out SkinnedPrimitiveBuilder<TMaterial, TVertex, TSkin> primitive)) return primitive.Indices;
+            if (_Primitives.TryGetValue(material, out SkinnedPrimitiveBuilder<TMaterial, TVertex, TJoints> primitive)) return primitive.Indices;
 
             return new int[0];
         }
 
-        internal static IEnumerable<(TMaterial, MemoryAccessor[], MemoryAccessor)[]> MergeBuffers(IEnumerable<SkinnedMeshBuilder<TMaterial, TVertex, TSkin>> meshBuilders)
+        internal static IEnumerable<PackedMeshBuilder<TMaterial>> PackMeshes(IEnumerable<SkinnedMeshBuilder<TMaterial, TVertex, TJoints>> meshBuilders)
         {
             var vertexBlocks = VertexTypes.VertexUtils.CreateVertexMemoryAccessors
                 (
@@ -154,20 +154,17 @@ namespace SharpGLTF.Geometry
                 .Select(item => item.Indices)
                 ).ToList();
 
-            int bidx = 0;
+            int idx = 0;
 
             foreach (var meshBuilder in meshBuilders)
             {
-                var dstMesh = new (TMaterial, MemoryAccessor[], MemoryAccessor)[meshBuilder.Primitives.Count];
-
-                int pidx = 0;
+                var dstMesh = new PackedMeshBuilder<TMaterial>(meshBuilder.Name);
 
                 foreach (var primitiveBuilder in meshBuilder.Primitives)
                 {
-                    dstMesh[pidx] = (primitiveBuilder.Material, vertexBlocks[bidx], indexBlocks[bidx]);
+                    dstMesh.AddPrimitive(primitiveBuilder.Material, vertexBlocks[idx], indexBlocks[idx]);
 
-                    ++pidx;
-                    ++bidx;
+                    ++idx;
                 }
 
                 yield return dstMesh;

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

@@ -13,7 +13,7 @@ namespace SharpGLTF.Geometry
     {
         public StaticMeshBuilder(string name = null) : base(name) { }
 
-        public new void AddPolygon(TMaterial material, params TVertex[] points)
+        public void AddPolygon(TMaterial material, params TVertex[] points)
         {
             for (int i = 2; i < points.Length; ++i)
             {

+ 4 - 4
src/SharpGLTF.Toolkit/Geometry/VertexTypes/SkinnedVertices.cs

@@ -5,13 +5,13 @@ using System.Text;
 
 namespace SharpGLTF.Geometry.VertexTypes
 {
-    public interface IVertexJoints { }
+    public interface IJoints { }
 
-    public struct VertexJoints0 : IVertexJoints
+    public struct VertexJoints0 : IJoints
     {
     }
 
-    public struct VertexJoints4 : IVertexJoints
+    public struct VertexJoints4 : IJoints
     {
         public VertexJoints4(int jointIndex)
         {
@@ -32,7 +32,7 @@ namespace SharpGLTF.Geometry.VertexTypes
         public Vector4 Weights_0;
     }
 
-    public struct VertexJoints8 : IVertexJoints
+    public struct VertexJoints8 : IJoints
     {
         public VertexJoints8(int jointIndex)
         {

+ 6 - 6
src/SharpGLTF.Toolkit/Geometry/VertexTypes/VertexUtils.cs

@@ -12,7 +12,7 @@ namespace SharpGLTF.Geometry.VertexTypes
     {
         public static IEnumerable<MemoryAccessor[]> CreateVertexMemoryAccessors<TVertex, TSkin>(this IEnumerable<IReadOnlyList<(TVertex, TSkin)>> vertexBlocks)
             where TVertex : struct, IVertex
-            where TSkin : struct, IVertexJoints
+            where TSkin : struct, IJoints
         {
             // total number of vertices
             var totalCount = vertexBlocks.Sum(item => item.Count);
@@ -43,10 +43,10 @@ namespace SharpGLTF.Geometry.VertexTypes
                         isSkin = true;
                     }
 
-                    if (accessor.Attribute.Dimensions == Schema2.DimensionType.SCALAR) accessor.AsScalarArray().FillFrom(0, GetScalarColumn<TVertex, TSkin>(finfo, block, isSkin));
-                    if (accessor.Attribute.Dimensions == Schema2.DimensionType.VEC2) accessor.AsVector2Array().FillFrom(0, GetVector2Column<TVertex, TSkin>(finfo, block, isSkin));
-                    if (accessor.Attribute.Dimensions == Schema2.DimensionType.VEC3) accessor.AsVector3Array().FillFrom(0, GetVector3Column<TVertex, TSkin>(finfo, block, isSkin));
-                    if (accessor.Attribute.Dimensions == Schema2.DimensionType.VEC4) accessor.AsVector4Array().FillFrom(0, GetVector4Column<TVertex, TSkin>(finfo, block, isSkin));
+                    if (accessor.Attribute.Dimensions == Schema2.DimensionType.SCALAR) accessor.Fill(GetScalarColumn(finfo, block, isSkin));
+                    if (accessor.Attribute.Dimensions == Schema2.DimensionType.VEC2) accessor.Fill(GetVector2Column(finfo, block, isSkin));
+                    if (accessor.Attribute.Dimensions == Schema2.DimensionType.VEC3) accessor.Fill(GetVector3Column(finfo, block, isSkin));
+                    if (accessor.Attribute.Dimensions == Schema2.DimensionType.VEC4) accessor.Fill(GetVector4Column(finfo, block, isSkin));
                 }
 
                 yield return accessors;
@@ -71,7 +71,7 @@ namespace SharpGLTF.Geometry.VertexTypes
             {
                 var accessor = new MemoryAccessor(ibuffer, attribute.Slice(baseIndicesIndex, block.Count));
 
-                accessor.AsIntegerArray().FillFrom(0, block);
+                accessor.Fill(block);
 
                 yield return accessor;
 

+ 1 - 1
src/SharpGLTF.Toolkit/Schema2/AccessorExtensions.cs

@@ -7,7 +7,7 @@ namespace SharpGLTF.Schema2
 {
     public static partial class Toolkit
     {
-        public static Accessor CreateVertexAccessor(this ModelRoot root, Geometry.MemoryAccessor memAccessor)
+        public static Accessor CreateVertexAccessor(this ModelRoot root, Memory.MemoryAccessor memAccessor)
         {
             var accessor = root.CreateAccessor(memAccessor.Attribute.Name);
 

+ 25 - 27
src/SharpGLTF.Toolkit/Schema2/MeshExtensions.cs

@@ -12,25 +12,32 @@ namespace SharpGLTF.Schema2
     {
         #region meshes
 
-        public static Mesh CreateMesh<TVertex, TSkin>(this ModelRoot root, Geometry.SkinnedMeshBuilder<Material, TVertex, TSkin> meshBuilder)
+        public static Mesh CreateMesh<TVertex, TJoints>(this ModelRoot root, Geometry.SkinnedMeshBuilder<Material, TVertex, TJoints> meshBuilder)
             where TVertex : struct, Geometry.VertexTypes.IVertex
-            where TSkin : struct, Geometry.VertexTypes.IVertexJoints
+            where TJoints : struct, Geometry.VertexTypes.IJoints
         {
             return root.CreateMeshes(m => m, meshBuilder).First();
         }
 
-        public static Mesh CreateMesh<TMaterial, TVertex, TSkin>(this ModelRoot root, Func<TMaterial, Material> materialEvaluator, Geometry.SkinnedMeshBuilder<TMaterial, TVertex, TSkin> meshBuilder)
+        public static Mesh CreateMesh<TMaterial, TVertex, TJoints>(this ModelRoot root, Func<TMaterial, Material> materialEvaluator, Geometry.SkinnedMeshBuilder<TMaterial, TVertex, TJoints> meshBuilder)
             where TVertex : struct, Geometry.VertexTypes.IVertex
-            where TSkin : struct, Geometry.VertexTypes.IVertexJoints
+            where TJoints : struct, Geometry.VertexTypes.IJoints
         {
             return root.CreateMeshes(materialEvaluator, meshBuilder).First();
         }
 
-        public static Mesh[] CreateMeshes<TMaterial, TVertex, TSkin>(this ModelRoot root, Func<TMaterial, Material> materialEvaluator, params Geometry.SkinnedMeshBuilder<TMaterial, TVertex, TSkin>[] meshBuilders)
+        public static IReadOnlyList<Mesh> CreateMeshes<TVertex, TJoints>(this ModelRoot root, params Geometry.SkinnedMeshBuilder<Material, TVertex, TJoints>[] meshBuilders)
             where TVertex : struct, Geometry.VertexTypes.IVertex
-            where TSkin : struct, Geometry.VertexTypes.IVertexJoints
+            where TJoints : struct, Geometry.VertexTypes.IJoints
         {
-            // create a new schema material for every unique material in the mesh builders.
+            return root.CreateMeshes<Material, TVertex, TJoints>(k => k, meshBuilders);
+        }
+
+        public static IReadOnlyList<Mesh> CreateMeshes<TMaterial, TVertex, TJoints>(this ModelRoot root, Func<TMaterial, Material> materialEvaluator, params Geometry.SkinnedMeshBuilder<TMaterial, TVertex, TJoints>[] meshBuilders)
+            where TVertex : struct, Geometry.VertexTypes.IVertex
+            where TJoints : struct, Geometry.VertexTypes.IJoints
+        {
+            // create a new material for every unique material in the mesh builders.
             var mapMaterials = meshBuilders
                 .SelectMany(item => item.Primitives)
                 .Select(item => item.Material)
@@ -38,26 +45,17 @@ namespace SharpGLTF.Schema2
                 .ToDictionary(k => k, k => materialEvaluator(k));
 
             // creates meshes and primitives using MemoryAccessors using a single, shared vertex and index buffer
-            var srcMeshes = Geometry.SkinnedMeshBuilder<TMaterial, TVertex, TSkin>
-                .MergeBuffers(meshBuilders)
+            var srcMeshes = Geometry.SkinnedMeshBuilder<TMaterial, TVertex, TJoints>
+                .PackMeshes(meshBuilders)
                 .ToList();
 
-            var dstMeshes = meshBuilders
-                .Select(item => root.CreateMesh(item.Name))
-                .ToArray();
+            var dstMeshes = new List<Mesh>();
 
-            for (int i = 0; i < dstMeshes.Length; ++i)
+            foreach (var srcMesh in srcMeshes)
             {
-                var dstMesh = dstMeshes[i];
-                var srcMesh = srcMeshes[i];
-
-                foreach (var srcPrim in srcMesh)
-                {
-                    dstMesh.CreatePrimitive()
-                        .WithMaterial( mapMaterials[srcPrim.Item1] )
-                        .WithVertexAccessors(srcPrim.Item2)
-                        .WithIndicesAccessor(PrimitiveType.TRIANGLES, srcPrim.Item3);
-                }
+                var dstMesh = srcMesh.CreateSchema2Mesh(root, m => mapMaterials[m]);
+
+                dstMeshes.Add(dstMesh);
             }
 
             return dstMeshes;
@@ -176,21 +174,21 @@ namespace SharpGLTF.Schema2
 
         public static MeshPrimitive WithVertexAccessors<TVertex, TSkin>(this MeshPrimitive primitive, IReadOnlyList<(TVertex, TSkin)> vertices)
             where TVertex : struct, Geometry.VertexTypes.IVertex
-            where TSkin : struct, Geometry.VertexTypes.IVertexJoints
+            where TSkin : struct, Geometry.VertexTypes.IJoints
         {
             var memAccessors = Geometry.VertexTypes.VertexUtils.CreateVertexMemoryAccessors(new[] { vertices }).First();
 
             return primitive.WithVertexAccessors(memAccessors);
         }
 
-        public static MeshPrimitive WithVertexAccessors(this MeshPrimitive primitive, IEnumerable<Geometry.MemoryAccessor> memAccessors)
+        public static MeshPrimitive WithVertexAccessors(this MeshPrimitive primitive, IEnumerable<Memory.MemoryAccessor> memAccessors)
         {
             foreach (var va in memAccessors) primitive.WithVertexAccessor(va);
 
             return primitive;
         }
 
-        public static MeshPrimitive WithVertexAccessor(this MeshPrimitive primitive, Geometry.MemoryAccessor memAccessor)
+        public static MeshPrimitive WithVertexAccessor(this MeshPrimitive primitive, Memory.MemoryAccessor memAccessor)
         {
             var root = primitive.LogicalParent.LogicalParent;
 
@@ -199,7 +197,7 @@ namespace SharpGLTF.Schema2
             return primitive;
         }
 
-        public static MeshPrimitive WithIndicesAccessor(this MeshPrimitive primitive, PrimitiveType primitiveType, Geometry.MemoryAccessor memAccessor)
+        public static MeshPrimitive WithIndicesAccessor(this MeshPrimitive primitive, PrimitiveType primitiveType, Memory.MemoryAccessor memAccessor)
         {
             var root = primitive.LogicalParent.LogicalParent;
 

+ 1 - 1
src/SharpGLTF.Toolkit/SharpGLTF.Toolkit.csproj

@@ -32,7 +32,7 @@
     <DocumentationFile>bin\Docs\SharpGLTF.Toolkit.xml</DocumentationFile>
   </PropertyGroup>
 
-  <ItemGroup>
+  <ItemGroup>    
     <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
     <PackageReference Include="System.Memory" Version="4.5.2" />
     <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />

+ 3 - 3
src/SharpGLTF/Debug/DebugViews.cs

@@ -69,15 +69,15 @@ namespace SharpGLTF.Debug
                 if (_Value.Dimensions == Schema2.DimensionType.VEC4) return _Value.AsVector4Array().Cast<Object>().ToArray();
                 if (_Value.Dimensions == Schema2.DimensionType.MAT4) return _Value.AsMatrix4x4Array().Cast<Object>().ToArray();
 
-                var itemSize = _Value.ItemByteSize;
-                var byteStride = Math.Max(_Value.SourceBufferView.ByteStride, itemSize);
+                var itemByteSz = _Value.ItemByteSize;
+                var byteStride = Math.Max(_Value.SourceBufferView.ByteStride, itemByteSz);
                 var items = new ArraySegment<Byte>[_Value.Count];
 
                 var buffer = _Value.SourceBufferView.Content.Slice(_Value.ByteOffset, _Value.Count * byteStride);
 
                 for (int i = 0; i < items.Length; ++i )
                 {
-                    items[i] = buffer.Slice(i * byteStride, itemSize);
+                    items[i] = buffer.Slice(i * byteStride, itemByteSz);
                 }
 
                 return items.Cast<Object>().ToArray();

+ 6 - 3
src/SharpGLTF/Geometry/MeshPrimitive.cs

@@ -6,6 +6,9 @@ using System.Text;
 
 namespace SharpGLTF.Geometry
 {
+    using Memory;
+
+    [Obsolete("Still here for reference, but most probably I'll use these objects for read meshes only")]
     public abstract class NamedObject
     {
         public NamedObject() { }
@@ -276,7 +279,7 @@ namespace SharpGLTF.Geometry
             _Indices = IndicesAccessor.CreateAccessors(itemsCount);
         }
 
-        public void AssignToSchema(Schema2.MeshPrimitive dstPrim)
+        internal void CopyTo(Schema2.MeshPrimitive dstPrim)
         {
             // TODO: clear primitive
 
@@ -340,7 +343,7 @@ namespace SharpGLTF.Geometry
             return p;
         }
 
-        public void AssignToSchema(Schema2.Mesh mesh)
+        public void CopyTo(Schema2.Mesh mesh)
         {
             mesh.Name = this.Name;
 
@@ -348,7 +351,7 @@ namespace SharpGLTF.Geometry
             {
                 var dstp = mesh.CreatePrimitive();
 
-                srcp.AssignToSchema(dstp);
+                srcp.CopyTo(dstp);
             }
 
             // todo: set morph targets

+ 0 - 0
src/SharpGLTF/Memory/Arrays.cs → src/SharpGLTF/Memory/EncodedArrays.cs


+ 49 - 0
src/SharpGLTF/Memory/FloatingArrays.cs

@@ -215,6 +215,21 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ScalarArray"/> struct.
+        /// </summary>
+        /// <param name="source">The array to wrap.</param>
+        /// <param name="byteOffset">The zero-based index of the first <see cref="Byte"/> in <paramref name="source"/>.</param>
+        /// <param name="itemsCount">The number of <see cref="Single"/> items in <paramref name="source"/>.</param>
+        /// <param name="byteStride">
+        /// The byte stride between elements.
+        /// If the value is zero, the size of the item is used instead.
+        /// </param>
+        /// <param name="encoding">A value of <see cref="ENCODING"/>.</param>
+        /// <param name="normalized">True if values are normalized.</param>
+        public ScalarArray(Byte[] source, int byteOffset, int itemsCount, int byteStride, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
+            : this(new BYTES(source), byteOffset, itemsCount, byteStride, encoding, normalized) { }
+
         /// <summary>
         /// Initializes a new instance of the <see cref="ScalarArray"/> struct.
         /// </summary>
@@ -289,6 +304,9 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
+        public Vector2Array(Byte[] source, int byteOffset, int itemsCount, int byteStride, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
+            : this(new BYTES(source), byteOffset, itemsCount, byteStride, encoding, normalized) { }
+
         public Vector2Array(BYTES source, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(source, 0, int.MaxValue, byteStride, encoding, normalized) { }
 
@@ -349,6 +367,21 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Vector3Array"/> struct.
+        /// </summary>
+        /// <param name="source">The array to wrap.</param>
+        /// <param name="byteOffset">The zero-based index of the first <see cref="Byte"/> in <paramref name="source"/>.</param>
+        /// <param name="itemsCount">The number of <see cref="Vector3"/> items in <paramref name="source"/>.</param>
+        /// <param name="byteStride">
+        /// The byte stride between elements.
+        /// If the value is zero, the size of the item is used instead.
+        /// </param>
+        /// <param name="encoding">A value of <see cref="ENCODING"/>.</param>
+        /// <param name="normalized">True if values are normalized.</param>
+        public Vector3Array(Byte[] source, int byteOffset, int itemsCount, int byteStride, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
+            : this(new BYTES(source), byteOffset, itemsCount, byteStride, encoding, normalized) { }
+
         /// <summary>
         /// Initializes a new instance of the <see cref="Vector3Array"/> struct.
         /// </summary>
@@ -432,6 +465,9 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
+        public Vector4Array(Byte[] source, int byteOffset, int itemsCount, int byteStride, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
+            : this(new BYTES(source), byteOffset, itemsCount, byteStride, encoding, normalized) { }
+
         public Vector4Array(BYTES source, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(source, 0, int.MaxValue, byteStride, encoding, normalized) { }
 
@@ -494,6 +530,9 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
+        public QuaternionArray(Byte[] source, int byteOffset, int itemsCount, int byteStride, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
+            : this(new BYTES(source), byteOffset, itemsCount, byteStride, encoding, normalized) { }
+
         public QuaternionArray(BYTES source, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(source, 0, int.MaxValue, byteStride, encoding, normalized) { }
 
@@ -556,6 +595,9 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
+        public Matrix4x4Array(Byte[] source, int byteOffset, int itemsCount, int byteStride, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
+            : this(new BYTES(source), byteOffset, itemsCount, byteStride, encoding, normalized) { }
+
         public Matrix4x4Array(BYTES source, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(source, 0, int.MaxValue, byteStride, encoding, normalized) { }
 
@@ -626,10 +668,17 @@ namespace SharpGLTF.Memory
         #endregion
     }
 
+    /// <summary>
+    /// Wraps an encoded <see cref="BYTES"/> and exposes it as an array of <see cref="float"/> array values.
+    /// </summary>
+    [System.Diagnostics.DebuggerDisplay("MultiArray Accessor {Count}")]
     public struct MultiArray : IEncodedArray<Single[]>
     {
         #region constructors
 
+        public MultiArray(Byte[] source, int byteOffset, int itemsCount, int byteStride, int dimensions, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
+            : this(new BYTES(source), byteOffset, itemsCount, byteStride, dimensions, encoding, normalized) { }
+
         public MultiArray(BYTES source, int byteOffset, int itemsCount, int byteStride, int dimensions, ENCODING encoding, Boolean normalized)
         {
             _Dimensions = dimensions;

+ 17 - 3
src/SharpGLTF/Geometry/MemoryAccessor.cs → src/SharpGLTF/Memory/MemoryAccessor.cs

@@ -4,10 +4,8 @@ using System.Linq;
 using System.Numerics;
 using System.Text;
 
-namespace SharpGLTF.Geometry
+namespace SharpGLTF.Memory
 {
-    using Memory;
-
     using DIMENSIONS = Schema2.DimensionType;
     using ENCODING = Schema2.EncodingType;
 
@@ -227,6 +225,10 @@ namespace SharpGLTF.Geometry
             _Attribute.ByteStride = byteStride;
         }
 
+        public void Fill(IEnumerable<Int32> values) { AsIntegerArray().FillFrom(0, values); }
+
+        public void Fill(IEnumerable<UInt32> values) { AsIntegerArray().FillFrom(0, values); }
+
         public IntegerArray AsIntegerArray()
         {
             Guard.IsTrue(_Attribute.IsValidIndexer, nameof(_Attribute));
@@ -234,6 +236,8 @@ namespace SharpGLTF.Geometry
             return new IntegerArray(_Data, _Attribute.ByteOffset, _Attribute.ItemsCount, _Attribute.Encoding.ToIndex());
         }
 
+        public void Fill(IEnumerable<Single> values) { AsScalarArray().FillFrom(0, values); }
+
         public ScalarArray AsScalarArray()
         {
             Guard.IsTrue(_Attribute.IsValidVertexAttribute, nameof(_Attribute));
@@ -241,6 +245,8 @@ namespace SharpGLTF.Geometry
             return new ScalarArray(_Data, _Attribute.ByteOffset, _Attribute.ItemsCount, _Attribute.ByteStride, _Attribute.Encoding, _Attribute.Normalized);
         }
 
+        public void Fill(IEnumerable<Vector2> values) { AsVector2Array().FillFrom(0, values); }
+
         public Vector2Array AsVector2Array()
         {
             Guard.IsTrue(_Attribute.IsValidVertexAttribute, nameof(_Attribute));
@@ -248,6 +254,8 @@ namespace SharpGLTF.Geometry
             return new Vector2Array(_Data, _Attribute.ByteOffset, _Attribute.ItemsCount, _Attribute.ByteStride, _Attribute.Encoding, _Attribute.Normalized);
         }
 
+        public void Fill(IEnumerable<Vector3> values) { AsVector3Array().FillFrom(0, values); }
+
         public Vector3Array AsVector3Array()
         {
             Guard.IsTrue(_Attribute.IsValidVertexAttribute, nameof(_Attribute));
@@ -255,6 +263,8 @@ namespace SharpGLTF.Geometry
             return new Vector3Array(_Data, _Attribute.ByteOffset, _Attribute.ItemsCount, _Attribute.ByteStride, _Attribute.Encoding, _Attribute.Normalized);
         }
 
+        public void Fill(IEnumerable<Vector4> values) { AsVector4Array().FillFrom(0, values); }
+
         public Vector4Array AsVector4Array()
         {
             Guard.IsTrue(_Attribute.IsValidVertexAttribute, nameof(_Attribute));
@@ -262,6 +272,8 @@ namespace SharpGLTF.Geometry
             return new Vector4Array(_Data, _Attribute.ByteOffset, _Attribute.ItemsCount, _Attribute.ByteStride, _Attribute.Encoding, _Attribute.Normalized);
         }
 
+        public void Fill(IEnumerable<Quaternion> values) { AsQuaternionArray().FillFrom(0, values); }
+
         public QuaternionArray AsQuaternionArray()
         {
             Guard.IsTrue(_Attribute.IsValidVertexAttribute, nameof(_Attribute));
@@ -269,6 +281,8 @@ namespace SharpGLTF.Geometry
             return new QuaternionArray(_Data, _Attribute.ByteOffset, _Attribute.ItemsCount, _Attribute.ByteStride, _Attribute.Encoding, _Attribute.Normalized);
         }
 
+        public void Fill(IEnumerable<Matrix4x4> values) { AsMatrix4x4Array().FillFrom(0, values); }
+
         public Matrix4x4Array AsMatrix4x4Array()
         {
             Guard.IsTrue(_Attribute.IsValidVertexAttribute, nameof(_Attribute));

+ 6 - 9
src/SharpGLTF/Schema2/gltf.AccessorSparse.cs

@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Numerics;
-using System.Text;
+using System.Collections.Generic;
 
 namespace SharpGLTF.Schema2
 {
@@ -42,12 +39,12 @@ namespace SharpGLTF.Schema2
 
         public int Count => _count;
 
-        internal KeyValuePair<Memory.IntegerArray, Geometry.MemoryAccessor> _CreateMemoryAccessors(Accessor baseAccessor)
+        internal KeyValuePair<Memory.IntegerArray, Memory.MemoryAccessor> _CreateMemoryAccessors(Accessor baseAccessor)
         {
             var key = this._indices._GetIndicesArray(baseAccessor.LogicalParent, _count);
             var val = this._values._GetMemoryAccessor(baseAccessor.LogicalParent, _count, baseAccessor);
 
-            return new KeyValuePair<Memory.IntegerArray, Geometry.MemoryAccessor>(key, val);
+            return new KeyValuePair<Memory.IntegerArray, Memory.MemoryAccessor>(key, val);
         }
     }
 
@@ -85,11 +82,11 @@ namespace SharpGLTF.Schema2
             this._byteOffset = byteOffset.AsNullable(_byteOffsetDefault);
         }
 
-        internal Geometry.MemoryAccessor _GetMemoryAccessor(ROOT root, int count, Accessor baseAccessor)
+        internal Memory.MemoryAccessor _GetMemoryAccessor(ROOT root, int count, Accessor baseAccessor)
         {
             var view = root.LogicalBufferViews[this._bufferView];
-            var info = new Geometry.MemoryAccessInfo(null, this._byteOffset ?? 0, count, view.ByteStride, baseAccessor.Dimensions, baseAccessor.Encoding, baseAccessor.Normalized);
-            return new Geometry.MemoryAccessor(view.Content, info);
+            var info = new Memory.MemoryAccessInfo(null, this._byteOffset ?? 0, count, view.ByteStride, baseAccessor.Dimensions, baseAccessor.Encoding, baseAccessor.Normalized);
+            return new Memory.MemoryAccessor(view.Content, info);
         }
     }
 }

+ 70 - 102
src/SharpGLTF/Schema2/gltf.Accessors.cs

@@ -46,20 +46,45 @@ namespace SharpGLTF.Schema2
 
         internal int _LogicalBufferViewIndex    => this._bufferView.AsValue(-1);
 
+        /// <summary>
+        /// Gets the <see cref="BufferView"/> buffer that contains the items as an encoded byte array.
+        /// </summary>
         public BufferView SourceBufferView      => this._bufferView.HasValue ? this.LogicalParent.LogicalBufferViews[this._bufferView.Value] : null;
 
+        /// <summary>
+        /// Gets the number of items.
+        /// </summary>
         public int Count                        => this._count;
 
+        /// <summary>
+        /// Gets the starting byte offset within <see cref="SourceBufferView"/>.
+        /// </summary>
         public int ByteOffset                   => this._byteOffset.AsValue(0);
 
+        /// <summary>
+        /// Gets the <see cref="DimensionType"/> of an item.
+        /// </summary>
         public DimensionType Dimensions           => this._type;
 
+        /// <summary>
+        /// Gets the <see cref="EncodingType"/> of an item.
+        /// </summary>
         public EncodingType Encoding           => this._componentType;
 
+        /// <summary>
+        /// Gets a value indicating whether the items values are normalized.
+        /// </summary>
         public Boolean Normalized               => this._normalized.AsValue(false);
 
+        /// <summary>
+        /// Gets a value indicating whether this <see cref="Accessor"/> has a sparse structure.
+        /// </summary>
         public Boolean IsSparse                 => this._sparse != null;
 
+        /// <summary>
+        /// Gets the number of bytes required to encode a single item in <see cref="SourceBufferView"/>
+        /// Given the current <see cref="Dimensions"/> and <see cref="Encoding"/> states.
+        /// </summary>
         public int ItemByteSize                 => Encoding.ByteLength() * Dimensions.DimCount();
 
         public Transforms.BoundingBox3? LocalBounds3
@@ -77,18 +102,18 @@ namespace SharpGLTF.Schema2
 
         #region API
 
-        internal Geometry.MemoryAccessor _GetMemoryAccessor()
+        internal MemoryAccessor _GetMemoryAccessor()
         {
             var view = SourceBufferView;
-            var info = new Geometry.MemoryAccessInfo(null, ByteOffset, Count, view.ByteStride, Dimensions, Encoding, Normalized);
-            return new Geometry.MemoryAccessor(view.Content, info);
+            var info = new MemoryAccessInfo(null, ByteOffset, Count, view.ByteStride, Dimensions, Encoding, Normalized);
+            return new MemoryAccessor(view.Content, info);
         }
 
-        internal KeyValuePair<Memory.IntegerArray, Geometry.MemoryAccessor>? _GetSparseMemoryAccessor()
+        internal KeyValuePair<IntegerArray, MemoryAccessor>? _GetSparseMemoryAccessor()
         {
             return this._sparse == null
                 ?
-                (KeyValuePair<Memory.IntegerArray, Geometry.MemoryAccessor>?)null
+                (KeyValuePair<IntegerArray, MemoryAccessor>?)null
                 :
                 this._sparse._CreateMemoryAccessors(this);
         }
@@ -97,15 +122,24 @@ namespace SharpGLTF.Schema2
 
         #region Data Buffer API
 
-        public void SetData(BufferView buffer, int byteOffset, int itemCount, DimensionType dimensions, EncodingType encoding, Boolean normalized)
+        /// <summary>
+        /// Associates this <see cref="Accessor"/> with a <see cref="BufferView"/>
+        /// </summary>
+        /// <param name="buffer">The <see cref="BufferView"/> source.</param>
+        /// <param name="bufferByteOffset">The start byte offset within <paramref name="buffer"/>.</param>
+        /// <param name="itemCount">The number of items in the accessor.</param>
+        /// <param name="dimensions">The <see cref="DimensionType"/> item type.</param>
+        /// <param name="encoding">The <see cref="EncodingType"/> item encoding.</param>
+        /// <param name="normalized">The item normalization mode.</param>
+        public void SetData(BufferView buffer, int bufferByteOffset, int itemCount, DimensionType dimensions, EncodingType encoding, Boolean normalized)
         {
             Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
 
-            Guard.MustBeGreaterThanOrEqualTo(byteOffset, _byteOffsetMinimum, nameof(byteOffset));
+            Guard.MustBeGreaterThanOrEqualTo(bufferByteOffset, _byteOffsetMinimum, nameof(bufferByteOffset));
             Guard.MustBeGreaterThanOrEqualTo(itemCount, _countMinimum, nameof(itemCount));
 
             this._bufferView = buffer.LogicalIndex;
-            this._byteOffset = byteOffset.AsNullable(_byteOffsetDefault, _byteOffsetMinimum, int.MaxValue);
+            this._byteOffset = bufferByteOffset.AsNullable(_byteOffsetDefault, _byteOffsetMinimum, int.MaxValue);
             this._count = itemCount;
 
             this._type = dimensions;
@@ -124,42 +158,27 @@ namespace SharpGLTF.Schema2
 
         #region Index Buffer API
 
-        public void SetIndexData(Geometry.MemoryAccessor src)
+        public void SetIndexData(MemoryAccessor src)
         {
             var bv = this.LogicalParent.UseBufferView(src.Data, src.Attribute.ByteStride, BufferMode.ELEMENT_ARRAY_BUFFER);
             SetIndexData(bv, src.Attribute.ByteOffset, src.Attribute.ItemsCount, src.Attribute.Encoding.ToIndex());
         }
 
-        public void SetIndexData(BufferView buffer, int byteOffset, IReadOnlyList<Int32> items, IndexEncodingType encoding = IndexEncodingType.UNSIGNED_INT)
-        {
-            Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
-
-            SetIndexData(buffer, byteOffset, items.Count, encoding);
-
-            AsIndicesArray().FillFrom(0, items);
-
-            this.UpdateBounds();
-        }
-
-        public void SetIndexData(BufferView buffer, int byteOffset, IReadOnlyList<UInt32> items, IndexEncodingType encoding = IndexEncodingType.UNSIGNED_INT)
-        {
-            Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
-
-            SetIndexData(buffer, byteOffset, items.Count, encoding);
-
-            AsIndicesArray().FillFrom(0, items);
-
-            this.UpdateBounds();
-        }
-
-        public void SetIndexData(BufferView buffer, int byteOffset, int itemCount, IndexEncodingType encoding)
+        /// <summary>
+        /// Associates this <see cref="Accessor"/> with a <see cref="BufferView"/>
+        /// </summary>
+        /// <param name="buffer">The <see cref="BufferView"/> source.</param>
+        /// <param name="bufferByteOffset">The start byte offset within <paramref name="buffer"/>.</param>
+        /// <param name="itemCount">The number of items in the accessor.</param>
+        /// <param name="encoding">The <see cref="IndexEncodingType"/> item encoding.</param>
+        public void SetIndexData(BufferView buffer, int bufferByteOffset, int itemCount, IndexEncodingType encoding)
         {
             Guard.NotNull(buffer, nameof(buffer));
             Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
 
             if (buffer.DeviceBufferTarget.HasValue) Guard.IsTrue(buffer.DeviceBufferTarget.Value == BufferMode.ELEMENT_ARRAY_BUFFER, nameof(buffer));
 
-            SetData(buffer, byteOffset, itemCount, DimensionType.SCALAR, encoding.ToComponent(), false);
+            SetData(buffer, bufferByteOffset, itemCount, DimensionType.SCALAR, encoding.ToComponent(), false);
         }
 
         public IntegerArray AsIndicesArray()
@@ -174,73 +193,22 @@ namespace SharpGLTF.Schema2
 
         #region Vertex Buffer API
 
-        public void SetVertexData(Geometry.MemoryAccessor src)
+        public void SetVertexData(MemoryAccessor src)
         {
             var bv = this.LogicalParent.UseBufferView(src.Data, src.Attribute.ByteStride, BufferMode.ARRAY_BUFFER);
 
             SetVertexData(bv, src.Attribute.ByteOffset, src.Attribute.ItemsCount, src.Attribute.Dimensions, src.Attribute.Encoding, src.Attribute.Normalized);
         }
 
-        public void SetVertexData(BufferView buffer, int bufferByteOffset, IReadOnlyList<Single> items, EncodingType encoding = EncodingType.FLOAT, Boolean normalized = false)
-        {
-            Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
-            Guard.MustBePositiveAndMultipleOf(DimensionType.SCALAR.DimCount() * encoding.ByteLength(), 4, nameof(encoding));
-
-            SetVertexData(buffer, bufferByteOffset, items.Count, DimensionType.SCALAR, encoding, normalized);
-
-            AsScalarArray().FillFrom(0, items);
-
-            this.UpdateBounds();
-        }
-
-        public void SetVertexData(BufferView buffer, int bufferByteOffset, IReadOnlyList<Vector2> items, EncodingType encoding = EncodingType.FLOAT, Boolean normalized = false)
-        {
-            Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
-            Guard.MustBePositiveAndMultipleOf(DimensionType.VEC2.DimCount() * encoding.ByteLength(), 4, nameof(encoding));
-
-            SetVertexData(buffer, bufferByteOffset, items.Count, DimensionType.VEC2, encoding, normalized);
-
-            AsVector2Array().FillFrom(0, items);
-
-            this.UpdateBounds();
-        }
-
-        public void SetVertexData(BufferView buffer, int bufferByteOffset, IReadOnlyList<Vector3> items, EncodingType encoding = EncodingType.FLOAT, Boolean normalized = false)
-        {
-            Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
-            Guard.MustBePositiveAndMultipleOf(DimensionType.VEC3.DimCount() * encoding.ByteLength(), 4, nameof(encoding));
-
-            SetVertexData(buffer, bufferByteOffset, items.Count, DimensionType.VEC3, encoding, normalized);
-
-            AsVector3Array().FillFrom(0, items);
-
-            this.UpdateBounds();
-        }
-
-        public void SetVertexData(BufferView buffer, int bufferByteOffset, IReadOnlyList<Vector4> items, EncodingType encoding = EncodingType.FLOAT, Boolean normalized = false)
-        {
-            Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
-            Guard.MustBePositiveAndMultipleOf(DimensionType.VEC4.DimCount() * encoding.ByteLength(), 4, nameof(encoding));
-
-            SetVertexData(buffer, bufferByteOffset, items.Count, DimensionType.VEC4, encoding, normalized);
-
-            AsVector4Array().FillFrom(0, items);
-
-            this.UpdateBounds();
-        }
-
-        public void SetVertexData(BufferView buffer, int bufferByteOffset, IReadOnlyList<Quaternion> items, EncodingType encoding = EncodingType.FLOAT, Boolean normalized = false)
-        {
-            Guard.MustShareLogicalParent(this, buffer, nameof(buffer));
-            Guard.MustBePositiveAndMultipleOf(DimensionType.VEC4.DimCount() * encoding.ByteLength(), 4, nameof(encoding));
-
-            SetVertexData(buffer, bufferByteOffset, items.Count, DimensionType.VEC4, encoding, normalized);
-
-            AsQuaternionArray().FillFrom(0, items);
-
-            this.UpdateBounds();
-        }
-
+        /// <summary>
+        /// Associates this <see cref="Accessor"/> with a <see cref="BufferView"/>
+        /// </summary>
+        /// <param name="buffer">The <see cref="BufferView"/> source.</param>
+        /// <param name="bufferByteOffset">The start byte offset within <paramref name="buffer"/>.</param>
+        /// <param name="itemCount">The number of items in the accessor.</param>
+        /// <param name="dimensions">The <see cref="DimensionType"/> item type.</param>
+        /// <param name="encoding">The <see cref="EncodingType"/> item encoding.</param>
+        /// <param name="normalized">The item normalization mode.</param>
         public void SetVertexData(BufferView buffer, int bufferByteOffset, int itemCount, DimensionType dimensions = DimensionType.VEC3, EncodingType encoding = EncodingType.FLOAT, Boolean normalized = false)
         {
             Guard.NotNull(buffer, nameof(buffer));
@@ -252,14 +220,14 @@ namespace SharpGLTF.Schema2
             SetData(buffer, bufferByteOffset, itemCount, dimensions, encoding, normalized);
         }
 
-        public IEncodedArray<float> AsScalarArray()
+        public IEncodedArray<Single> AsScalarArray()
         {
             var memory = _GetMemoryAccessor();
 
             if (this._sparse == null) return memory.AsScalarArray();
 
             var sparseKV = this._sparse._CreateMemoryAccessors(this);
-            return Geometry.MemoryAccessor.CreateScalarSparseArray(memory, sparseKV.Key, sparseKV.Value);
+            return MemoryAccessor.CreateScalarSparseArray(memory, sparseKV.Key, sparseKV.Value);
         }
 
         public IEncodedArray<Vector2> AsVector2Array()
@@ -269,7 +237,7 @@ namespace SharpGLTF.Schema2
             if (this._sparse == null) return memory.AsVector2Array();
 
             var sparseKV = this._sparse._CreateMemoryAccessors(this);
-            return Geometry.MemoryAccessor.CreateVector2SparseArray(memory, sparseKV.Key, sparseKV.Value);
+            return MemoryAccessor.CreateVector2SparseArray(memory, sparseKV.Key, sparseKV.Value);
         }
 
         public IEncodedArray<Vector3> AsVector3Array()
@@ -279,7 +247,7 @@ namespace SharpGLTF.Schema2
             if (this._sparse == null) return memory.AsVector3Array();
 
             var sparseKV = this._sparse._CreateMemoryAccessors(this);
-            return Geometry.MemoryAccessor.CreateVector3SparseArray(memory, sparseKV.Key, sparseKV.Value);
+            return MemoryAccessor.CreateVector3SparseArray(memory, sparseKV.Key, sparseKV.Value);
         }
 
         public IEncodedArray<Vector4> AsVector4Array()
@@ -289,7 +257,7 @@ namespace SharpGLTF.Schema2
             if (this._sparse == null) return memory.AsVector4Array();
 
             var sparseKV = this._sparse._CreateMemoryAccessors(this);
-            return Geometry.MemoryAccessor.CreateVector4SparseArray(memory, sparseKV.Key, sparseKV.Value);
+            return MemoryAccessor.CreateVector4SparseArray(memory, sparseKV.Key, sparseKV.Value);
         }
 
         public IEncodedArray<Quaternion> AsQuaternionArray()
@@ -305,11 +273,11 @@ namespace SharpGLTF.Schema2
         {
             if (_sparse != null) throw new InvalidOperationException("Can't be used on Acessors with Sparse Data");
 
-            var byteSize = Encoding.ByteLength() * Dimensions.DimCount();
-            var byteStride = Math.Max(byteSize, SourceBufferView.ByteStride);
+            var itemByteSz = Encoding.ByteLength() * Dimensions.DimCount();
+            var byteStride = Math.Max(itemByteSz, SourceBufferView.ByteStride);
             var byteOffset = vertexIdx * byteStride;
 
-            return SourceBufferView.Content.Slice(this.ByteOffset + (vertexIdx * byteStride), byteSize);
+            return SourceBufferView.Content.Slice(this.ByteOffset + (vertexIdx * byteStride), itemByteSz);
         }
 
         #endregion

+ 1 - 1
src/SharpGLTF/Schema2/gltf.MeshPrimitive.cs

@@ -193,7 +193,7 @@ namespace SharpGLTF.Schema2
 
         public Memory.IntegerArray GetIndices() => IndexAccessor.AsIndicesArray();
 
-        public Geometry.MemoryAccessor GetVertices(string attributeKey) => GetVertexAccessor(attributeKey)._GetMemoryAccessor();
+        public Memory.MemoryAccessor GetVertices(string attributeKey) => GetVertexAccessor(attributeKey)._GetMemoryAccessor();
 
         #endregion
 

+ 1 - 1
src/SharpGLTF/Schema2/khr.lights.cs

@@ -250,7 +250,7 @@ namespace SharpGLTF.Schema2
         /// Gets or sets the <see cref="Schema2.PunctualLight"/> of this <see cref="Node"/>.
         /// </summary>
         /// <remarks>
-        /// This is part of <see cref="https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual"/> extension.
+        /// This is part of <see href="https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual"/> extension.
         /// </remarks>
         public PunctualLight PunctualLight
         {

+ 6 - 9
src/SharpGLTF/SharpGLTF.csproj

@@ -2,6 +2,7 @@
 
   <PropertyGroup>    
     <TargetFramework>netstandard2.0</TargetFramework>
+    <AssemblyName>SharpGLTF</AssemblyName>
     <RootNamespace>SharpGLTF</RootNamespace>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>    
     <PackageProjectUrl>https://github.com/vpenades/SharpGLTF</PackageProjectUrl>
@@ -14,7 +15,9 @@
     <Version>1.0.0-alpha0005</Version>
     <LangVersion>latest</LangVersion>
     <DebugSymbols>true</DebugSymbols>
-    <PackageLicenseFile>LICENSE</PackageLicenseFile>
+    <PackageLicenseFile>LICENSE</PackageLicenseFile>    
+    <PackageIconUrl>https://raw.githubusercontent.com/vpenades/SharpGLTF/master/build/Icons/glTF2Sharp.png</PackageIconUrl>
+    <CodeAnalysisRuleSet>..\..\SharpGLTF.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
 
   <ItemGroup>
@@ -31,7 +34,7 @@
     <DocumentationFile>bin\Docs\SharpGLTF.xml</DocumentationFile>
   </PropertyGroup>
   
-  <ItemGroup>
+  <ItemGroup>    
     <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />    
     <PackageReference Include="System.Memory" Version="4.5.2" />
     <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
@@ -46,13 +49,7 @@
       <ExcludeFromStyleCop>true</ExcludeFromStyleCop>
     </None>
   </ItemGroup>
-
-  <PropertyGroup>
-    <CodeAnalysisRuleSet>..\..\SharpGLTF.ruleset</CodeAnalysisRuleSet>
-    <AssemblyName>SharpGLTF</AssemblyName>
-    <PackageIconUrl>https://raw.githubusercontent.com/vpenades/SharpGLTF/master/build/Icons/glTF2Sharp.png</PackageIconUrl>    
-  </PropertyGroup>  
-
+  
   <ItemGroup>
     <AdditionalFiles Include="..\..\stylecop.json" />
   </ItemGroup>

+ 1 - 1
tests/SharpGLTF.Tests/Geometry/CreateMeshTests.cs

@@ -69,7 +69,7 @@ namespace SharpGLTF.Geometry
             // this assigns the mesh we've created before to this schema mesh.
             // Notice that the schema buffers being created will be using the
             // memory allocated by (#1) and (#2)
-            srcMesh.AssignToSchema(rnode.Mesh);
+            srcMesh.CopyTo(rnode.Mesh);
                         
             model.AttachToCurrentTest("Triangle.gltf");
             model.AttachToCurrentTest("Triangle.glb");

+ 37 - 35
tests/SharpGLTF.Tests/Schema2/Authoring/SolidMeshUtils.cs

@@ -63,55 +63,57 @@ namespace SharpGLTF.Schema2.Authoring
             var v11 = new Vector3(-t, 0, 1) * radius;
 
             // 5 faces around point 0
-            meshBuilder._AddSphereTriangle(material, xform, v0, v11, v5);
-            meshBuilder._AddSphereTriangle(material, xform, v0, v5, v1);
-            meshBuilder._AddSphereTriangle(material, xform, v0, v1, v7);
-            meshBuilder._AddSphereTriangle(material, xform, v0, v7, v10);
-            meshBuilder._AddSphereTriangle(material, xform, v0, v10, v11);
+            meshBuilder._AddSphereTriangle(material, xform, v0, v11, v5, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v0, v5, v1, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v0, v1, v7, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v0, v7, v10, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v0, v10, v11, 3);
 
             // 5 adjacent faces
-            meshBuilder._AddSphereTriangle(material, xform, v1, v5, v9);
-            meshBuilder._AddSphereTriangle(material, xform, v5, v11, v4);
-            meshBuilder._AddSphereTriangle(material, xform, v11, v10, v2);
-            meshBuilder._AddSphereTriangle(material, xform, v10, v7, v6);
-            meshBuilder._AddSphereTriangle(material, xform, v7, v1, v8);
+            meshBuilder._AddSphereTriangle(material, xform, v1, v5, v9, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v5, v11, v4, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v11, v10, v2, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v10, v7, v6, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v7, v1, v8, 3);
 
             // 5 faces around point 3
-            meshBuilder._AddSphereTriangle(material, xform, v3, v9, v4);
-            meshBuilder._AddSphereTriangle(material, xform, v3, v4, v2);
-            meshBuilder._AddSphereTriangle(material, xform, v3, v2, v6);
-            meshBuilder._AddSphereTriangle(material, xform, v3, v6, v8);
-            meshBuilder._AddSphereTriangle(material, xform, v3, v8, v9);
+            meshBuilder._AddSphereTriangle(material, xform, v3, v9, v4, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v3, v4, v2, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v3, v2, v6, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v3, v6, v8, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v3, v8, v9, 3);
 
             // 5 adjacent faces
-            meshBuilder._AddSphereTriangle(material, xform, v4, v9, v5);
-            meshBuilder._AddSphereTriangle(material, xform, v2, v4, v11);
-            meshBuilder._AddSphereTriangle(material, xform, v6, v2, v10);
-            meshBuilder._AddSphereTriangle(material, xform, v8, v6, v7);
-            meshBuilder._AddSphereTriangle(material, xform, v9, v8, v1);
+            meshBuilder._AddSphereTriangle(material, xform, v4, v9, v5, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v2, v4, v11, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v6, v2, v10, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v8, v6, v7, 3);
+            meshBuilder._AddSphereTriangle(material, xform, v9, v8, v1, 3);
         }
 
-        private static void _AddSphereTriangle<TMaterial>(this StaticMeshBuilder<TMaterial, VPOSNRM> meshBuilder, TMaterial material, Matrix4x4 xform, Vector3 a, Vector3 b, Vector3 c)
+        private static void _AddSphereTriangle<TMaterial>(this StaticMeshBuilder<TMaterial, VPOSNRM> meshBuilder, TMaterial material, Matrix4x4 xform, Vector3 a, Vector3 b, Vector3 c, int iterations = 0)
         {
-            var ab = Vector3.Normalize(a + b) * a.Length();
-            var bc = Vector3.Normalize(b + c) * b.Length();
-            var ca = Vector3.Normalize(c + a) * c.Length();
+            if (iterations <=0)
+            {
+                var aa = new VPOSNRM(Vector3.Transform(a, xform), Vector3.Normalize(Vector3.TransformNormal(a, xform)));
+                var bb = new VPOSNRM(Vector3.Transform(b, xform), Vector3.Normalize(Vector3.TransformNormal(b, xform)));
+                var cc = new VPOSNRM(Vector3.Transform(c, xform), Vector3.Normalize(Vector3.TransformNormal(c, xform)));
 
-            var aa = new VPOSNRM(Vector3.Transform(a, xform), Vector3.Normalize(Vector3.TransformNormal(a, xform)));
-            var bb = new VPOSNRM(Vector3.Transform(b, xform), Vector3.Normalize(Vector3.TransformNormal(b, xform)));
-            var cc = new VPOSNRM(Vector3.Transform(c, xform), Vector3.Normalize(Vector3.TransformNormal(c, xform)));
+                meshBuilder.AddTriangle(material, aa, bb, cc);
+                return;
+            }
 
-            // meshBuilder.AddTriangle(material, aa, bb, cc);
+            --iterations;
 
-            var aabb = new VPOSNRM(Vector3.Transform(ab, xform), Vector3.Normalize(Vector3.TransformNormal(ab, xform)));
-            var bbcc = new VPOSNRM(Vector3.Transform(bc, xform), Vector3.Normalize(Vector3.TransformNormal(bc, xform)));
-            var ccaa = new VPOSNRM(Vector3.Transform(ca, xform), Vector3.Normalize(Vector3.TransformNormal(ca, xform)));
+            var ab = Vector3.Normalize(a + b) * a.Length();
+            var bc = Vector3.Normalize(b + c) * b.Length();
+            var ca = Vector3.Normalize(c + a) * c.Length();
 
-            meshBuilder.AddTriangle(material, aabb, bbcc, ccaa);
+            _AddSphereTriangle(meshBuilder, material, xform, ab, bc, ca, iterations);
 
-            meshBuilder.AddTriangle(material, aa, aabb, ccaa);
-            meshBuilder.AddTriangle(material, bb, bbcc, aabb);
-            meshBuilder.AddTriangle(material, cc, ccaa, bbcc);
+            _AddSphereTriangle(meshBuilder, material, xform, a, ab, ca, iterations);
+            _AddSphereTriangle(meshBuilder, material, xform, b, bc, ab, iterations);
+            _AddSphereTriangle(meshBuilder, material, xform, c, ca, bc, iterations);
         }
     }
 }