Browse Source

improving VertexColumns API

Vicente Penades 6 years ago
parent
commit
6529895cdc

+ 2 - 2
src/Shared/_Extensions.cs

@@ -198,7 +198,7 @@ namespace SharpGLTF
             return (left.Value.Item2, right.Value.Item2, amount);
         }
 
-        internal static Func<float, Vector3> GetSamplerFunc(this IEnumerable<(float, Vector3)> collection)
+        internal static Func<float, Vector3> GetLinearSamplerFunc(this IEnumerable<(float, Vector3)> collection)
         {
             if (collection == null) return null;
 
@@ -211,7 +211,7 @@ namespace SharpGLTF
             return _sampler;
         }
 
-        internal static Func<float, Quaternion> GetSamplerFunc(this IEnumerable<(float, Quaternion)> collection)
+        internal static Func<float, Quaternion> GetLinearSamplerFunc(this IEnumerable<(float, Quaternion)> collection)
         {
             if (collection == null) return null;
 

+ 3 - 3
src/SharpGLTF.Core/Schema2/gltf.Node.cs

@@ -128,9 +128,9 @@ namespace SharpGLTF.Schema2
 
             var xform = this.LocalTransform;
 
-            var sfunc = animation.FindScaleChannel(this).GetSamplerFunc();
-            var rfunc = animation.FindRotationChannel(this).GetSamplerFunc();
-            var tfunc = animation.FindTranslationChannel(this).GetSamplerFunc();
+            var sfunc = animation.FindScaleChannel(this).GetLinearSamplerFunc();
+            var rfunc = animation.FindRotationChannel(this).GetLinearSamplerFunc();
+            var tfunc = animation.FindTranslationChannel(this).GetLinearSamplerFunc();
 
             if (sfunc != null) xform.Scale = sfunc(time);
             if (rfunc != null) xform.Rotation = rfunc(time);

+ 23 - 23
src/SharpGLTF.Core/Transforms/MeshTransforms.cs

@@ -11,13 +11,13 @@ namespace SharpGLTF.Transforms
 {
     public interface ITransform
     {
-        V3 TransformPosition(V3 position, params (int, float)[] skinWeights);
-        V3 TransformNormal(V3 normal, params (int, float)[] skinWeights);
-        V4 TransformTangent(V4 tangent, params (int, float)[] skinWeights);
+        V3 TransformPosition(V3 position, (int, float)[] skinWeights);
+        V3 TransformNormal(V3 normal, (int, float)[] skinWeights);
+        V4 TransformTangent(V4 tangent, (int, float)[] skinWeights);
 
-        V3 TransformPosition(V3[] positions, params (int, float)[] skinWeights);
-        V3 TransformNormal(V3[] normals, params (int, float)[] skinWeights);
-        V4 TransformTangent(V4[] tangents, params (int, float)[] skinWeights);
+        V3 TransformPosition(V3[] positions, (int, float)[] skinWeights);
+        V3 TransformNormal(V3[] normals, (int, float)[] skinWeights);
+        V4 TransformTangent(V4[] tangents, (int, float)[] skinWeights);
     }
 
     public abstract class MorphTransform
@@ -99,7 +99,7 @@ namespace SharpGLTF.Transforms
         #endregion
     }
 
-    public class StaticTransform : MorphTransform , ITransform
+    public class StaticTransform : MorphTransform, ITransform
     {
         public StaticTransform(TRANSFORM xform, params float[] morphWeights)
             : base(morphWeights)
@@ -109,36 +109,36 @@ namespace SharpGLTF.Transforms
 
         private readonly TRANSFORM _Transform;
 
-        public V3 TransformPosition(V3 position, params (int, float)[] skinWeights)
+        public V3 TransformPosition(V3 position, (int, float)[] skinWeights)
         {
             return V3.Transform(position, _Transform);
         }
 
-        public V3 TransformNormal(V3 normal, params (int, float)[] skinWeights)
+        public V3 TransformNormal(V3 normal, (int, float)[] skinWeights)
         {
             return V3.Normalize(V3.Transform(normal, _Transform));
         }
 
-        public V4 TransformTangent(V4 tangent, params (int, float)[] skinWeights)
+        public V4 TransformTangent(V4 tangent, (int, float)[] skinWeights)
         {
             return V4.Transform(tangent, _Transform);
         }
 
-        public V3 TransformPosition(V3[] positions, params (int, float)[] skinWeights)
+        public V3 TransformPosition(V3[] positions, (int, float)[] skinWeights)
         {
             var position = MorphPositions(positions);
 
             return V3.Transform(position, _Transform);
         }
 
-        public V3 TransformNormal(V3[] normals, params (int, float)[] skinWeights)
+        public V3 TransformNormal(V3[] normals, (int, float)[] skinWeights)
         {
             var normal = MorphNormals(normals);
 
             return V3.Normalize(V3.TransformNormal(normal, _Transform));
         }
 
-        public V4 TransformTangent(V4[] tangents, params (int, float)[] skinWeights)
+        public V4 TransformTangent(V4[] tangents, (int, float)[] skinWeights)
         {
             var tangent = MorphTangents(tangents);
 
@@ -150,7 +150,7 @@ namespace SharpGLTF.Transforms
         }
     }
 
-    public class SkinTransform : MorphTransform , ITransform
+    public class SkinTransform : MorphTransform, ITransform
     {
         public SkinTransform(TRANSFORM[] invBindings, TRANSFORM[] xforms, params float[] morphWeights)
             : base(morphWeights)
@@ -169,7 +169,7 @@ namespace SharpGLTF.Transforms
 
         private readonly TRANSFORM[] _JointTransforms;
 
-        public V3 TransformPosition(V3 localPosition, params (int, float)[] skinWeights)
+        public V3 TransformPosition(V3 localPosition, (int, float)[] skinWeights)
         {
             var worldPosition = V3.Zero;
 
@@ -181,7 +181,7 @@ namespace SharpGLTF.Transforms
             return worldPosition;
         }
 
-        public V3 TransformNormal(V3 localNormal, params (int, float)[] skinWeights)
+        public V3 TransformNormal(V3 localNormal, (int, float)[] skinWeights)
         {
             var worldNormal = V3.Zero;
 
@@ -193,7 +193,7 @@ namespace SharpGLTF.Transforms
             return V3.Normalize(localNormal);
         }
 
-        public V4 TransformTangent(V4 localTangent, params (int, float)[] skinWeights)
+        public V4 TransformTangent(V4 localTangent, (int, float)[] skinWeights)
         {
             var localTangentV = new V3(localTangent.X, localTangent.Y, localTangent.Z);
             var worldTangent = V3.Zero;
@@ -206,19 +206,19 @@ namespace SharpGLTF.Transforms
             return new V4(worldTangent, localTangentV.Z);
         }
 
-        public V3 TransformPosition(V3[] positions, params (int, float)[] skinWeights)
+        public V3 TransformPosition(V3[] positions, (int, float)[] skinWeights)
         {
-            return TransformPosition(MorphPositions(positions));
+            return TransformPosition(MorphPositions(positions), skinWeights);
         }
 
-        public V3 TransformNormal(V3[] normals, params (int, float)[] skinWeights)
+        public V3 TransformNormal(V3[] normals, (int, float)[] skinWeights)
         {
-            return TransformNormal(MorphNormals(normals));
+            return TransformNormal(MorphNormals(normals), skinWeights);
         }
 
-        public V4 TransformTangent(V4[] tangents, params (int, float)[] skinWeights)
+        public V4 TransformTangent(V4[] tangents, (int, float)[] skinWeights)
         {
-            return TransformTangent(MorphTangents(tangents));
+            return TransformTangent(MorphTangents(tangents), skinWeights);
         }
     }
 }

