// Magica Cloth. // Copyright (c) MagicaSoft, 2020-2022. // https://magicasoft.jp using Unity.Collections; #if UNITY_2020_1_OR_NEWER using Unity.Collections.LowLevel.Unsafe; #elif MAGICACLOTH_UNSAFE using Unity.Collections.LowLevel.Unsafe; #else using System.Runtime.CompilerServices; #endif namespace MagicaCloth { /// /// NativeArray拡張メソッド /// public static class NativeArrayExtension { #if !MAGICACLOTH_UNSAFE /// /// 高速なCopyTo /// nativeArrayのstartIndexからのデータをarrayに書き出す /// /// /// /// public static void CopyToFast(this NativeArray nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct { #if UNITY_2020_1_OR_NEWER T[] ar = UnsafeUtility.As(ref array); #else T[] ar = Unsafe.As(ref array); #endif NativeArray.Copy(nativeArray, startIndex, ar, 0, array.Length); } /// /// 高速なCopyTo /// nativeArrayのstartIndexからのデータをnativeArrayに書き出す /// /// /// /// public static void CopyToFast(this NativeArray nativeArray, int startIndex, NativeArray array) where T : struct { NativeArray.Copy(nativeArray, startIndex, array, 0, array.Length); } /// /// 高速なCopyTo /// nativeArrayのsourceIndexからcountのデータをdestinationIndexにコピーする /// /// /// /// /// /// public static void CopyBlock(this NativeArray nativeArray, int sourceIndex, int destinationIndex, int count) where T : struct { NativeArray.Copy(nativeArray, sourceIndex, nativeArray, destinationIndex, count); } /// /// 高速なCopyFrom /// /// /// /// public static void CopyFromFast(this NativeArray nativeArray, NativeArray array) where T : struct { NativeArray.Copy(array, 0, nativeArray, 0, array.Length); } /// /// 高速なCopyFrom /// arrayの内容をnativeArrayのstartIndex位置にコピーする /// /// /// /// public static void CopyFromFast(this NativeArray nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct { #if UNITY_2020_1_OR_NEWER T[] ar = UnsafeUtility.As(ref array); #else T[] ar = Unsafe.As(ref array); #endif NativeArray.Copy(ar, 0, nativeArray, startIndex, array.Length); } /// /// 高速なデータ書き込み /// /// /// /// /// /// public static void SetValue(this NativeArray nativeArray, int startIndex, int count, T value) where T : struct { for (int i = 0; i < count; i++, startIndex++) { nativeArray[startIndex] = value; } } #else /// /// 高速なCopyTo /// /// /// /// public static unsafe void CopyToFast(this NativeArray nativeArray, T2[] array) where T : struct where T2 : struct { int byteLength = nativeArray.Length * UnsafeUtility.SizeOf(); void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]); void* nativeBuffer = nativeArray.GetUnsafePtr(); UnsafeUtility.MemCpy(managedBuffer, nativeBuffer, byteLength); } /// /// 高速なCopyTo /// nativeArrayのstartIndexからのデータをarrayに書き出す /// /// /// /// public static unsafe void CopyToFast(this NativeArray nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct { int stride = UnsafeUtility.SizeOf(); int byteLength = array.Length * stride; void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]); byte* p = (byte*)nativeArray.GetUnsafePtr(); p += startIndex * stride; UnsafeUtility.MemCpy(managedBuffer, (void*)p, byteLength); } /// /// 高速なCopyTo /// nativeArrayのstartIndexからのデータをnativeArrayに書き出す /// /// /// /// public static unsafe void CopyToFast(this NativeArray nativeArray, int startIndex, NativeArray array) where T : struct { int stride = UnsafeUtility.SizeOf(); int byteLength = array.Length * stride; byte* p = (byte*)nativeArray.GetUnsafePtr(); p += startIndex * stride; UnsafeUtility.MemCpy(array.GetUnsafePtr(), (void*)p, byteLength); } /// /// 高速なCopyTo /// nativeArrayのsourceIndexからcountのデータをdestinationIndexにコピーする /// /// /// /// /// /// public static unsafe void CopyBlock(this NativeArray nativeArray, int sourceIndex, int destinationIndex, int count) where T : struct { int stride = UnsafeUtility.SizeOf(); int byteLength = count * stride; byte* p = (byte*)nativeArray.GetUnsafePtr(); UnsafeUtility.MemCpy((void*)(p + destinationIndex * stride), (void*)(p + sourceIndex * stride), byteLength); } /// /// 高速なCopyFrom /// /// /// /// public static unsafe void CopyFromFast(this NativeArray nativeArray, T2[] array) where T : struct where T2 : struct { int byteLength = nativeArray.Length * UnsafeUtility.SizeOf(); void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]); void* nativeBuffer = nativeArray.GetUnsafePtr(); UnsafeUtility.MemCpy(nativeBuffer, managedBuffer, byteLength); } /// /// 高速なCopyFrom /// /// /// /// public static unsafe void CopyFromFast(this NativeArray nativeArray, NativeArray array) where T : struct { int byteLength = array.Length * UnsafeUtility.SizeOf(); void* managedBuffer = array.GetUnsafePtr(); void* nativeBuffer = nativeArray.GetUnsafePtr(); UnsafeUtility.MemCpy(nativeBuffer, managedBuffer, byteLength); } /// /// 高速なCopyFrom /// arrayの内容をnativeArrayのstartIndex位置にコピーする /// /// /// /// public static unsafe void CopyFromFast(this NativeArray nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct { int stride = UnsafeUtility.SizeOf(); int byteLength = array.Length * stride; void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]); byte* p = (byte*)nativeArray.GetUnsafePtr(); p += startIndex * stride; UnsafeUtility.MemCpy((void*)p, managedBuffer, byteLength); } /// /// 高速なデータ書き込み /// /// /// /// /// /// public static unsafe void SetValue(this NativeArray nativeArray, int startIndex, int count, T value) where T : struct { void* nativeBuffer = nativeArray.GetUnsafePtr(); for (int i = 0; i < count; i++) { UnsafeUtility.WriteArrayElement(nativeBuffer, startIndex + i, value); } } #endif } }