|
|
@@ -7,7 +7,7 @@ using System.Text;
|
|
|
namespace SharpGLTF.Transforms
|
|
|
{
|
|
|
/// <summary>
|
|
|
- /// Represents a sparse collection of weight values, with a maximum of 8 weights.
|
|
|
+ /// Represents a sparse collection of non zero weight values, with a maximum of 8 weights.
|
|
|
/// </summary>
|
|
|
[System.Diagnostics.DebuggerDisplay("[{Index0}]={Weight0} [{Index1}]={Weight1} [{Index2}]={Weight2} [{Index3}]={Weight3} [{Index4}]={Weight4} [{Index5}]={Weight5} [{Index6}]={Weight6} [{Index7}]={Weight7}")]
|
|
|
public struct SparseWeight8 : IReadOnlyList<float>, IReadOnlyDictionary<int, float>
|
|
|
@@ -25,7 +25,7 @@ namespace SharpGLTF.Transforms
|
|
|
|
|
|
var indexedWeights = weights
|
|
|
.Select((val, idx) => (idx, val))
|
|
|
- .Where(item => item.val > 0)
|
|
|
+ .Where(item => item.val != 0)
|
|
|
.OrderByDescending(item => item.val)
|
|
|
.Take(8)
|
|
|
.ToArray();
|
|
|
@@ -101,6 +101,42 @@ namespace SharpGLTF.Transforms
|
|
|
public float Weight6;
|
|
|
public float Weight7;
|
|
|
|
|
|
+ public static bool AreWeightsEqual(in SparseWeight8 x, in SparseWeight8 y)
|
|
|
+ {
|
|
|
+ Span<int> indices = stackalloc int[16];
|
|
|
+ Span<float> xWeights = stackalloc float[16];
|
|
|
+ Span<float> yWeights = stackalloc float[16];
|
|
|
+
|
|
|
+ int c = 0;
|
|
|
+ c = CopyTo(x, indices, xWeights, c);
|
|
|
+ c = CopyTo(y, indices, yWeights, c);
|
|
|
+
|
|
|
+ xWeights = xWeights.Slice(0, c);
|
|
|
+ yWeights = yWeights.Slice(0, c);
|
|
|
+
|
|
|
+ return xWeights.SequenceEqual(yWeights);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int GetWeightsHashCode()
|
|
|
+ {
|
|
|
+ Span<int> indices = stackalloc int[8];
|
|
|
+ Span<float> weights = stackalloc float[8];
|
|
|
+
|
|
|
+ var c = CopyTo(this, indices, weights, 0);
|
|
|
+
|
|
|
+ BubbleSortByIndex(indices, weights, c);
|
|
|
+
|
|
|
+ int h = 0;
|
|
|
+
|
|
|
+ for (int i = 0; i < c; ++i)
|
|
|
+ {
|
|
|
+ h += indices[i].GetHashCode() ^ weights[i].GetHashCode();
|
|
|
+ h *= 17;
|
|
|
+ }
|
|
|
+
|
|
|
+ return h;
|
|
|
+ }
|
|
|
+
|
|
|
#endregion
|
|
|
|
|
|
#region properties
|
|
|
@@ -121,89 +157,96 @@ namespace SharpGLTF.Transforms
|
|
|
|
|
|
#region API
|
|
|
|
|
|
- public static SparseWeight8 InterpolateLinear(SparseWeight8 x, SparseWeight8 y, float amount)
|
|
|
+ public static SparseWeight8 Add(in SparseWeight8 x, in SparseWeight8 y)
|
|
|
{
|
|
|
- Span<int> indices = stackalloc int[16];
|
|
|
- Span<float> xWeights = stackalloc float[16];
|
|
|
- Span<float> yWeights = stackalloc float[16];
|
|
|
-
|
|
|
- int offset = 0;
|
|
|
- offset = CopyTo(x, indices, xWeights, offset);
|
|
|
- offset = CopyTo(y, indices, yWeights, offset);
|
|
|
+ return _OperateLinear(x, y, (xx, yy) => xx + yy);
|
|
|
+ }
|
|
|
|
|
|
- indices = indices.Slice(0, offset);
|
|
|
- xWeights = xWeights.Slice(0, offset);
|
|
|
- yWeights = yWeights.Slice(0, offset);
|
|
|
+ public static SparseWeight8 Subtract(in SparseWeight8 x, in SparseWeight8 y)
|
|
|
+ {
|
|
|
+ return _OperateLinear(x, y, (xx, yy) => xx - yy);
|
|
|
+ }
|
|
|
|
|
|
- var invAmount = 1.0f - amount;
|
|
|
+ public static SparseWeight8 Multiply(in SparseWeight8 x, in SparseWeight8 y)
|
|
|
+ {
|
|
|
+ return _OperateLinear(x, y, (xx, yy) => xx * yy);
|
|
|
+ }
|
|
|
|
|
|
- for (int i = 0; i < indices.Length; ++i)
|
|
|
- {
|
|
|
- xWeights[i] = (xWeights[i] * invAmount) + (yWeights[i] * amount);
|
|
|
- }
|
|
|
+ public static SparseWeight8 Divide(in SparseWeight8 x, in SparseWeight8 y)
|
|
|
+ {
|
|
|
+ return _OperateLinear(x, y, (xx, yy) => xx / yy);
|
|
|
+ }
|
|
|
|
|
|
- BubbleSort(indices, xWeights);
|
|
|
+ public static SparseWeight8 InterpolateLinear(SparseWeight8 x, SparseWeight8 y, float amount)
|
|
|
+ {
|
|
|
+ var xAmount = 1.0f - amount;
|
|
|
+ var yAmount = amount;
|
|
|
|
|
|
- return new SparseWeight8(indices, xWeights);
|
|
|
+ return _OperateLinear(x, y, (xx, yy) => (xx * xAmount) + (yy * yAmount));
|
|
|
}
|
|
|
|
|
|
public static SparseWeight8 InterpolateCubic(SparseWeight8 x, SparseWeight8 xt, SparseWeight8 y, SparseWeight8 yt, float amount)
|
|
|
{
|
|
|
- Span<int> indices = stackalloc int[16];
|
|
|
- Span<float> xWeights = stackalloc float[16];
|
|
|
- Span<float> xTangent = stackalloc float[16];
|
|
|
- Span<float> yWeights = stackalloc float[16];
|
|
|
- Span<float> yTangent = stackalloc float[16];
|
|
|
-
|
|
|
- int offset = 0;
|
|
|
- offset = CopyTo(x, xt, indices, xWeights, xTangent, offset);
|
|
|
- offset = CopyTo(y, yt, indices, yWeights, yTangent, offset);
|
|
|
-
|
|
|
- indices = indices.Slice(0, offset);
|
|
|
- xWeights = xWeights.Slice(0, offset);
|
|
|
- xTangent = xWeights.Slice(0, offset);
|
|
|
- yWeights = yWeights.Slice(0, offset);
|
|
|
- yTangent = yTangent.Slice(0, offset);
|
|
|
-
|
|
|
var basis = Animations.SamplerFactory.CreateHermitePointWeights(amount);
|
|
|
|
|
|
- for (int i = 0; i < indices.Length; ++i)
|
|
|
+ return _OperateCubic(x, xt, y, yt, (xx, xxt, yy, yyt) => (xx * basis.Item1) + (yy * basis.Item2) + (xxt * basis.Item3) + (yyt * basis.Item4));
|
|
|
+ }
|
|
|
+
|
|
|
+ public IEnumerable<float> Expand(int count)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < count; ++i)
|
|
|
{
|
|
|
- xWeights[i]
|
|
|
- = (xWeights[i] * basis.Item1)
|
|
|
- + (yWeights[i] * basis.Item2)
|
|
|
- + (xTangent[i] * basis.Item3)
|
|
|
- + (yTangent[i] * basis.Item4);
|
|
|
+ yield return GetExpandedAt(i);
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ public IEnumerator<float> GetEnumerator() { return Expand(GetExpandedCount()).GetEnumerator(); }
|
|
|
|
|
|
- BubbleSort(indices, xWeights);
|
|
|
+ IEnumerator IEnumerable.GetEnumerator() { return Expand(GetExpandedCount()).GetEnumerator(); }
|
|
|
|
|
|
- return new SparseWeight8(indices, xWeights);
|
|
|
+ public bool ContainsKey(int key)
|
|
|
+ {
|
|
|
+ return GetPairs().Select(item => item.Item1).Contains(key);
|
|
|
}
|
|
|
|
|
|
- private static int CopyTo(SparseWeight8 p, SparseWeight8 t, Span<int> indices, Span<float> weights, Span<float> tangent, int offset)
|
|
|
+ public bool TryGetValue(int key, out float value)
|
|
|
{
|
|
|
- System.Diagnostics.Debug.Assert(indices.Length == weights.Length);
|
|
|
- System.Diagnostics.Debug.Assert(indices.Length == tangent.Length);
|
|
|
+ if (key == Index0) { value = Weight0; return true; }
|
|
|
+ if (key == Index1) { value = Weight1; return true; }
|
|
|
+ if (key == Index2) { value = Weight2; return true; }
|
|
|
+ if (key == Index3) { value = Weight3; return true; }
|
|
|
+ if (key == Index4) { value = Weight4; return true; }
|
|
|
+ if (key == Index5) { value = Weight5; return true; }
|
|
|
+ if (key == Index6) { value = Weight6; return true; }
|
|
|
+ if (key == Index7) { value = Weight7; return true; }
|
|
|
+ value = 0;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- for (int i = 0; i < 8; ++i)
|
|
|
- {
|
|
|
- var pair = p.GetPair(i);
|
|
|
- if (pair.Item2 == 0) continue;
|
|
|
- var idx = indices.Slice(0, offset).IndexOf(pair.Item1);
|
|
|
+ IEnumerator<KeyValuePair<int, float>> IEnumerable<KeyValuePair<int, float>>.GetEnumerator()
|
|
|
+ {
|
|
|
+ return GetPairs().Select(item => new KeyValuePair<int, float>(item.Item1, item.Item2)).GetEnumerator();
|
|
|
+ }
|
|
|
|
|
|
- if (idx < 0)
|
|
|
- {
|
|
|
- indices[offset] = pair.Item1;
|
|
|
- weights[offset] = pair.Item2;
|
|
|
- tangent[offset] = t[pair.Item1];
|
|
|
- ++offset;
|
|
|
- }
|
|
|
+ public override string ToString()
|
|
|
+ {
|
|
|
+ var sb = new StringBuilder();
|
|
|
+
|
|
|
+ int c = this.Count;
|
|
|
+
|
|
|
+ for (int i = 0; i < c; ++i)
|
|
|
+ {
|
|
|
+ if (sb.Length > 0) sb.Append(" ");
|
|
|
+ sb.Append(this[i]);
|
|
|
}
|
|
|
|
|
|
- return offset;
|
|
|
+ return sb.ToString();
|
|
|
}
|
|
|
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region code
|
|
|
+
|
|
|
private static int CopyTo(SparseWeight8 p, Span<int> indices, Span<float> weights, int offset)
|
|
|
{
|
|
|
System.Diagnostics.Debug.Assert(indices.Length == weights.Length);
|
|
|
@@ -224,73 +267,160 @@ namespace SharpGLTF.Transforms
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- weights[idx] = pair.Item2;
|
|
|
+ weights[idx] = pair.Item2; // should perform ADD (in case there's more than one element?)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return offset;
|
|
|
}
|
|
|
|
|
|
- private static void BubbleSort(Span<int> indices, Span<float> weights)
|
|
|
+ /// <summary>
|
|
|
+ /// Performs <paramref name="operationFunc"/> over all the elements of the operands.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="x">The first <see cref="SparseWeight8"/> operand.</param>
|
|
|
+ /// <param name="y">The second <see cref="SparseWeight8"/> operand.</param>
|
|
|
+ /// <param name="operationFunc">The operator function to apply to every element.</param>
|
|
|
+ /// <returns>A new <see cref="SparseWeight8"/>.</returns>
|
|
|
+ private static SparseWeight8 _OperateLinear(in SparseWeight8 x, in SparseWeight8 y, Func<float, float, float> operationFunc)
|
|
|
{
|
|
|
- System.Diagnostics.Debug.Assert(indices.Length == weights.Length);
|
|
|
+ // prepare buffers in the stack
|
|
|
+ Span<int> indices = stackalloc int[16];
|
|
|
+ Span<float> xxx = stackalloc float[16];
|
|
|
+ Span<float> yyy = stackalloc float[16];
|
|
|
|
|
|
- for (int i = 0; i < weights.Length - 1; ++i)
|
|
|
+ // fill the buffers so all the elements are aligned by column
|
|
|
+ int offset = 0;
|
|
|
+ offset = CopyTo(x, indices, xxx, offset);
|
|
|
+ offset = CopyTo(y, indices, yyy, offset);
|
|
|
+
|
|
|
+ // perform operation element by element
|
|
|
+ for (int i = 0; i < offset; ++i)
|
|
|
{
|
|
|
- for (int j = i + 1; j < weights.Length; ++j)
|
|
|
- {
|
|
|
- if (weights[j - 1] < weights[j])
|
|
|
- {
|
|
|
- var index = indices[j - 1];
|
|
|
- indices[j - 1] = indices[j];
|
|
|
- indices[j] = index;
|
|
|
-
|
|
|
- var weight = weights[j - 1];
|
|
|
- weights[j - 1] = weights[j];
|
|
|
- weights[j] = weight;
|
|
|
- }
|
|
|
- }
|
|
|
+ xxx[i] = operationFunc(xxx[i], yyy[i]);
|
|
|
}
|
|
|
+
|
|
|
+ // sort results by relevance, so they can fit
|
|
|
+ // in a new structure in case there's more than
|
|
|
+ // 8 results
|
|
|
+
|
|
|
+ indices = indices.Slice(0, offset);
|
|
|
+ xxx = xxx.Slice(0, offset);
|
|
|
+
|
|
|
+ BubbleSortByWeight(indices, xxx, offset);
|
|
|
+
|
|
|
+ return new SparseWeight8(indices, xxx);
|
|
|
}
|
|
|
|
|
|
- internal IEnumerable<(int, float)> GetPairs()
|
|
|
+ /// <summary>
|
|
|
+ /// Performs <paramref name="operationFunc"/> over all the elements of the operands.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="x">The first <see cref="SparseWeight8"/> operand.</param>
|
|
|
+ /// <param name="y">The second <see cref="SparseWeight8"/> operand.</param>
|
|
|
+ /// <param name="z">The third <see cref="SparseWeight8"/> operand.</param>
|
|
|
+ /// <param name="w">The fourth <see cref="SparseWeight8"/> operand.</param>
|
|
|
+ /// <param name="operationFunc">The operator function to apply to every element.</param>
|
|
|
+ /// <returns>A new <see cref="SparseWeight8"/>.</returns>
|
|
|
+ private static SparseWeight8 _OperateCubic
|
|
|
+ (
|
|
|
+ in SparseWeight8 x,
|
|
|
+ in SparseWeight8 y,
|
|
|
+ in SparseWeight8 z,
|
|
|
+ in SparseWeight8 w,
|
|
|
+ Func<float, float, float, float, float> operationFunc
|
|
|
+ )
|
|
|
{
|
|
|
- if (Weight0 > 0) yield return (Index0, Weight0);
|
|
|
- if (Weight1 > 0) yield return (Index1, Weight1);
|
|
|
- if (Weight2 > 0) yield return (Index2, Weight2);
|
|
|
- if (Weight3 > 0) yield return (Index3, Weight3);
|
|
|
- if (Weight4 > 0) yield return (Index4, Weight4);
|
|
|
- if (Weight5 > 0) yield return (Index5, Weight5);
|
|
|
- if (Weight6 > 0) yield return (Index6, Weight6);
|
|
|
- if (Weight7 > 0) yield return (Index7, Weight7);
|
|
|
+ // prepare buffers in the stack
|
|
|
+ Span<int> indices = stackalloc int[16];
|
|
|
+ Span<float> xxx = stackalloc float[16];
|
|
|
+ Span<float> yyy = stackalloc float[16];
|
|
|
+ Span<float> zzz = stackalloc float[16];
|
|
|
+ Span<float> www = stackalloc float[16];
|
|
|
+
|
|
|
+ // fill the buffers so all the elements are aligned by column
|
|
|
+ int offset = 0;
|
|
|
+ offset = CopyTo(x, indices, xxx, offset);
|
|
|
+ offset = CopyTo(y, indices, yyy, offset);
|
|
|
+ offset = CopyTo(z, indices, zzz, offset);
|
|
|
+ offset = CopyTo(w, indices, www, offset);
|
|
|
+
|
|
|
+ // perform operation element by element
|
|
|
+ for (int i = 0; i < offset; ++i)
|
|
|
+ {
|
|
|
+ xxx[i] = operationFunc(xxx[i], yyy[i], zzz[i], www[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // sort results by relevance, so they can fit
|
|
|
+ // in a new structure in case there's more than
|
|
|
+ // 8 results
|
|
|
+
|
|
|
+ indices = indices.Slice(0, offset);
|
|
|
+ xxx = xxx.Slice(0, offset);
|
|
|
+
|
|
|
+ BubbleSortByWeight(indices, xxx, offset);
|
|
|
+
|
|
|
+ return new SparseWeight8(indices, xxx);
|
|
|
}
|
|
|
|
|
|
- private float GetExpandedAt(int idx)
|
|
|
+ private static void BubbleSortByWeight(Span<int> indices, Span<float> weights, int count = int.MaxValue)
|
|
|
{
|
|
|
- if (idx == Index0) return Weight0;
|
|
|
- if (idx == Index1) return Weight1;
|
|
|
- if (idx == Index2) return Weight2;
|
|
|
- if (idx == Index3) return Weight3;
|
|
|
- if (idx == Index4) return Weight4;
|
|
|
- if (idx == Index5) return Weight5;
|
|
|
- if (idx == Index6) return Weight6;
|
|
|
- if (idx == Index7) return Weight7;
|
|
|
- return 0;
|
|
|
+ System.Diagnostics.Debug.Assert(indices.Length == weights.Length);
|
|
|
+
|
|
|
+ count = Math.Min(indices.Length, count);
|
|
|
+
|
|
|
+ for (int i = 0; i < count - 1; ++i)
|
|
|
+ {
|
|
|
+ for (int j = i + 1; j < count; ++j)
|
|
|
+ {
|
|
|
+ if (weights[j - 1] > weights[j]) continue;
|
|
|
+
|
|
|
+ if (weights[j - 1] == weights[j] && indices[j - 1] < indices[j]) continue;
|
|
|
+
|
|
|
+ var index = indices[j - 1];
|
|
|
+ indices[j - 1] = indices[j];
|
|
|
+ indices[j] = index;
|
|
|
+
|
|
|
+ var weight = weights[j - 1];
|
|
|
+ weights[j - 1] = weights[j];
|
|
|
+ weights[j] = weight;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private int GetExpandedCount()
|
|
|
+ private static void BubbleSortByIndex(Span<int> indices, Span<float> weights, int count = int.MaxValue)
|
|
|
{
|
|
|
- var c = 0;
|
|
|
- if (Weight0 > 0 && c <= Index0) c = Index0 + 1;
|
|
|
- if (Weight1 > 0 && c <= Index1) c = Index1 + 1;
|
|
|
- if (Weight2 > 0 && c <= Index2) c = Index2 + 1;
|
|
|
- if (Weight3 > 0 && c <= Index3) c = Index3 + 1;
|
|
|
- if (Weight4 > 0 && c <= Index4) c = Index4 + 1;
|
|
|
- if (Weight5 > 0 && c <= Index5) c = Index5 + 1;
|
|
|
- if (Weight6 > 0 && c <= Index6) c = Index6 + 1;
|
|
|
- if (Weight7 > 0 && c <= Index7) c = Index7 + 1;
|
|
|
+ System.Diagnostics.Debug.Assert(indices.Length == weights.Length);
|
|
|
|
|
|
- return c;
|
|
|
+ count = Math.Min(indices.Length, count);
|
|
|
+
|
|
|
+ for (int i = 0; i < count - 1; ++i)
|
|
|
+ {
|
|
|
+ for (int j = i + 1; j < count; ++j)
|
|
|
+ {
|
|
|
+ if (indices[j - 1] < indices[j]) continue;
|
|
|
+
|
|
|
+ if (indices[j - 1] == indices[j] && weights[j - 1] > weights[j]) continue;
|
|
|
+
|
|
|
+ var index = indices[j - 1];
|
|
|
+ indices[j - 1] = indices[j];
|
|
|
+ indices[j] = index;
|
|
|
+
|
|
|
+ var weight = weights[j - 1];
|
|
|
+ weights[j - 1] = weights[j];
|
|
|
+ weights[j] = weight;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ internal IEnumerable<(int, float)> GetPairs()
|
|
|
+ {
|
|
|
+ if (Weight0 != 0) yield return (Index0, Weight0);
|
|
|
+ if (Weight1 != 0) yield return (Index1, Weight1);
|
|
|
+ if (Weight2 != 0) yield return (Index2, Weight2);
|
|
|
+ if (Weight3 != 0) yield return (Index3, Weight3);
|
|
|
+ if (Weight4 != 0) yield return (Index4, Weight4);
|
|
|
+ if (Weight5 != 0) yield return (Index5, Weight5);
|
|
|
+ if (Weight6 != 0) yield return (Index6, Weight6);
|
|
|
+ if (Weight7 != 0) yield return (Index7, Weight7);
|
|
|
}
|
|
|
|
|
|
private (int, float) GetPair(int idx)
|
|
|
@@ -309,43 +439,34 @@ namespace SharpGLTF.Transforms
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public IEnumerable<float> Expand(int count)
|
|
|
- {
|
|
|
- for (int i = 0; i < count; ++i)
|
|
|
- {
|
|
|
- yield return GetExpandedAt(i);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public IEnumerator<float> GetEnumerator() { return Expand(GetExpandedCount()).GetEnumerator(); }
|
|
|
-
|
|
|
- IEnumerator IEnumerable.GetEnumerator() { return Expand(GetExpandedCount()).GetEnumerator(); }
|
|
|
-
|
|
|
- public bool ContainsKey(int key)
|
|
|
+ private float GetExpandedAt(int idx)
|
|
|
{
|
|
|
- return GetPairs().Select(item => item.Item1).Contains(key);
|
|
|
+ if (idx == Index0) return Weight0;
|
|
|
+ if (idx == Index1) return Weight1;
|
|
|
+ if (idx == Index2) return Weight2;
|
|
|
+ if (idx == Index3) return Weight3;
|
|
|
+ if (idx == Index4) return Weight4;
|
|
|
+ if (idx == Index5) return Weight5;
|
|
|
+ if (idx == Index6) return Weight6;
|
|
|
+ if (idx == Index7) return Weight7;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
- public bool TryGetValue(int key, out float value)
|
|
|
+ private int GetExpandedCount()
|
|
|
{
|
|
|
- if (key == Index0) { value = Weight0; return true; }
|
|
|
- if (key == Index1) { value = Weight1; return true; }
|
|
|
- if (key == Index2) { value = Weight2; return true; }
|
|
|
- if (key == Index3) { value = Weight3; return true; }
|
|
|
- if (key == Index4) { value = Weight4; return true; }
|
|
|
- if (key == Index5) { value = Weight5; return true; }
|
|
|
- if (key == Index6) { value = Weight6; return true; }
|
|
|
- if (key == Index7) { value = Weight7; return true; }
|
|
|
- value = 0;
|
|
|
- return false;
|
|
|
- }
|
|
|
+ var c = 0;
|
|
|
+ if (Weight0 != 0 && c <= Index0) c = Index0 + 1;
|
|
|
+ if (Weight1 != 0 && c <= Index1) c = Index1 + 1;
|
|
|
+ if (Weight2 != 0 && c <= Index2) c = Index2 + 1;
|
|
|
+ if (Weight3 != 0 && c <= Index3) c = Index3 + 1;
|
|
|
+ if (Weight4 != 0 && c <= Index4) c = Index4 + 1;
|
|
|
+ if (Weight5 != 0 && c <= Index5) c = Index5 + 1;
|
|
|
+ if (Weight6 != 0 && c <= Index6) c = Index6 + 1;
|
|
|
+ if (Weight7 != 0 && c <= Index7) c = Index7 + 1;
|
|
|
|
|
|
- IEnumerator<KeyValuePair<int, float>> IEnumerable<KeyValuePair<int, float>>.GetEnumerator()
|
|
|
- {
|
|
|
- return GetPairs().Select(item => new KeyValuePair<int, float>(item.Item1, item.Item2)).GetEnumerator();
|
|
|
+ return c;
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
-
|
|
|
}
|
|
|
}
|