+ 239 - 0
src/SharpGLTF.Toolkit/Geometry/VertexColumns.cs

@@ -0,0 +1,239 @@
+using System;
+using System.Collections.Generic;
+using System.Numerics;
+using System.Text;
+
+namespace SharpGLTF.Geometry
+{
+    using VertexTypes;
+
+    /// <summary>
+    /// Represents a vertex buffer, where every vertex attribute is represented as a vector column.
+    /// </summary>
+    /// <remarks>
+    /// One of the use cases of <see cref="VertexColumns"/> is to bind the different attribute
+    /// columns directly to the <see cref="Schema2.Accessor"/> source feed, which means that
+    /// if you modify the contents of a column that is binded directly to a model, you're
+    /// modifying the model's internal data.
+    /// </remarks>
+    public class VertexColumns
+    {
+        #region Data Columns
+
+        public IList<Vector3> Positions { get; set; }
+        public IList<Vector3> Normals { get; set; }
+        public IList<Vector4> Tangents { get; set; }
+
+        public IList<Vector4> Colors0 { get; set; }
+        public IList<Vector4> Colors1 { get; set; }
+
+        public IList<Vector2> Textures0 { get; set; }
+        public IList<Vector2> Textures1 { get; set; }
+
+        public IList<Vector4> Joints0 { get; set; }
+        public IList<Vector4> Joints1 { get; set; }
+
+        public IList<Vector4> Weights0 { get; set; }
+        public IList<Vector4> Weights1 { get; set; }
+
+        #endregion
+
+        #region API
+
+        /// <summary>
+        /// Creates an internal copy of the <see cref="Positions"/> columns,
+        /// which ensures the column data is not shared with other objects
+        /// </summary>
+        public void IsolatePositions()
+        {
+            if (this.Positions == null) return;
+
+            var newPositions = new Vector3[this.Positions.Count];
+
+            this.Positions.CopyTo(newPositions, 0);
+
+            this.Positions = newPositions;
+        }
+
+        /// <summary>
+        /// Creates an internal copy of the <see cref="Normals"/> columns,
+        /// which ensures the column data is not shared with other objects
+        /// </summary>
+        public void IsolateNormals()
+        {
+            if (this.Normals == null) return;
+
+            var newNormals = new Vector3[this.Normals.Count];
+
+            this.Normals.CopyTo(newNormals, 0);
+
+            this.Normals = newNormals;
+        }
+
+        /// <summary>
+        /// Creates an internal copy of the <see cref="Tangents"/> columns,
+        /// which ensures the column data is not shared with other objects
+        /// </summary>
+        public void IsolateTangents()
+        {
+            if (this.Tangents == null) return;
+
+            var newTangents = new Vector4[this.Tangents.Count];
+
+            this.Tangents.CopyTo(newTangents, 0);
+
+            this.Tangents = newTangents;
+        }
+
+        public void ApplyNormals(IReadOnlyDictionary<Vector3, Vector3> normalsMap)
+        {
+            IsolateNormals();
+
+            if (this.Normals == null) this.Normals = new Vector3[Positions.Count];
+
+            for (int i = 0; i < Normals.Count; ++i)
+            {
+                if (normalsMap.TryGetValue(this.Positions[i], out Vector3 nrm))
+                {
+                    this.Normals[i] = nrm;
+                }
+            }
+        }
+
+        public void ApplyTransform(Transforms.ITransform transform)
+        {
+            // since positions, normals and tangents might be binded directly to the model's buffer data,
+            // and we don't want to modify the source data, we create a copy of the columns.
+
+            IsolatePositions();
+            IsolateNormals();
+            IsolateTangents();
+
+            // prepare skinning data, if available
+
+            var jw0 = Joints0 != null && Weights0 != null;
+            var jw1 = Joints1 != null && Weights1 != null;
+
+            var jwjwjwjw = new (int, float)[(jw0 ? 4 : 0) + (jw1 ? 4 : 0)];
+
+            int vcount = Positions.Count;
+
+            for (int i = 0; i < vcount; ++i)
+            {
+                if (jw0)
+                {
+                    var j = Joints0[i];
+                    var w = Weights0[i];
+                    jwjwjwjw[0] = ((int)j.X, w.X);
+                    jwjwjwjw[1] = ((int)j.Y, w.Y);
+                    jwjwjwjw[2] = ((int)j.Z, w.Z);
+                    jwjwjwjw[3] = ((int)j.W, w.W);
+                }
+
+                if (jw1)
+                {
+                    var j = Joints1[i];
+                    var w = Weights1[i];
+                    jwjwjwjw[4] = ((int)j.X, w.X);
+                    jwjwjwjw[5] = ((int)j.Y, w.Y);
+                    jwjwjwjw[6] = ((int)j.Z, w.Z);
+                    jwjwjwjw[7] = ((int)j.W, w.W);
+                }
+
+                if (Positions != null) Positions[i] = transform.TransformPosition(Positions[i], jwjwjwjw);
+                if (Normals != null) Normals[i] = transform.TransformNormal(Normals[i], jwjwjwjw);
+                if (Tangents != null) Tangents[i] = transform.TransformTangent(Tangents[i], jwjwjwjw);
+            }
+
+            // we've just applied the transform,
+            // so we no longer need these columns.
+
+            Joints0 = null;
+            Joints1 = null;
+            Weights0 = null;
+            Weights1 = null;
+        }
+
+        public TvG GetVertexGeometry<TvG>(int index)
+            where TvG : struct, IVertexGeometry
+        {
+            var pnt = default(TvG);
+
+            if (Positions != null) pnt.SetPosition(Positions[index]);
+            if (Normals != null) pnt.SetNormal(Normals[index]);
+            if (Tangents != null) pnt.SetTangent(Tangents[index]);
+
+            return pnt;
+        }
+
+        public TvM GetVertexMaterial<TvM>(int index)
+            where TvM : struct, IVertexMaterial
+        {
+            var cctt = default(TvM);
+
+            if (Colors0 != null && cctt.MaxColors > 0) cctt.SetColor(0, Colors0[index]);
+            if (Colors1 != null && cctt.MaxColors > 1) cctt.SetColor(1, Colors1[index]);
+
+            if (Textures0 != null && cctt.MaxTextures > 0) cctt.SetTexCoord(0, Textures0[index]);
+            if (Textures1 != null && cctt.MaxTextures > 1) cctt.SetTexCoord(1, Textures1[index]);
+
+            return cctt;
+        }
+
+        public TvS GetVertexSkinning<TvS>(int index)
+            where TvS : struct, IVertexSkinning
+        {
+            var jjjj = default(TvS);
+
+            if (Joints0 != null && Weights0 != null)
+            {
+                var j = Joints0[index];
+                var w = Weights0[index];
+
+                jjjj.SetJointBinding(0, (int)j.X, w.X);
+                jjjj.SetJointBinding(1, (int)j.Y, w.Y);
+                jjjj.SetJointBinding(2, (int)j.Z, w.Z);
+                jjjj.SetJointBinding(3, (int)j.W, w.W);
+            }
+
+            if (Joints1 != null && Weights1 != null)
+            {
+                var j = Joints1[index];
+                var w = Weights1[index];
+
+                jjjj.SetJointBinding(4, (int)j.X, w.X);
+                jjjj.SetJointBinding(5, (int)j.Y, w.Y);
+                jjjj.SetJointBinding(6, (int)j.Z, w.Z);
+                jjjj.SetJointBinding(7, (int)j.W, w.W);
+            }
+
+            return jjjj;
+        }
+
+        public VertexBuilder<TvG, TvM, VertexEmpty> GetVertex<TvG, TvM>(int index)
+            where TvG : struct, IVertexGeometry
+            where TvM : struct, IVertexMaterial
+        {
+            return new VertexBuilder<TvG, TvM, VertexEmpty>
+                (
+                GetVertexGeometry<TvG>(index),
+                GetVertexMaterial<TvM>(index)
+                );
+        }
+
+        public VertexBuilder<TvG, TvM, TvS> GetVertex<TvG, TvM, TvS>(int index)
+            where TvG : struct, IVertexGeometry
+            where TvM : struct, IVertexMaterial
+            where TvS : struct, IVertexSkinning
+        {
+            return new VertexBuilder<TvG, TvM, TvS>
+                (
+                GetVertexGeometry<TvG>(index),
+                GetVertexMaterial<TvM>(index),
+                GetVertexSkinning<TvS>(index)
+                );
+        }
+
+        #endregion
+    }
+}

