Arrays.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Numerics;
  6. using System.Text;
  7. namespace SharpGLTF.Memory
  8. {
  9. public interface IEncodedArray<T> : IReadOnlyCollection<T>
  10. where T : unmanaged
  11. {
  12. T this[int index] { get; set; }
  13. void CopyTo(ArraySegment<T> dst);
  14. // void CopyTo(IEncodedArray<T> dst);
  15. (T, T) GetBounds();
  16. }
  17. struct EncodedArrayEnumerator<T> : IEnumerator<T>
  18. where T : unmanaged
  19. {
  20. #region lifecycle
  21. public EncodedArrayEnumerator(IEncodedArray<T> accessor)
  22. {
  23. this._Accessor = accessor;
  24. this._Count = accessor.Count;
  25. this._Index = -1;
  26. }
  27. public void Dispose()
  28. {
  29. }
  30. #endregion
  31. #region data
  32. private readonly IEncodedArray<T> _Accessor;
  33. private readonly int _Count;
  34. private int _Index;
  35. #endregion
  36. #region API
  37. public T Current => _Accessor[_Index];
  38. object IEnumerator.Current => _Accessor[_Index];
  39. public bool MoveNext()
  40. {
  41. ++_Index;
  42. return _Index < _Count;
  43. }
  44. public void Reset()
  45. {
  46. _Index = -1;
  47. }
  48. #endregion
  49. }
  50. public static class EncodedArrayUtils
  51. {
  52. public static IntegerArray IndicesRange(int start, int count)
  53. {
  54. var array = new IntegerArray( new ArraySegment<Byte>(new Byte[count * 4]), Schema2.IndexType.UNSIGNED_INT);
  55. for (int i = 0; i < count; ++i)
  56. {
  57. array[i] = (UInt32)(start + i);
  58. }
  59. return array;
  60. }
  61. public static void FillFrom(this IEncodedArray<UInt32> dst, int dstIndex, IEnumerable<Int32> src)
  62. {
  63. using (var ator = src.GetEnumerator())
  64. {
  65. while (dstIndex < dst.Count && ator.MoveNext())
  66. {
  67. dst[dstIndex++] = (UInt32)ator.Current;
  68. }
  69. }
  70. }
  71. public static void FillFrom<T>(this IEncodedArray<T> dst, int dstIndex, IEnumerable<T> src)
  72. where T : unmanaged
  73. {
  74. using (var ator = src.GetEnumerator())
  75. {
  76. while (dstIndex < dst.Count && ator.MoveNext())
  77. {
  78. dst[dstIndex++] = ator.Current;
  79. }
  80. }
  81. }
  82. public static void FillFrom<T>(this IEncodedArray<T> dst, int dstIndex, params T[] src)
  83. where T : unmanaged
  84. {
  85. for (int i = 0; i < src.Length; ++i)
  86. {
  87. dst[dstIndex + i] = src[i];
  88. }
  89. }
  90. public static void CopyTo<T>(IEncodedArray<T> src, IEncodedArray<T> dst, int dstOffset = 0)
  91. where T : unmanaged
  92. {
  93. for (int i = 0; i < src.Count; ++i)
  94. {
  95. dst[i + dstOffset] = src[i];
  96. }
  97. }
  98. public static void CopyTo<T>(T[] src, IEncodedArray<T> dst, int dstOffset = 0)
  99. where T : unmanaged
  100. {
  101. for (int i = 0; i < src.Length; ++i)
  102. {
  103. dst[i + dstOffset] = src[i];
  104. }
  105. }
  106. public static void Copy<T>(IEncodedArray<T> src, T[] dst)
  107. where T : unmanaged
  108. {
  109. Copy<T>(src, new ArraySegment<T>(dst));
  110. }
  111. public static void Copy<T>(IEncodedArray<T> src, ArraySegment<T> dst)
  112. where T : unmanaged
  113. {
  114. var c = src.Count;
  115. for (int i = 0; i < c; ++i) dst.Array[dst.Offset + i] = src[i];
  116. }
  117. public static (Single, Single) GetBounds(ScalarArray accesor)
  118. {
  119. var min = Single.MaxValue;
  120. var max = Single.MinValue;
  121. int c = accesor.Count;
  122. for (int i = 0; i < c; ++i)
  123. {
  124. var v = accesor[i];
  125. min = Math.Min(min, v);
  126. max = Math.Max(max, v);
  127. }
  128. return (min, max);
  129. }
  130. public static (Vector2, Vector2) GetBounds(Vector2Array accesor)
  131. {
  132. var min = new Vector2(Single.MaxValue);
  133. var max = new Vector2(Single.MinValue);
  134. int c = accesor.Count;
  135. for (int i = 0; i < c; ++i)
  136. {
  137. var v = accesor[i];
  138. min = Vector2.Min(min, v);
  139. max = Vector2.Max(max, v);
  140. }
  141. return (min, max);
  142. }
  143. public static (Vector3, Vector3) GetBounds(Vector3Array accesor)
  144. {
  145. var min = new Vector3(Single.MaxValue);
  146. var max = new Vector3(Single.MinValue);
  147. int c = accesor.Count;
  148. for (int i = 0; i < c; ++i)
  149. {
  150. var v = accesor[i];
  151. min = Vector3.Min(min, v);
  152. max = Vector3.Max(max, v);
  153. }
  154. return (min, max);
  155. }
  156. public static (Vector4, Vector4) GetBounds(IEncodedArray<Vector4> accesor)
  157. {
  158. var min = new Vector4(Single.MaxValue);
  159. var max = new Vector4(Single.MinValue);
  160. int c = accesor.Count;
  161. for (int i = 0; i < c; ++i)
  162. {
  163. var v = accesor[i];
  164. min = Vector4.Min(min, v);
  165. max = Vector4.Max(max, v);
  166. }
  167. return (min, max);
  168. }
  169. }
  170. /// <summary>
  171. /// Wraps a collection of Scalar values and exposes it as a collection of Vector4 values
  172. /// </summary>
  173. struct _MapScalarToVector4 : IEncodedArray<Vector4>
  174. {
  175. public _MapScalarToVector4(ScalarArray source)
  176. {
  177. _Accessor = source;
  178. }
  179. private ScalarArray _Accessor;
  180. public int Count => _Accessor.Count;
  181. public Vector4 this[int index]
  182. {
  183. get => new Vector4(_Accessor[index], 0, 0, 0);
  184. set => _Accessor[index] = value.X;
  185. }
  186. public void CopyTo(ArraySegment<Vector4> dst) { EncodedArrayUtils.Copy(this, dst); }
  187. public IEnumerator<Vector4> GetEnumerator() { return new EncodedArrayEnumerator<Vector4>(this); }
  188. IEnumerator IEnumerable.GetEnumerator() { return new EncodedArrayEnumerator<Vector4>(this); }
  189. public (Vector4, Vector4) GetBounds() { return EncodedArrayUtils.GetBounds(this); }
  190. }
  191. /// <summary>
  192. /// Wraps a collection of Vector2 values and exposes it as a collection of Vector4 values
  193. /// </summary>
  194. struct _MapVector2ToVector4 : IEncodedArray<Vector4>
  195. {
  196. public _MapVector2ToVector4(Vector2Array source)
  197. {
  198. _Accessor = source;
  199. }
  200. private Vector2Array _Accessor;
  201. public int Count => _Accessor.Count;
  202. public Vector4 this[int index]
  203. {
  204. get { var v = _Accessor[index]; return new Vector4(v.X, v.Y, 0, 0); }
  205. set => _Accessor[index] = new Vector2(value.X, value.Y);
  206. }
  207. public void CopyTo(ArraySegment<Vector4> dst) { EncodedArrayUtils.Copy(this, dst); }
  208. public IEnumerator<Vector4> GetEnumerator() { return new EncodedArrayEnumerator<Vector4>(this); }
  209. IEnumerator IEnumerable.GetEnumerator() { return new EncodedArrayEnumerator<Vector4>(this); }
  210. public (Vector4, Vector4) GetBounds() { return EncodedArrayUtils.GetBounds(this); }
  211. }
  212. /// <summary>
  213. /// Wraps a collection of Vector3 values and exposes it as a collection of Vector4 values
  214. /// </summary>
  215. struct _MapVector3ToVector4 : IEncodedArray<Vector4>
  216. {
  217. public _MapVector3ToVector4(Vector3Array source)
  218. {
  219. _Accessor = source;
  220. }
  221. private Vector3Array _Accessor;
  222. public int Count => _Accessor.Count;
  223. public Vector4 this[int index]
  224. {
  225. get { var v = _Accessor[index]; return new Vector4(v.X, v.Y, v.Z, 0); }
  226. set => _Accessor[index] = new Vector3(value.X, value.Y, value.Z);
  227. }
  228. public void CopyTo(ArraySegment<Vector4> dst) { EncodedArrayUtils.Copy(this, dst); }
  229. public IEnumerator<Vector4> GetEnumerator() { return new EncodedArrayEnumerator<Vector4>(this); }
  230. IEnumerator IEnumerable.GetEnumerator() { return new EncodedArrayEnumerator<Vector4>(this); }
  231. public (Vector4, Vector4) GetBounds() { return EncodedArrayUtils.GetBounds(this); }
  232. }
  233. /// <summary>
  234. /// Wraps a collection of Quaternion values and exposes it as a collection of Vector4 values
  235. /// </summary>
  236. struct _MapQuaternionToVector4 : IEncodedArray<Vector4>
  237. {
  238. public _MapQuaternionToVector4(QuaternionArray source)
  239. {
  240. _Accessor = source;
  241. }
  242. private QuaternionArray _Accessor;
  243. public int Count => _Accessor.Count;
  244. public Vector4 this[int index]
  245. {
  246. get { var v = _Accessor[index]; return new Vector4(v.X, v.Y, v.Z, v.W); }
  247. set => _Accessor[index] = new Quaternion(value.X, value.Y, value.Z, value.W);
  248. }
  249. public void CopyTo(ArraySegment<Vector4> dst) { EncodedArrayUtils.Copy(this, dst); }
  250. public IEnumerator<Vector4> GetEnumerator() { return new EncodedArrayEnumerator<Vector4>(this); }
  251. IEnumerator IEnumerable.GetEnumerator() { return new EncodedArrayEnumerator<Vector4>(this); }
  252. public (Vector4, Vector4) GetBounds() { return EncodedArrayUtils.GetBounds(this); }
  253. }
  254. }