瀏覽代碼

more API changes

Vicente Penades 6 年之前
父節點
當前提交
c213771ab7

+ 5 - 5
src/SharpGLTF.DOM/Geometry/MeshPrimitive.cs

@@ -74,22 +74,22 @@ namespace SharpGLTF.Geometry
 
         public void SetValues(int startIndex, params Single[] values)
         {
-            Memory.EncodedArrayUtils.CopyFrom(AsScalarArray(), startIndex, values);
+            Memory.EncodedArrayUtils.FillFrom(AsScalarArray(), startIndex, values);
         }
 
         public void SetValues(int startIndex, params Vector2[] values)
         {
-            Memory.EncodedArrayUtils.CopyFrom(AsVector2Array(), startIndex, values);
+            Memory.EncodedArrayUtils.FillFrom(AsVector2Array(), startIndex, values);
         }
 
         public void SetValues(int startIndex, params Vector3[] values)
         {
-            Memory.EncodedArrayUtils.CopyFrom(AsVector3Array(), startIndex, values);
+            Memory.EncodedArrayUtils.FillFrom(AsVector3Array(), startIndex, values);
         }
 
         public void SetValues(int startIndex, params Vector4[] values)
         {
-            Memory.EncodedArrayUtils.CopyFrom(AsVector4Array(), startIndex, values);
+            Memory.EncodedArrayUtils.FillFrom(AsVector4Array(), startIndex, values);
         }
 
         public Memory.IEncodedArray<Single> AsScalarArray()
@@ -173,7 +173,7 @@ namespace SharpGLTF.Geometry
 
         public void SetValues(int startIndex, params UInt32[] values)
         {
-            Memory.EncodedArrayUtils.CopyFrom(AsIntegerArray(), startIndex, values);
+            Memory.EncodedArrayUtils.FillFrom(AsIntegerArray(), startIndex, values);
         }
 
         public Memory.IEncodedArray<UInt32> AsIntegerArray()

+ 14 - 2
src/SharpGLTF.DOM/Memory/Arrays.cs

@@ -81,12 +81,24 @@ namespace SharpGLTF.Memory
             return array;
         }
 
-        public static void CopyFrom<T>(this IEncodedArray<T> dst, int index, params T[] src)
+        public static void FillFrom<T>(this IEncodedArray<T> dst, int dstIndex, IEnumerable<T> src)
+            where T : unmanaged
+        {
+            using (var ator = src.GetEnumerator())
+            {
+                while (dstIndex < dst.Count && ator.MoveNext())
+                {
+                    dst[dstIndex++] = ator.Current;
+                }
+            }
+        }
+
+        public static void FillFrom<T>(this IEncodedArray<T> dst, int dstIndex, params T[] src)
             where T : unmanaged
         {
             for (int i = 0; i < src.Length; ++i)
             {
-                dst[index + i] = src[i];
+                dst[dstIndex + i] = src[i];
             }
         }
 

+ 4 - 4
src/SharpGLTF.DOM/Schema2/gltf.Accessors.cs

@@ -107,7 +107,7 @@ namespace SharpGLTF.Schema2
             this._componentType = encoding;
             this._normalized = normalized.AsNullable(false);
 
-            _UpdateBounds();
+            UpdateBounds();
         }
 
         public Memory.Matrix4x4Array AsMatrix4x4Array()
@@ -142,7 +142,7 @@ namespace SharpGLTF.Schema2
             this._componentType = encoding.ToComponent();
             this._normalized = null;
 
-            _UpdateBounds();
+            UpdateBounds();
         }
 
         public Memory.IntegerArray AsIndicesArray()
@@ -180,7 +180,7 @@ namespace SharpGLTF.Schema2
             this._componentType = encoding;
             this._normalized = normalized.AsNullable(false);
 
-            _UpdateBounds();
+            UpdateBounds();
         }
 
         public Memory.IEncodedArray<Single> AsScalarArray()
@@ -234,7 +234,7 @@ namespace SharpGLTF.Schema2
             return SourceBufferView.Content.Slice(this.ByteOffset + (vertexIdx * byteStride), byteSize);
         }
 
