NativeArrayExtension.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // Magica Cloth.
  2. // Copyright (c) MagicaSoft, 2020-2022.
  3. // https://magicasoft.jp
  4. using Unity.Collections;
  5. #if UNITY_2020_1_OR_NEWER
  6. using Unity.Collections.LowLevel.Unsafe;
  7. #elif MAGICACLOTH_UNSAFE
  8. using Unity.Collections.LowLevel.Unsafe;
  9. #else
  10. using System.Runtime.CompilerServices;
  11. #endif
  12. namespace MagicaCloth
  13. {
  14. /// <summary>
  15. /// NativeArray拡張メソッド
  16. /// </summary>
  17. public static class NativeArrayExtension
  18. {
  19. #if !MAGICACLOTH_UNSAFE
  20. /// <summary>
  21. /// 高速なCopyTo
  22. /// nativeArrayのstartIndexからのデータをarrayに書き出す
  23. /// </summary>
  24. /// <typeparam name="T"></typeparam>
  25. /// <param name="nativeArray"></param>
  26. /// <param name="array"></param>
  27. public static void CopyToFast<T, T2>(this NativeArray<T> nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct
  28. {
  29. #if UNITY_2020_1_OR_NEWER
  30. T[] ar = UnsafeUtility.As<T2[], T[]>(ref array);
  31. #else
  32. T[] ar = Unsafe.As<T2[], T[]>(ref array);
  33. #endif
  34. NativeArray<T>.Copy(nativeArray, startIndex, ar, 0, array.Length);
  35. }
  36. /// <summary>
  37. /// 高速なCopyTo
  38. /// nativeArrayのstartIndexからのデータをnativeArrayに書き出す
  39. /// </summary>
  40. /// <typeparam name="T"></typeparam>
  41. /// <param name="nativeArray"></param>
  42. /// <param name="array"></param>
  43. public static void CopyToFast<T>(this NativeArray<T> nativeArray, int startIndex, NativeArray<T> array) where T : struct
  44. {
  45. NativeArray<T>.Copy(nativeArray, startIndex, array, 0, array.Length);
  46. }
  47. /// <summary>
  48. /// 高速なCopyTo
  49. /// nativeArrayのsourceIndexからcountのデータをdestinationIndexにコピーする
  50. /// </summary>
  51. /// <typeparam name="T"></typeparam>
  52. /// <param name="nativeArray"></param>
  53. /// <param name="sourceIndex"></param>
  54. /// <param name="destinationIndex"></param>
  55. /// <param name="count"></param>
  56. public static void CopyBlock<T>(this NativeArray<T> nativeArray, int sourceIndex, int destinationIndex, int count) where T : struct
  57. {
  58. NativeArray<T>.Copy(nativeArray, sourceIndex, nativeArray, destinationIndex, count);
  59. }
  60. /// <summary>
  61. /// 高速なCopyFrom
  62. /// </summary>
  63. /// <typeparam name="T"></typeparam>
  64. /// <param name="nativeArray"></param>
  65. /// <param name="array"></param>
  66. public static void CopyFromFast<T>(this NativeArray<T> nativeArray, NativeArray<T> array) where T : struct
  67. {
  68. NativeArray<T>.Copy(array, 0, nativeArray, 0, array.Length);
  69. }
  70. /// <summary>
  71. /// 高速なCopyFrom
  72. /// arrayの内容をnativeArrayのstartIndex位置にコピーする
  73. /// </summary>
  74. /// <typeparam name="T"></typeparam>
  75. /// <param name="nativeArray"></param>
  76. /// <param name="array"></param>
  77. public static void CopyFromFast<T, T2>(this NativeArray<T> nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct
  78. {
  79. #if UNITY_2020_1_OR_NEWER
  80. T[] ar = UnsafeUtility.As<T2[], T[]>(ref array);
  81. #else
  82. T[] ar = Unsafe.As<T2[], T[]>(ref array);
  83. #endif
  84. NativeArray<T>.Copy(ar, 0, nativeArray, startIndex, array.Length);
  85. }
  86. /// <summary>
  87. /// 高速なデータ書き込み
  88. /// </summary>
  89. /// <typeparam name="T"></typeparam>
  90. /// <param name="nativeArray"></param>
  91. /// <param name="startIndex"></param>
  92. /// <param name="count"></param>
  93. /// <param name="value"></param>
  94. public static void SetValue<T>(this NativeArray<T> nativeArray, int startIndex, int count, T value) where T : struct
  95. {
  96. for (int i = 0; i < count; i++, startIndex++)
  97. {
  98. nativeArray[startIndex] = value;
  99. }
  100. }
  101. #else
  102. /// <summary>
  103. /// 高速なCopyTo
  104. /// </summary>
  105. /// <typeparam name="T"></typeparam>
  106. /// <param name="nativeArray"></param>
  107. /// <param name="array"></param>
  108. public static unsafe void CopyToFast<T, T2>(this NativeArray<T> nativeArray, T2[] array) where T : struct where T2 : struct
  109. {
  110. int byteLength = nativeArray.Length * UnsafeUtility.SizeOf<T>();
  111. void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]);
  112. void* nativeBuffer = nativeArray.GetUnsafePtr();
  113. UnsafeUtility.MemCpy(managedBuffer, nativeBuffer, byteLength);
  114. }
  115. /// <summary>
  116. /// 高速なCopyTo
  117. /// nativeArrayのstartIndexからのデータをarrayに書き出す
  118. /// </summary>
  119. /// <typeparam name="T"></typeparam>
  120. /// <param name="nativeArray"></param>
  121. /// <param name="array"></param>
  122. public static unsafe void CopyToFast<T, T2>(this NativeArray<T> nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct
  123. {
  124. int stride = UnsafeUtility.SizeOf<T>();
  125. int byteLength = array.Length * stride;
  126. void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]);
  127. byte* p = (byte*)nativeArray.GetUnsafePtr();
  128. p += startIndex * stride;
  129. UnsafeUtility.MemCpy(managedBuffer, (void*)p, byteLength);
  130. }
  131. /// <summary>
  132. /// 高速なCopyTo
  133. /// nativeArrayのstartIndexからのデータをnativeArrayに書き出す
  134. /// </summary>
  135. /// <typeparam name="T"></typeparam>
  136. /// <param name="nativeArray"></param>
  137. /// <param name="array"></param>
  138. public static unsafe void CopyToFast<T>(this NativeArray<T> nativeArray, int startIndex, NativeArray<T> array) where T : struct
  139. {
  140. int stride = UnsafeUtility.SizeOf<T>();
  141. int byteLength = array.Length * stride;
  142. byte* p = (byte*)nativeArray.GetUnsafePtr();
  143. p += startIndex * stride;
  144. UnsafeUtility.MemCpy(array.GetUnsafePtr(), (void*)p, byteLength);
  145. }
  146. /// <summary>
  147. /// 高速なCopyTo
  148. /// nativeArrayのsourceIndexからcountのデータをdestinationIndexにコピーする
  149. /// </summary>
  150. /// <typeparam name="T"></typeparam>
  151. /// <param name="nativeArray"></param>
  152. /// <param name="sourceIndex"></param>
  153. /// <param name="destinationIndex"></param>
  154. /// <param name="count"></param>
  155. public static unsafe void CopyBlock<T>(this NativeArray<T> nativeArray, int sourceIndex, int destinationIndex, int count) where T : struct
  156. {
  157. int stride = UnsafeUtility.SizeOf<T>();
  158. int byteLength = count * stride;
  159. byte* p = (byte*)nativeArray.GetUnsafePtr();
  160. UnsafeUtility.MemCpy((void*)(p + destinationIndex * stride), (void*)(p + sourceIndex * stride), byteLength);
  161. }
  162. /// <summary>
  163. /// 高速なCopyFrom
  164. /// </summary>
  165. /// <typeparam name="T"></typeparam>
  166. /// <param name="nativeArray"></param>
  167. /// <param name="array"></param>
  168. public static unsafe void CopyFromFast<T, T2>(this NativeArray<T> nativeArray, T2[] array) where T : struct where T2 : struct
  169. {
  170. int byteLength = nativeArray.Length * UnsafeUtility.SizeOf<T>();
  171. void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]);
  172. void* nativeBuffer = nativeArray.GetUnsafePtr();
  173. UnsafeUtility.MemCpy(nativeBuffer, managedBuffer, byteLength);
  174. }
  175. /// <summary>
  176. /// 高速なCopyFrom
  177. /// </summary>
  178. /// <typeparam name="T"></typeparam>
  179. /// <param name="nativeArray"></param>
  180. /// <param name="array"></param>
  181. public static unsafe void CopyFromFast<T>(this NativeArray<T> nativeArray, NativeArray<T> array) where T : struct
  182. {
  183. int byteLength = array.Length * UnsafeUtility.SizeOf<T>();
  184. void* managedBuffer = array.GetUnsafePtr();
  185. void* nativeBuffer = nativeArray.GetUnsafePtr();
  186. UnsafeUtility.MemCpy(nativeBuffer, managedBuffer, byteLength);
  187. }
  188. /// <summary>
  189. /// 高速なCopyFrom
  190. /// arrayの内容をnativeArrayのstartIndex位置にコピーする
  191. /// </summary>
  192. /// <typeparam name="T"></typeparam>
  193. /// <param name="nativeArray"></param>
  194. /// <param name="array"></param>
  195. public static unsafe void CopyFromFast<T, T2>(this NativeArray<T> nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct
  196. {
  197. int stride = UnsafeUtility.SizeOf<T>();
  198. int byteLength = array.Length * stride;
  199. void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]);
  200. byte* p = (byte*)nativeArray.GetUnsafePtr();
  201. p += startIndex * stride;
  202. UnsafeUtility.MemCpy((void*)p, managedBuffer, byteLength);
  203. }
  204. /// <summary>
  205. /// 高速なデータ書き込み
  206. /// </summary>
  207. /// <typeparam name="T"></typeparam>
  208. /// <param name="nativeArray"></param>
  209. /// <param name="startIndex"></param>
  210. /// <param name="count"></param>
  211. /// <param name="value"></param>
  212. public static unsafe void SetValue<T>(this NativeArray<T> nativeArray, int startIndex, int count, T value) where T : struct
  213. {
  214. void* nativeBuffer = nativeArray.GetUnsafePtr();
  215. for (int i = 0; i < count; i++)
  216. {
  217. UnsafeUtility.WriteArrayElement(nativeBuffer, startIndex + i, value);
  218. }
  219. }
  220. #endif
  221. }
  222. }