+ 0 - 153
src/SharpGLTF.Toolkit/Geometry/VertexTypes/VertexColumns.cs

@@ -1,153 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Numerics;
-using System.Text;
-
-namespace SharpGLTF.Geometry.VertexTypes
-{
-    /// <summary>
-    /// Represents a vertex buffer, where every vertex attribute is represented as a vector column.
-    /// </summary>
-    public class VertexColumns
-    {
-        #region columns
-
-        public IList<Vector3> Positions { get; set; }
-        public IList<Vector3> Normals { get; set; }
-        public IList<Vector4> Tangents { get; set; }
-
-        public IList<Vector4> Colors0 { get; set; }
-        public IList<Vector4> Colors1 { get; set; }
-
-        public IList<Vector2> Textures0 { get; set; }
-        public IList<Vector2> Textures1 { get; set; }
-
-        public IList<Vector4> Joints0 { get; set; }
-        public IList<Vector4> Joints1 { get; set; }
-
-        public IList<Vector4> Weights0 { get; set; }
-        public IList<Vector4> Weights1 { get; set; }
-
-        #endregion
-
-        #region API
-
-        public void SetNormals(IReadOnlyDictionary<Vector3, Vector3> normalsMap)
-        {
-            Normals = new Vector3[Positions.Count];
-
-            for (int i = 0; i < Normals.Count; ++i)
-            {
-                if (normalsMap.TryGetValue(Positions[i], out Vector3 nrm))
-                {
-                    Normals[i] = nrm;
-                }
-            }
-        }
-
-        public void ApplyTransform(Transforms.ITransform transform)
-        {
-            var newPos = new Vector3[Positions.Count];
-            var newNrm = Normals == null || Normals.Count < newPos.Length ? null : new Vector3[newPos.Length];
-            var newTgt = Tangents == null || Tangents.Count < newPos.Length ? null : new Vector4[newPos.Length];
-
-            var jw0 = Joints0 != null && Joints0.Count == newPos.Length && Weights0 != null && Weights0.Count == newPos.Length;
-            var jw1 = Joints1 != null && Joints1.Count == newPos.Length && Weights1 != null && Weights1.Count == newPos.Length;
-            var jjww = new (int, float)[8];
-
-            for (int i = 0; i < newPos.Length; ++i)
-            {
-                if (jw0)
-                {
-                    var j = Joints0[i];
-                    var w = Weights0[i];
-                    jjww[0] = ((int)j.X, w.X);
-                    jjww[1] = ((int)j.Y, w.Y);
-                    jjww[2] = ((int)j.Z, w.Z);
-                    jjww[3] = ((int)j.W, w.W);
-                }
-
-                if (jw1)
-                {
-                    var j = Joints1[i];
-                    var w = Weights1[i];
-                    jjww[4] = ((int)j.X, w.X);
-                    jjww[5] = ((int)j.Y, w.Y);
-                    jjww[6] = ((int)j.Z, w.Z);
-                    jjww[7] = ((int)j.W, w.W);
-                }
-
-                newPos[i] = transform.TransformPosition(Positions[i], jjww);
-                if (newNrm != null) newNrm[i] = transform.TransformNormal(Normals[i], jjww);
-                if (newTgt != null) newTgt[i] = transform.TransformTangent(Tangents[i], jjww);
-            }
-
-            Positions = newPos;
-            Normals = newNrm;
-            Tangents = newTgt;
-
-            Joints0 = null;
-            Joints1 = null;
-            Weights0 = null;
-            Weights1 = null;
-        }
-
-        public TvP GetPositionFragment<TvP>(int index)
-            where TvP : struct, IVertexGeometry
-        {
-            var pnt = default(TvP);
-
-            if (Positions != null) pnt.SetPosition(Positions[index]);
-            if (Normals != null) pnt.SetNormal(Normals[index]);
-            if (Tangents != null) pnt.SetTangent(Tangents[index]);
-
-            return pnt;
-        }
-
-        public TvM GetMaterialFragment<TvM>(int index)
-            where TvM : struct, IVertexMaterial
-        {
-            var cctt = default(TvM);
-
-            if (Colors0 != null && cctt.MaxColors > 0) cctt.SetColor(0, Colors0[index]);
-            if (Colors1 != null && cctt.MaxColors > 1) cctt.SetColor(1, Colors1[index]);
-
-            if (Textures0 != null && cctt.MaxTextures > 0) cctt.SetTexCoord(0, Textures0[index]);
-            if (Textures1 != null && cctt.MaxTextures > 1) cctt.SetTexCoord(1, Textures1[index]);
-
-            return cctt;
-        }
-
-        public TvS GetSkinningFragment<TvS>(int index)
-            where TvS : struct, IVertexSkinning
-        {
-            var jjjj = default(TvS);
-
-            if (Joints0 != null && Weights0 != null)
-            {
-                var j = Joints0[index];
-                var w = Weights0[index];
-
-                jjjj.SetJointBinding(0, (int)j.X, w.X);
-                jjjj.SetJointBinding(1, (int)j.Y, w.Y);
-                jjjj.SetJointBinding(2, (int)j.Z, w.Z);
-                jjjj.SetJointBinding(3, (int)j.W, w.W);
-            }
-
-            if (Joints1 != null && Weights1 != null)
-            {
-                var j = Joints1[index];
-                var w = Weights1[index];
-
-                jjjj.SetJointBinding(4, (int)j.X, w.X);
-                jjjj.SetJointBinding(5, (int)j.Y, w.Y);
-                jjjj.SetJointBinding(6, (int)j.Z, w.Z);
-                jjjj.SetJointBinding(7, (int)j.W, w.W);
-            }
-
-            return jjjj;
-        }
-
-        #endregion
-    }
-}

