Browse Source

Code clenaup

vpenades 2 years ago
parent
commit
0811ab7f1b

+ 1 - 1
src/Shared/Guard.cs

@@ -245,7 +245,7 @@ namespace SharpGLTF
 
             if (gltfURI.Any(c => _InvalidRelativePathChars.Contains(c))) throw new ArgumentException($"Invalid URI '{gltfURI}'.");
 
-            if (gltfURI.Any(chr => char.IsWhiteSpace(chr))) gltfURI = Uri.EscapeUriString(gltfURI);
+            if (gltfURI.Any(chr => char.IsWhiteSpace(chr))) gltfURI = gltfURI._EscapeStringInternal();
 
             if (!Uri.TryCreate(gltfURI, UriKind.Relative, out Uri xuri)) throw new ArgumentException($"Invalid URI '{gltfURI}'.");
 

+ 46 - 9
src/Shared/_Extensions.cs

@@ -191,6 +191,23 @@ namespace SharpGLTF
 
         #endregion
 
+        #region string extensions
+
+        #if NETSTANDARD2_0
+        internal static bool StartsWith(this string text, char c)
+        {
+            return text.StartsWith(c.ToString());
+        }
+
+        internal static string Replace(this string text, string oldText, string newText, StringComparison comparison)
+        {
+            if (comparison == StringComparison.Ordinal) return text.Replace(oldText, newText);
+            throw new NotImplementedException();
+        }
+        #endif
+
+        #endregion
+
         #region linq
 
         public static bool AreSameReference<T>(this (T x, T y) refs, out bool result)
@@ -312,6 +329,18 @@ namespace SharpGLTF
             }
         }
 
+        internal static IReadOnlyList<T> EnsureList<T>(this IEnumerable<T> collection)
+        {
+            return collection is IReadOnlyList<T> list
+                ? list
+                : collection.ToList();
+        }
+
+        internal static bool IsEmpty<T>(this IReadOnlyList<T> list)
+        {
+            return list.Count == 0;
+        }
+
         internal static int IndexOf<T>(this IReadOnlyList<T> collection, T value)
         {
             var l = collection.Count;
@@ -563,7 +592,7 @@ namespace SharpGLTF
                                 if (!ptr.MoveNext()) break;
                                 var b = ptr.Current;
 
-                                if (!_IsDegenerated(a, b)) yield return ((int)a, (int)b);
+                                if (!_IsDegeneratedSegment(a, b)) yield return ((int)a, (int)b);
                             }
                         }
 
@@ -591,7 +620,7 @@ namespace SharpGLTF
                                 if (!ptr.MoveNext()) break;
                                 var c = ptr.Current;
 
-                                if (!_IsDegenerated(a, b, c)) yield return ((int)a, (int)b, (int)c);
+                                if (!_IsDegeneratedTriangle(a, b, c)) yield return ((int)a, (int)b, (int)c);
                             }
                         }
 
@@ -612,7 +641,7 @@ namespace SharpGLTF
                                 if (!ptr.MoveNext()) break;
                                 var c = ptr.Current;
 
-                                if (!_IsDegenerated(a, b, c)) yield return ((int)a, (int)b, (int)c);
+                                if (!_IsDegeneratedTriangle(a, b, c)) yield return ((int)a, (int)b, (int)c);
 
                                 b = c;
                             }
@@ -637,7 +666,7 @@ namespace SharpGLTF
                                 if (!ptr.MoveNext()) break;
                                 var c = ptr.Current;
 
-                                if (!_IsDegenerated(a, b, c))
+                                if (!_IsDegeneratedTriangle(a, b, c))
                                 {
                                     if (reversed) yield return ((int)b, (int)a, (int)c);
                                     else yield return ((int)a, (int)b, (int)c);
@@ -656,12 +685,12 @@ namespace SharpGLTF
             }
         }
 
-        private static bool _IsDegenerated(uint a, uint b)
+        private static bool _IsDegeneratedSegment(uint a, uint b)
         {
             return a == b;
         }
 
-        private static bool _IsDegenerated(uint a, uint b, uint c)
+        private static bool _IsDegeneratedTriangle(uint a, uint b, uint c)
         {
             if (a == b) return true;
             if (a == c) return true;
@@ -727,9 +756,9 @@ namespace SharpGLTF
                 return Convert.FromBase64String(content);
             }
 
