Browse Source

improvements to animation pointer

vpenades 7 months ago
parent
commit
1211b5d272

+ 36 - 0
src/Shared/_Extensions.cs

@@ -204,6 +204,42 @@ namespace SharpGLTF
             if (comparison == StringComparison.Ordinal) return text.Replace(oldText, newText);
             throw new NotImplementedException();
         }
+
+        internal static int IndexOf(this string text, string value, StringComparison comparison)
+        {
+            switch(comparison)
+            {
+                case StringComparison.OrdinalIgnoreCase:
+                case StringComparison.InvariantCultureIgnoreCase:
+                    text = text.ToUpperInvariant();
+                    value = value.ToUpperInvariant();
+                    break;
+                case StringComparison.CurrentCultureIgnoreCase:
+                    text = text.ToUpper();
+                    value = value.ToUpper();
+                    break;                  
+            }
+
+            return text.IndexOf(value);
+        }
+
+        internal static int IndexOf(this string text, char value, StringComparison comparison)
+        {
+            switch (comparison)
+            {
+                case StringComparison.OrdinalIgnoreCase:
+                case StringComparison.InvariantCultureIgnoreCase:
+                    text = text.ToUpperInvariant();
+                    value = char.ToUpperInvariant(value);
+                    break;
+                case StringComparison.CurrentCultureIgnoreCase:
+                    text = text.ToUpper();
+                    value = char.ToUpper(value);
+                    break;
+            }
+
+            return text.IndexOf(value);
+        }
         #endif
 
         #endregion

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

@@ -80,9 +80,9 @@ namespace SharpGLTF.Schema2
         public string TargetPointerPath => this._target?.GetPointerPath() ?? null;
 
         /// <summary>
-        /// Gets the <see cref="Node"/> which property is to be bound with this animation.
-        /// </summary>
-        [Obsolete("Use TargetPointerPath whenever possible")]
+        /// Gets the <see cref="Node"/> which property is to be bound with this animation,
+        /// or NULL if the target is not a <see cref="Node"/>
+        /// </summary>        
         public Node TargetNode
         {
             get

+ 39 - 15
src/SharpGLTF.Core/Schema2/gltf.AnimationChannelTarget.cs

@@ -66,6 +66,11 @@ namespace SharpGLTF.Schema2
 
         #region API
 
+        /// <summary>
+        /// Gets the index of the <see cref="Node"/> pointed by this animation,
+        /// or -1 if it points to a target that is not a <see cref="Node"/>.
+        /// </summary>
+        /// <returns>A node index, or -1</returns>
         public int GetNodeIndex()
         {
             if (this._node != null) return this._node.Value;
@@ -73,12 +78,17 @@ namespace SharpGLTF.Schema2
             if (_NodePath == PropertyPath.pointer)
             {
                 var aptr = this.GetExtension<AnimationPointer>();
-                if (aptr != null && AnimationPointer.TryParseNodeTransform(aptr.Pointer, out var nidx, out _)) return nidx;
+                if (aptr != null && AnimationPointer.TryParseNodeIndex(aptr.Pointer, out var nidx)) return nidx;
             }
 
             return -1;
         }
 
+        /// <summary>
+        /// If the target is a node, it returns a <see cref="PropertyPath"/> resolved to <see cref="PropertyPath.scale"/>, <see cref="PropertyPath.rotation"/> or <see cref="PropertyPath.translation"/>
+        /// otherwise it will return <see cref="PropertyPath.pointer"/>
+        /// </summary>
+        /// <returns>A <see cref="PropertyPath"/> value.</returns>
         public PropertyPath GetNodePath()
         {
             if (_NodePath == PropertyPath.pointer)
@@ -90,6 +100,10 @@ namespace SharpGLTF.Schema2
             return _NodePath;
         }
 
+        /// <summary>
+        /// Returns a pointer path regardless of whether it's defined by default <see cref="PropertyPath"/> or by the animation pointer extension.
+        /// </summary>
+        /// <returns>An animation pointer path.</returns>
         public string GetPointerPath()
         {
             var aptr = this.GetExtension<AnimationPointer>();
@@ -153,35 +167,45 @@ namespace SharpGLTF.Schema2
         /// <summary>
         /// Parses the pointer path to see if it can be converted to a standard nodeIndex-PropertyPath path.
         /// </summary>
-        /// <param name="pointer">The path to try parse.</param>
+        /// <param name="pointerPath">The path to try parse.</param>
         /// <param name="nodeIndex">the logical index of the node.</param>
         /// <param name="property">the transformation property.</param>
         /// <returns>true if the parsing succeeded.</returns>
-        public static bool TryParseNodeTransform(string pointer, out int nodeIndex, out PropertyPath property)
+        public static bool TryParseNodeTransform(string pointerPath, out int nodeIndex, out PropertyPath property)
         {
-            nodeIndex = -1;
             property = PropertyPath.pointer;
 
-            if (pointer == null || !pointer.StartsWith("/nodes/")) return false;
-
+            if (!TryParseNodeIndex(pointerPath, out nodeIndex)) return false;
 
-            pointer = pointer.Substring(7);
-            var next = pointer.IndexOf('/');
+            pointerPath = pointerPath.Substring(7);
+            var next = pointerPath.IndexOf('/', StringComparison.Ordinal);
+            if (next < 0) return false;
 
-            if (!int.TryParse(pointer.Substring(0, next), System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out var idx)) return false;
-
-            var tail = pointer.Substring(next + 1);
+            var tail = pointerPath.Substring(next + 1);
             switch (tail)
             {
-                case "scale": nodeIndex = idx; property = PropertyPath.scale; return true;
-                case "rotation": nodeIndex = idx; property = PropertyPath.rotation; return true;
-                case "translation": nodeIndex = idx; property = PropertyPath.translation; return true;
-                case "weights": nodeIndex = idx; property = PropertyPath.weights; return true;
+                case "scale": property = PropertyPath.scale; return true;
+                case "rotation": property = PropertyPath.rotation; return true;
+                case "translation": property = PropertyPath.translation; return true;
+                case "weights": property = PropertyPath.weights; return true;
             }
 
             return false;
         }
 
+        public static bool TryParseNodeIndex(string pointerPath, out int nodeIndex)
+        {
+            nodeIndex = -1;           
+
+            if (pointerPath == null || !pointerPath.StartsWith("/nodes/")) return false;
+
+            pointerPath = pointerPath.Substring(7);
+            var next = pointerPath.IndexOf('/', StringComparison.Ordinal);
+            if (next < 0) next = pointerPath.Length;
+
+            return int.TryParse(pointerPath.Substring(0, next), System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out nodeIndex);
+        }
+
         #endregion
     }
 }

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

@@ -128,7 +128,7 @@ namespace SharpGLTF.Schema2
 
         #region API
 
-        private Accessor _CreateInputAccessor(IReadOnlyList<Single> input)
+        private Accessor _CreateInputAccessor(ROLIST input)
         {
             Guard.NotNull(input, nameof(input));
             Guard.MustBeGreaterThan(input.Count, 0, nameof(input.Count));
@@ -147,7 +147,7 @@ namespace SharpGLTF.Schema2
             return accessor;
         }
 
-        private Accessor _CreateOutputAccessor(IReadOnlyList<Single> output)
+        private Accessor _CreateOutputAccessor(ROLIST output)
         {
             Guard.NotNull(output, nameof(output));
             Guard.MustBeGreaterThan(output.Count, 0, nameof(output.Count));