+ 17 - 21
src/SharpGLTF.Toolkit/Schema2/MeshExtensions.cs

@@ -290,27 +290,27 @@ namespace SharpGLTF.Schema2
             where TvS : struct, Geometry.VertexTypes.IVertexSkinning
         {
             var vertices = prim.GetVertexColumns();
-            if (vertices.Normals == null && defaultNormals != null) vertices.SetNormals(defaultNormals);
+            if (vertices.Normals == null && defaultNormals != null) vertices.ApplyNormals(defaultNormals);
 
             var triangles = prim.GetTriangleIndices();
 
             foreach (var t in triangles)
             {
-                var ap = vertices.GetPositionFragment<TvP>(t.Item1);
-                var bp = vertices.GetPositionFragment<TvP>(t.Item2);
-                var cp = vertices.GetPositionFragment<TvP>(t.Item3);
+                var ap = vertices.GetVertexGeometry<TvP>(t.Item1);
+                var bp = vertices.GetVertexGeometry<TvP>(t.Item2);
+                var cp = vertices.GetVertexGeometry<TvP>(t.Item3);
 
                 ap.Transform(xform);
                 bp.Transform(xform);
                 cp.Transform(xform);
 
-                var am = vertices.GetMaterialFragment<TvM>(t.Item1);
-                var bm = vertices.GetMaterialFragment<TvM>(t.Item2);
-                var cm = vertices.GetMaterialFragment<TvM>(t.Item3);
+                var am = vertices.GetVertexMaterial<TvM>(t.Item1);
+                var bm = vertices.GetVertexMaterial<TvM>(t.Item2);
+                var cm = vertices.GetVertexMaterial<TvM>(t.Item3);
 
-                var aj = vertices.GetSkinningFragment<TvS>(t.Item1);
-                var bj = vertices.GetSkinningFragment<TvS>(t.Item2);
-                var cj = vertices.GetSkinningFragment<TvS>(t.Item3);
+                var aj = vertices.GetVertexSkinning<TvS>(t.Item1);
+                var bj = vertices.GetVertexSkinning<TvS>(t.Item2);
+                var cj = vertices.GetVertexSkinning<TvS>(t.Item3);
 
                 yield return ((ap, am, aj), (bp, bm, bj), (cp, cm, cj), prim.Material);
             }
@@ -321,7 +321,7 @@ namespace SharpGLTF.Schema2
             where TvM : struct, Geometry.VertexTypes.IVertexMaterial
         {
             var vertices = prim.GetVertexColumns();
-            if (vertices.Normals == null && defaultNormals != null) vertices.SetNormals(defaultNormals);
+            if (vertices.Normals == null && defaultNormals != null) vertices.ApplyNormals(defaultNormals);
 
             vertices.ApplyTransform(xform);
 
@@ -331,15 +331,11 @@ namespace SharpGLTF.Schema2
 
             foreach (var t in triangles)
             {
-                var ap = vertices.GetPositionFragment<TvP>(t.Item1);
-                var bp = vertices.GetPositionFragment<TvP>(t.Item2);
-                var cp = vertices.GetPositionFragment<TvP>(t.Item3);
+                var a = vertices.GetVertex<TvP, TvM>(t.Item1);
+                var b = vertices.GetVertex<TvP, TvM>(t.Item1);
+                var c = vertices.GetVertex<TvP, TvM>(t.Item1);
 
-                var am = vertices.GetMaterialFragment<TvM>(t.Item1);
-                var bm = vertices.GetMaterialFragment<TvM>(t.Item2);
-                var cm = vertices.GetMaterialFragment<TvM>(t.Item3);
-
-                yield return ((ap, am), (bp, bm), (cp, cm), prim.Material);
+                yield return ((a.Geometry, a.Material), (b.Geometry, b.Material), (c.Geometry, c.Material), prim.Material);
             }
         }
 
@@ -353,11 +349,11 @@ namespace SharpGLTF.Schema2
             return p;
         }
 
-        public static Geometry.VertexTypes.VertexColumns GetVertexColumns(this MeshPrimitive primitive)
+        public static Geometry.VertexColumns GetVertexColumns(this MeshPrimitive primitive)
         {
             var vertexAccessors = primitive.VertexAccessors;
 
-            var columns = new Geometry.VertexTypes.VertexColumns();
+            var columns = new Geometry.VertexColumns();
 
             if (vertexAccessors.ContainsKey("POSITION")) columns.Positions = vertexAccessors["POSITION"].AsVector3Array();
             if (vertexAccessors.ContainsKey("NORMAL")) columns.Normals = vertexAccessors["NORMAL"].AsVector3Array();