-        internal void _UpdateBounds()
+        public void UpdateBounds()
         {
             var count = this._type.DimCount();
 

+ 137 - 0
tests/SharpGLTF.Tests/BufferBuilder.cs

@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.Numerics;
+using System.Text;
+
+namespace SharpGLTF
+{
+    using Memory;
+    using System.Linq;
+    using COLOR = UInt32;
+
+    class BufferBuilder
+    {
+        #region data
+
+        private readonly VertexColumn<Vector3> _Positions = new VertexColumn<Vector3>();        
+        private readonly Dictionary<COLOR, List<int>> _Indices = new Dictionary<COLOR, List<int>>();        
+
+        #endregion
+
+        #region API        
+
+        public void AddTriangle(COLOR color, Vector3 a, Vector3 b, Vector3 c)
+        {
+            var aa = _Positions.Use(a);
+            var bb = _Positions.Use(b);
+            var cc = _Positions.Use(c);
+
+            // check for degenerated triangles:
+            if (aa == bb) return;
+            if (aa == cc) return;
+            if (bb == cc) return;
+
+            if (!_Indices.TryGetValue(color, out List<int> indices))
+            {
+                indices = new List<int>();
+                _Indices[color] = indices;
+            }
+
+            indices.Add(aa);
+            indices.Add(bb);
+            indices.Add(cc);
+        }
+
+        public void AddPolygon(COLOR color, params Vector3[] points)
+        {
+            for(int i=2; i < points.Length; ++i)
+            {
+                AddTriangle(color, points[0], points[i - 1], points[i]);
+            }
+        }
+
+        public Schema2.ModelRoot ToModel()
+        {
+            var root = Schema2.ModelRoot.CreateModel();
+
+            var node = root.UseScene(0).AddVisualNode("Default");
+
+            node.Mesh = root.CreateMesh();
+
+            const int byteStride = 12 * 2;
+
+            var vbuffer = root.CreateBuffer(_Positions.Count * byteStride);
+            var vview = root.CreateBufferView(vbuffer, null, null, byteStride, Schema2.BufferMode.ARRAY_BUFFER);
+
+            var vpositions = root.CreateAccessor("Positions");
+            vpositions.SetVertexData(vview, 0, Schema2.ElementType.VEC3, Schema2.ComponentType.FLOAT, false, _Positions.Count);            
+            vpositions.AsVector3Array().FillFrom(0, _Positions.ToArray());
+            vpositions.UpdateBounds();
+
+            var vnormals = root.CreateAccessor("Normals");
+            vnormals.SetVertexData(vview, 12, Schema2.ElementType.VEC3, Schema2.ComponentType.FLOAT, false, _Positions.Count);            
+            vnormals.AsVector3Array().FillFrom(0, _CalculateNormals());
+            vnormals.UpdateBounds();
+
+            foreach (var kvp in _Indices)
+            {
+                var color = new Vector4((kvp.Key >> 24) & 255, (kvp.Key >> 16) & 255, (kvp.Key >> 8) & 255, (kvp.Key) & 255) / 255.0f;                
+
+                var prim = node.Mesh.CreatePrimitive();
+                prim.Material = root.CreateMaterial().InitializeDefault(color);
+                prim.DrawPrimitiveType = Schema2.PrimitiveType.TRIANGLES;
+                
+                prim.SetVertexAccessor("POSITION", vpositions);
+                prim.SetVertexAccessor("NORMAL", vnormals);                
+
+                var ibuffer = root.CreateBuffer(kvp.Value.Count * 4);
+                var iview = root.CreateBufferView(ibuffer, null, null, null, Schema2.BufferMode.ELEMENT_ARRAY_BUFFER);
+                var indices = root.CreateAccessor("Indices");
+                indices.AsIndicesArray().FillFrom(0, kvp.Value.Select(item => (uint)item));
+
+                indices.SetIndexData(iview, 0, Schema2.IndexType.UNSIGNED_INT, kvp.Value.Count);
+                prim.IndexAccessor = indices;
+            }
+
+            root.MergeBuffers();
+
+            return root;
+        }
+
+        private Vector3[] _CalculateNormals()
+        {
+            var normals = new Vector3[_Positions.Count];
+
+            foreach(var prim in _Indices.Values)
+            {
+                for(int i=0; i < prim.Count; i+=3)
+                {
+                    var a = prim[i + 0];
+                    var b = prim[i + 1];
+                    var c = prim[i + 2];
+
+                    var aa = _Positions[a];
+                    var bb = _Positions[b];
+                    var cc = _Positions[c];
+
+                    var n = Vector3.Cross(bb - aa, cc - aa);
+
+                    normals[a] += n;
+                    normals[b] += n;
+                    normals[c] += n;
+                }
+            }
+
+            for(int i=0; i < normals.Length; ++i)
+            {
+                normals[i] = normals[i].Length() <= float.Epsilon ? Vector3.UnitX : Vector3.Normalize(normals[i]);
+            }
+
+            return normals;
+        }
+
+        #endregion
+    }
+
+    
+}