-            if (content.StartsWith(",", StringComparison.OrdinalIgnoreCase))
+            if (content.StartsWith(','))
             {
-                content = content.Substring(",".Length);
+                content = content.Substring(1);
 
                 if (content.Length == 1) return new Byte[] { Byte.Parse(content, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture) };
 
@@ -741,7 +770,15 @@ namespace SharpGLTF
 
         #endregion
 
-        #region json        
+        #region json
+
+        public static string _EscapeStringInternal(this string uri)
+        {
+            // https://stackoverflow.com/questions/4396598/whats-the-difference-between-escapeuristring-and-escapedatastring
+            #pragma warning disable SYSLIB0013 // Type or member is obsolete
+            return Uri.EscapeUriString(uri);
+            #pragma warning restore SYSLIB0013 // Type or member is obsolete
+        }
 
         #if NET6_0
 

+ 18 - 6
src/SharpGLTF.Core/Animations/CurveSampler.cs

@@ -152,6 +152,8 @@ namespace SharpGLTF.Animations
         {
             Guard.NotNull(sequence, nameof(sequence));
 
+            sequence = sequence.EnsureList();
+
             if (!sequence.Any()) return (default(T), default(T), 0);
 
             (float Key, T Value)? left = null;
@@ -172,7 +174,7 @@ namespace SharpGLTF.Animations
 
                 if (item.Key > offset)
                 {
-                    if (left == null) left = prev;
+                    left ??= prev;
                     right = item;
                     break;
                 }
@@ -213,6 +215,8 @@ namespace SharpGLTF.Animations
         {
             Guard.NotNull(sequence, nameof(sequence));
 
+            sequence = sequence.EnsureList();
+
             if (!sequence.Any()) return (0, 0, 0);
 
             float? left = null;
@@ -233,7 +237,7 @@ namespace SharpGLTF.Animations
 
                 if (item > offset)
                 {
-                    if (left == null) left = prev;
+                    left ??= prev;
                     right = item;
                     break;
                 }
@@ -274,15 +278,23 @@ namespace SharpGLTF.Animations
         /// <returns>A sequence of 1 second chunks.</returns>
         internal static IEnumerable<(float, T)[]> SplitByTime<T>(this IEnumerable<(Single Time, T Value)> sequence)
         {
-            if (!sequence.Any()) yield break;
+            List<(float, T)> segment = null;
 
-            var segment = new List<(float, T)>();
             int time = 0;
+            
+            (Single Time, T Value) last = default;
 
-            var last = sequence.First();
+            bool isFirst = true;
 
             foreach (var item in sequence)
             {
+                if (isFirst)
+                {
+                    last = item;
+                    segment ??= new List<(float, T)>();
+                    isFirst = false;
+                }
+
                 var t = (int)item.Time;
 
                 if (time > t) throw new InvalidOperationException("unexpected data encountered.");
@@ -307,7 +319,7 @@ namespace SharpGLTF.Animations
                 last = item;
             }
 
-            if (segment.Count > 0) yield return segment.ToArray();
+            if (segment != null && segment.Count > 0) yield return segment.ToArray();
         }
 
         #endregion

+ 1 - 3
src/SharpGLTF.Core/Animations/CurveSamplers.Fixed.cs

@@ -17,13 +17,11 @@ namespace SharpGLTF.Animations
 
         public static ICurveSampler<T> Create(IEnumerable<(float Key, T Value)> sequence)
         {
-            System.Diagnostics.Debug.Assert(!sequence.Skip(1).Any());
             return new FixedSampler<T>(sequence.First().Value);
         }
 
         public static ICurveSampler<T> Create(IEnumerable<(float Key, (T, T, T) Value)> sequence)
-        {
-            System.Diagnostics.Debug.Assert(!sequence.Skip(1).Any());
+        {            
             return new FixedSampler<T>(sequence.First().Value.Item2);
         }
 

+ 3 - 2
src/SharpGLTF.Core/Diagnostics/DebuggerDisplay.cs

@@ -86,11 +86,12 @@ namespace SharpGLTF.Diagnostics
 
             var vcounts = prim.VertexAccessors.Values
                 .Select(item => item.Count)
-                .Distinct();
+                .Distinct()
+                .ToList();
 
             var vcount = vcounts.First();
 
-            if (vcounts.Count() > 1)
+            if (vcounts.Count > 1)
             {
                 var vAccessors = prim.VertexAccessors
                     .OrderBy(item => item.Key, Memory.MemoryAccessInfo.NameComparer)

+ 1 - 1
src/SharpGLTF.Core/Memory/MemoryAccessor.Validation.cs

@@ -186,7 +186,7 @@ namespace SharpGLTF.Memory
 
             if (weights0 == null) throw new ArgumentNullException(nameof(weights0));
 
-            if (weights0.Attribute.Encoding != weights1.Attribute.Encoding) throw new ArgumentException("WEIGHTS_0 and WEIGHTS_1 format mismatch.", nameof(weights1.Attribute));
+            if (weights0.Attribute.Encoding != weights1.Attribute.Encoding) throw new ArgumentException("WEIGHTS_0 and WEIGHTS_1 format mismatch.", nameof(weights1));
 
             var len = weights0.Attribute.ItemByteLength;
             Span<Byte> dst = stackalloc byte[len * 2];

+ 1 - 1
src/SharpGLTF.Core/Schema2/gltf.Buffer.cs

@@ -70,7 +70,7 @@ namespace SharpGLTF.Schema2
         {
             writer.WriteAllBytesToEnd(satelliteUri, new ArraySegment<byte>(_Content.GetPaddedContent()));
 
-            this._uri = Uri.EscapeUriString(satelliteUri);
+            this._uri = satelliteUri._EscapeStringInternal();
             this._byteLength = _Content.Length;
         }
 

+ 9 - 5
src/SharpGLTF.Core/Schema2/gltf.BufferView.cs

@@ -144,12 +144,16 @@ namespace SharpGLTF.Schema2
         /// <returns>true if the buffer is interleaved</returns>
         public bool IsInterleaved(IEnumerable<Accessor> accessors)
         {
-            Guard.NotNullOrEmpty(accessors, nameof(accessors));
-            Guard.IsTrue(accessors.All(item => item.SourceBufferView == this), nameof(accessors));
+            Guard.NotNullOrEmpty(accessors, nameof(accessors));            
 
-            return accessors
-                .Select(item => item.ByteOffset)
-                .All(o => o < this.ByteStride);
+            foreach(var accessor in accessors)
+            {
+                Guard.NotNull(accessor, nameof(accessor));
+                Guard.IsTrue(accessor.SourceBufferView == this, nameof(accessors));
+                if (accessor.ByteOffset >= this.ByteStride) return false;
+            }
+
+            return true;
         }
 
         internal static bool AreEqual(BufferView bv, BYTES content, int byteStride, BufferMode? target)

+ 3 - 4
src/SharpGLTF.Core/Schema2/gltf.ExtraProperties.cs

@@ -8,7 +8,6 @@ using SharpGLTF.IO;
 
 using JsonToken = System.Text.Json.JsonTokenType;
 
-// using JSONEXTRAS = SharpGLTF.IO.JsonContent;
 using JSONEXTRAS = System.Text.Json.Nodes.JsonNode;
 
 namespace SharpGLTF.Schema2
@@ -192,7 +191,7 @@ namespace SharpGLTF.Schema2
             SerializeProperty(writer, "extras", content);
         }
 
-        private static IReadOnlyDictionary<string, JsonSerializable> _ToDictionary(JsonSerializable context, IEnumerable<JsonSerializable> serializables)
+        private static Dictionary<string, JsonSerializable> _ToDictionary(JsonSerializable context, IEnumerable<JsonSerializable> serializables)
         {
             var dict = new Dictionary<string, JsonSerializable>();
 
@@ -227,7 +226,7 @@ namespace SharpGLTF.Schema2
 
                 case "extras":
                     {
-                        var content = System.Text.Json.Nodes.JsonNode.Parse(ref reader);
+                        var content = JSONEXTRAS.Parse(ref reader);
                         _extras = content;
                         break;
                     }
@@ -236,7 +235,7 @@ namespace SharpGLTF.Schema2
             }
         }
 
-        private static void _DeserializeExtensions(JsonSerializable parent, ref Utf8JsonReader reader, IList<JsonSerializable> extensions)
+        private static void _DeserializeExtensions(JsonSerializable parent, ref Utf8JsonReader reader, List<JsonSerializable> extensions)
         {
             reader.Read();
 

+ 2 - 2
src/SharpGLTF.Core/Schema2/gltf.Images.cs

@@ -234,8 +234,8 @@ namespace SharpGLTF.Schema2
 
             satelliteUri = writer.WriteImage(satelliteUri, imimg);
 
-            satelliteUri = satelliteUri.Replace("\\", "/");
-            _uri = Uri.EscapeUriString(satelliteUri);
+            satelliteUri = satelliteUri.Replace("\\", "/", StringComparison.Ordinal);
+            _uri = satelliteUri._EscapeStringInternal();
             _mimeType = null;
         }
 

+ 1 - 1
src/SharpGLTF.Core/Schema2/gltf.LogicalChildOfRoot.cs

@@ -100,7 +100,7 @@ namespace SharpGLTF.Schema2
             }
         }
 
-        private bool RenameIfAvailable(string newName, ISet<string> usedNames)
+        private bool RenameIfAvailable(string newName, HashSet<string> usedNames)
         {
             if (usedNames.Contains(newName)) return false;
             this.Name = newName;

+ 6 - 5
src/SharpGLTF.Core/Schema2/gltf.MaterialChannel.cs

@@ -15,7 +15,7 @@ namespace SharpGLTF.Schema2
     /// to have an homogeneous and easy to use API.
     /// </remarks>
     [System.Diagnostics.DebuggerDisplay("Channel {_Key}")]
-    public readonly struct MaterialChannel
+    public readonly struct MaterialChannel : IEquatable<MaterialChannel>
     {
         #region lifecycle
 
@@ -49,16 +49,14 @@ namespace SharpGLTF.Schema2
 
         [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
         private readonly IReadOnlyList<IMaterialParameter> _Parameters;
-
-        /// <inheritdoc />
+        
         public override int GetHashCode()
         {
             if (_Material == null) return 0;
 
             return _Material.GetHashCode() ^ _Key.GetHashCode(StringComparison.InvariantCulture);
         }
-
-        /// <inheritdoc />
+        
         public override bool Equals(object obj) { return obj is MaterialChannel other && Equals(other); }
 
         public bool Equals(MaterialChannel other)
@@ -69,6 +67,9 @@ namespace SharpGLTF.Schema2
             return true;
         }
 
+        public static bool operator ==(in MaterialChannel a, in MaterialChannel b) { return a.Equals(b); }
+        public static bool operator !=(in MaterialChannel a, in MaterialChannel b) { return !a.Equals(b); }
+
         #endregion
 
         #region properties

+ 3 - 2
src/SharpGLTF.Core/Schema2/gltf.MeshPrimitive.cs

@@ -429,10 +429,11 @@ namespace SharpGLTF.Schema2
                 .Where(item => item.Mesh == this.LogicalParent)
                 .Select(item => item.Skin)
                 .Where(item => item != null)
-                .Select(item => item.JointsCount);
+                .Select(item => item.JointsCount)
+                .ToList();            
 
             // if no skins found, use a max joint value that essentially skips max joint validation
-            var maxJoints = skins.Any() ? skins.Max() : int.MaxValue;
+            var maxJoints = skins.Count != 0 ? skins.Max() : int.MaxValue;
 
             Accessor.ValidateVertexAttributes(validate, this.VertexAccessors, maxJoints);
         }

+ 5 - 5
src/SharpGLTF.Core/Schema2/gltf.Skin.cs

@@ -223,19 +223,19 @@ namespace SharpGLTF.Schema2
         {
             if (nodes == null) return null;
 
+            nodes = nodes.EnsureList();
+
             foreach (var j in nodes)
             {
                 Guard.NotNull(j, nameof(nodes));
                 Guard.MustShareLogicalParent(this, j, nameof(nodes));
-            }
-
-            var workingNodes = nodes.ToList();
+            }            
 
-            var rootJoint = workingNodes.First();
+            var rootJoint = nodes.First();
 
             while (true)
             {
-                if (workingNodes.All(j => rootJoint == j || rootJoint._ContainsVisualNode(j, true))) return rootJoint;
+                if (nodes.All(j => rootJoint == j || rootJoint._ContainsVisualNode(j, true))) return rootJoint;
 
                 if (rootJoint.VisualParent == null) break;