public NativeArray <T> AsArray() { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckGetSecondaryDataPointerAndThrow(m_Safety); CheckAllocated(m_ListData); var arraySafety = m_Safety; AtomicSafetyHandle.UseSecondaryVersion(ref arraySafety); #endif var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(m_ListData->Ptr, m_ListData->Length, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, arraySafety); #endif return(array); }
/// <summary> /// Return a native array that aliases the original bit array contents. /// </summary> /// <typeparam name="T">The type of the elements in the container.</typeparam> /// <exception cref="InvalidOperationException">Thrown if output size doesn't match input, or if reinterpreted data would be truncated.</exception> /// <returns>Native array view into bit array.</returns> public NativeArray <T> AsNativeArray <T>() where T : unmanaged { CheckReadBounds <T>(); var bitsPerElement = UnsafeUtility.SizeOf <T>() * 8; var length = m_BitArray.Length / bitsPerElement; var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(m_BitArray.Ptr, length, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.UseSecondaryVersion(ref m_Safety); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, m_Safety); #endif return(array); }
public static NativeArray <int> GetWriteGroupTypes(int typeIndex) { #if UNITY_CSHARP_TINY var arr = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <int>(null, 0, Allocator.None); #else var type = GetTypeInfo(typeIndex); var writeGroups = type.WriteGroups; var writeGroupCount = type.WriteGroupCount; var arr = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <int>(writeGroups, writeGroupCount, Allocator.None); #endif #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref arr, AtomicSafetyHandle.Create()); #endif return(arr); }
protected NativeArray <T> GetNativeArray <T>(Chunk *chunk) where T : struct, IComponentData { var hash = typeof(T).GetHashCode(); int componentIndex = ArcheType->GetIndex(hash); Assert.IsTrue(componentIndex >= 0); var buf = Block.GetComponentDataArray(chunk, componentIndex); var len = Block.GetComponentDataCount(chunk, componentIndex); var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(buf, len, Allocator.Persistent); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, AtomicSafetyHandle.GetTempUnsafePtrSliceHandle()); #endif return(array); }
public void CopyTo(NativeArray <T> array) { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckGetSecondaryDataPointerAndThrow(m_Safety); var arraySafety = m_Safety; AtomicSafetyHandle.UseSecondaryVersion(ref arraySafety); #endif var tarray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T> (m_ListData->buffer, m_ListData->length, Collections.Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref tarray, arraySafety); #endif tarray.CopyTo(array); }
public NativeArray <T> AsArray() { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckGetSecondaryDataPointerAndThrow(m_Safety); var arraySafety = m_Safety; AtomicSafetyHandle.UseSecondaryVersion(ref arraySafety); #endif var array = m_Impl.AsNativeArray(); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, arraySafety); #endif return(array); }
public static unsafe NativeArray <TO> Reinterpret <TI, TO>(this NativeArray <TI> nativeArray) where TI : struct where TO : struct { var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <TO>( nativeArray.GetUnsafePtr(), nativeArray.Length, Allocator.Invalid); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, AtomicSafetyHandle.Create()); #endif return(array); }
private static unsafe void OnReportPooledQueries(IntPtr buffer, int count) { var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Query>(buffer.ToPointer(), count, Allocator.None); var safety = AtomicSafetyHandle.Create(); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, safety); if (OnRetrievePooledQueries != null) { OnRetrievePooledQueries(array); } AtomicSafetyHandle.Release(safety); }
/// <summary> /// Provides a native array interface to entity instances stored in this chunk. /// </summary> /// <remarks>The native array returned by this method references existing data, not a copy.</remarks> /// <param name="archetypeChunkEntityType">An object containing type and job safety information. Create this /// object by calling <see cref="Unity.Entities.JobComponentSystem.GetArchetypeChunkEntityType()"/> immediately /// before scheduling a job. Pass the object to a job using a public field you define as part of the job struct.</param> /// <returns>A native array containing the entities in the chunk.</returns> public NativeArray <Entity> GetNativeArray(ArchetypeChunkEntityType archetypeChunkEntityType) { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckReadAndThrow(archetypeChunkEntityType.m_Safety); #endif var archetype = m_Chunk->Archetype; var buffer = m_Chunk->Buffer; var length = m_Chunk->Count; var startOffset = archetype->Offsets[0]; var result = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Entity>(buffer + startOffset, length, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref result, archetypeChunkEntityType.m_Safety); #endif return(result); }
void Start() { _meshFilter = GetComponent <MeshFilter>(); _mesh = _meshFilter.mesh; VSize = _mesh.vertexCount; V = new NativeArray <float>(3 * VSize, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref V, AtomicSafetyHandle.Create()); #endif var layout = _mesh.GetVertexAttributes(); _mesh.MarkDynamic(); //GPU buffer should be dynamic so we can modify it easily with D3D11Buffer::Map() unsafe { NativeArray <float> tmp; fixed(Vector3 *managedVPtr = _mesh.vertices) tmp = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <float>((float *)managedVPtr, 3 * VSize, Allocator.Temp); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref tmp, AtomicSafetyHandle.Create()); #endif // NativeArray<float>.Copy(tmp, V); //Make our own copy V.CopyFrom(tmp); tmp.Dispose(); } // Do not use this as it makes the GPU buffer no longer dynamic for us // mesh.UploadMeshData(true); //delete managed copy and make no longer readable via Unity if (useCustomUploadToGpu) { //Setup custom uploading mesh data _vertexUploadData = new VertexUploadData(); _vertexUploadHandle = GCHandle.Alloc(_vertexUploadData, GCHandleType.Pinned); _gfxVertexBufferPtr = _mesh.GetNativeVertexBufferPtr(0); // command is called every frame until it's removed (can leave it if updating every frame) _commandBuffer = new CommandBuffer(); _commandBuffer.name = "UploadMeshCmd"; // for profiling IntPtr dataPtr = _vertexUploadHandle.AddrOfPinnedObject(); // command.IssuePluginEventAndData(Native.GetUploadMeshPtr(), 1, dataPtr); // Camera.main.AddCommandBufferAsync(CameraEvent.AfterEverything, command, ComputeQueueType.Default); // Graphics.ExecuteCommandBufferAsync(command, ComputeQueueType.Default); } }
static NativeArray <ulong2> GetULong2View(NativeArray <byte> data) { unsafe { var ptr = (ulong2 *)data.GetUnsafeReadOnlyPtr(); var blocks = data.Length >> 4; var r = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ulong2>(ptr, blocks, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref r, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(data)); #endif return(r); } }
public static unsafe DataStreamReader AsDataStreamReader <T>(this DynamicBuffer <T> self) where T : struct, IBufferElementData { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (UnsafeUtility.SizeOf <T>() != 1) { throw new System.InvalidOperationException("Can only convert DynamicBuffers of size 1 to DataStreamWriters"); } #endif var na = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(self.GetUnsafePtr(), self.Length, Allocator.Invalid); #if ENABLE_UNITY_COLLECTIONS_CHECKS var safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(self.AsNativeArray()); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref na, safety); #endif return(new DataStreamReader(na)); }
public unsafe NativeArray <T> GetData <T>() where T : struct { long size = GetDataSize(); long stride = UnsafeUtility.SizeOf <T>(); if (size % stride != 0) { throw new ArgumentException($"Type passed to {nameof(GetData)} can't capture the asset data. Data size is {size} which is not a multiple of type size {stride}"); } var arrSize = size / stride; var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>((void *)GetDataPtr(), (int)arrSize, Allocator.None); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, GetSafetyHandle(this)); return(array); }
public NativeArray <T> GetData <T>(int layer = 0) where T : struct { if (!this.done || this.hasError) { throw new InvalidOperationException("Cannot access the data as it is not available"); } if (layer < 0 || layer >= this.layerCount) { throw new ArgumentException(string.Format("Layer index is out of range {0} / {1}", layer, this.layerCount)); } int num = UnsafeUtility.SizeOf <T>(); NativeArray <T> result = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(this.GetDataRaw(layer), this.GetLayerDataSize() / num, Allocator.None); NativeArrayUnsafeUtility.SetAtomicSafetyHandle <T>(ref result, this.GetSafetyHandle()); return(result); }
/// <summary> /// Array of indiices into source NativeArray which share the same source value /// </summary> /// <param name="index">Index of shared value</param> /// <returns></returns> public unsafe NativeArray <int> GetSharedValueIndicesBySharedIndex(int index) { int sharedValueIndexCountOffset = 2 * m_Source.Length; int sharedValueIndexCount = m_Buffer[sharedValueIndexCountOffset + index]; int sharedValueStartIndicesOffset = 3 * m_Source.Length; int sharedValueStartIndex = m_Buffer[sharedValueStartIndicesOffset + index]; int sortedValueOffset = m_SortedBuffer * m_Source.Length; int *rawIndices = ((int *)m_Buffer.GetUnsafeReadOnlyPtr()) + (sortedValueOffset + sharedValueStartIndex); var arr = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <int>(rawIndices, sharedValueIndexCount, Allocator.Invalid); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref arr, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(m_Buffer)); #endif return(arr); }
// todo: try not making new array and just write from position and length of write buffer static int EncodeChunk(byte[] buffer, Chunk chunk) { var blocks = chunk.blocks; // run length encoding, a byte for type followed by byte for runcount // rewrote project to access data in xzy order, because i assume there will be more horizontal than vertical structures in the world gen (and thus more runs) // WWWWWBWWWBWWWW - example // W5B1W3B1W4 - type followed by run count (up to length 256) // WW5BWW3BWW4 - alternate way where double type indicates a run // runs cost one byte extra but singles cost one byte less? not sure if worth // todo: investigate whether using ushort is better for runs and types eventually maybe writer.Start(uintBuffer); writer.Write(chunk.builtStructures); // circumvent the safety check here because it gets mad for some reason when trying to save // even though i am quite sure it is safe. Saving is only called when a chunk is being destroyed // and only if it was either already generated new or loaded and then modified // in both cases the generation job is finished editing the blocks // i think it doesnt trust the fact that its in a separate thread #if ENABLE_UNITY_COLLECTIONS_CHECKS var handle = AtomicSafetyHandle.Create(); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref blocks, handle); #endif int i = 0; while (i < blocks.Length) { byte type = blocks[i].type; byte run = 1; while (++i < blocks.Length && blocks[i].type == type && run < byte.MaxValue) { run++; } writer.Write(type); writer.Write(run); } #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.Release(handle); #endif writer.Finish(); return(writer.GetData(buffer)); }
public NativeArray <T> GetSubArray(int start, int length) { if (start < 0) { throw new ArgumentOutOfRangeException(nameof(start), "start must be >= 0"); } if (start + length > Length) { throw new ArgumentOutOfRangeException(nameof(length), $"sub array range {start}-{start+length-1} is outside the range of the native array 0-{Length-1}"); } var result = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(((byte *)m_Buffer) + ((long)UnsafeUtility.SizeOf <T>()) * start, length, Allocator.Invalid); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref result, m_Safety); result.m_DisposeSentinel = null; return(result); }
public unsafe NativeArray <Entity> GetChunkArray(int startIndex, int maxCount) { AtomicSafetyHandle.CheckReadAndThrow(this.m_Safety); if (startIndex < 0) { this.FailOutOfRangeError(startIndex); } else if ((startIndex + maxCount) > this.m_Length) { this.FailOutOfRangeError(startIndex + maxCount); } this.m_Iterator.MoveToEntityIndexAndUpdateCache(startIndex, out this.m_Cache, false); NativeArray <Entity> array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Entity>(this.m_Cache.CachedPtr + (startIndex * this.m_Cache.CachedSizeOf), Math.Min(maxCount, this.m_Cache.CachedEndIndex - startIndex), Allocator.Invalid); NativeArrayUnsafeUtility.SetAtomicSafetyHandle <Entity>(ref array, this.m_Safety); return(array); }
public unsafe NativeArray <T> GetPixelData <T>(int mipLevel) where T : struct { bool flag = !this.isReadable; if (flag) { throw base.CreateNonReadableException(this); } int pixelDataOffset = base.GetPixelDataOffset(mipLevel, 0); int pixelDataSize = base.GetPixelDataSize(mipLevel, 0); int num = UnsafeUtility.SizeOf <T>(); IntPtr value = new IntPtr(this.GetWritableImageData(0).ToInt64() + (long)pixelDataOffset); NativeArray <T> result = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>((void *)value, pixelDataSize / num, Allocator.None); NativeArrayUnsafeUtility.SetAtomicSafetyHandle <T>(ref result, this.GetSafetyHandleForSlice(mipLevel)); return(result); }
/// <summary> /// Provides a NativeArray that you can pass into a job whose contents can be modified by a previous job. /// </summary> /// <remarks>Pass a deferred array to a job when the list is populated or modified by a previous job. Using a /// deferred array allows you to schedule both jobs at the same time. (Without a deferred array, you would /// have to wait for the results of the first job before you scheduling the second.)</remarks> /// <returns>A [NativeArray](https://docs.unity3d.com/ScriptReference/Unity.Collections.NativeArray_1.html) that /// can be passed to one job as a "promise" that is fulfilled by a previous job.</returns> /// <example> /// The following example populates a list with integers in one job and passes that data to a second job as /// a deferred array. If you tried to pass the list directly to the second job, that job would get the contents /// of the list at the time you schedule the job and would not see any modifications made to the list by the /// first job. /// <code> /// using UnityEngine; /// using Unity.Jobs; /// using Unity.Collections; /// /// public class DeferredArraySum : MonoBehaviour ///{ /// public struct ListPopulatorJob : IJob /// { /// public NativeList<int> list; /// /// public void Execute() /// { /// for (int i = list.Length; i < list.Capacity; i++) /// { /// list.Add(i); /// } /// } /// } /// /// public struct ArraySummerJob : IJob /// { /// [ReadOnly] public NativeArray<int> deferredArray; /// public NativeArray<int> sum; /// /// public void Execute() /// { /// sum[0] = 0; /// for (int i = 0; i < deferredArray.Length; i++) /// { /// sum[0] += deferredArray[i]; /// } /// } /// } /// /// void Start() /// { /// var deferredList = new NativeList<int>(100, Allocator.TempJob); /// /// var populateJob = new ListPopulatorJob() /// { /// list = deferredList /// }; /// /// var output = new NativeArray<int>(1, Allocator.TempJob); /// var sumJob = new ArraySummerJob() /// { /// deferredArray = deferredList.AsDeferredJobArray(), /// sum = output /// }; /// /// var populateJobHandle = populateJob.Schedule(); /// var sumJobHandle = sumJob.Schedule(populateJobHandle); /// /// sumJobHandle.Complete(); /// /// Debug.Log("Result: " + output[0]); /// /// deferredList.Dispose(); /// output.Dispose(); /// } /// } /// </code> /// </example> public unsafe NativeArray <T> AsDeferredJobArray() { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckExistsAndThrow(m_Safety); #endif byte *buffer = (byte *)m_ListData; // We use the first bit of the pointer to infer that the array is in list mode // Thus the job scheduling code will need to patch it. buffer += 1; var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(buffer, 0, Allocator.Invalid); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, m_Safety); #endif return(array); }
/// <summary> /// Returns an array of FieldInfos for the passed in Type, if that type was had field information generated via /// the [GenerateComponentFieldInfo] attribute. See that attribute for more details on usage. /// This function can be called recursively using Types from the returned NativeArray's FieldInfo element's FieldType property. /// </summary> /// <param name="type"></param> /// <returns>NativeArray of FieldInfo</returns> public static NativeArray <FieldInfo> GetFieldInfos(Type type) { if (!s_TypeToFieldInfosMap.TryGetValue(type, out var lookup)) { throw new ArgumentException($"'{type}' is not a Component type or a nested field type of a component. We only generate FieldInfo for Components and their fields if the component was registered using [GenerateComponentFieldInfo]."); } var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <FieldInfo>((FieldInfo *)s_FieldInfos.GetUnsafeReadOnlyPtr() + lookup.Index, lookup.Count, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS // This handle isn't correct but collections makes this way more difficult than this needs to be // and we know s_TypeInfos has the same lifetime and readonly requirement as the fieldinfos var handle = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(s_TypeInfos); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, handle); #endif return(array); }
public static unsafe void Execute(ref TOutput data, IntPtr userData, IntPtr method, ref JobRanges ranges, int jobIndex) { var methodID = (MethodID)method.ToInt32(); switch (methodID) { case MethodID.BeginMix: { var champleCount = userData.ToInt32(); data.BeginMix(champleCount); break; } case MethodID.EndMix: { UnsafeUtility.CopyPtrToStructure(userData.ToPointer(), out EndMixData endMixData); var length = endMixData.ChannelCount * endMixData.ChampleCount; var nativeBuffer = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <float>(endMixData.Buffer, length, Allocator.Invalid); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref nativeBuffer, endMixData.Safety); #endif var frameCount = endMixData.ChampleCount / endMixData.ChannelCount; data.EndMix(nativeBuffer, frameCount); break; } case MethodID.Dispose: { data.Dispose(); break; } case MethodID.Initialize: { var initializationData = (InitializationData *)userData; data.Initialize(initializationData->ChannelCount, initializationData->SoundFormat, initializationData->SampleRate, initializationData->DSPBufferSize); break; } default: throw new ArgumentOutOfRangeException(); } }
internal NativeArray <byte> GetTypeMask(int typeIndex) { var view = GetMaskView(typeIndex); unsafe { var result = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte> ( view.Ptr, view.LengthInBytes, Allocator.None ); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref result, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(MaskBuffer)); #endif return(result); } }
public void Execute() { long sum = 0; // reconstruct the native array for the Burst Job void * ptr = (void *)arrPtr[0]; NativeArray <int> array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <int>(ptr, arrLen[0], Allocator.None); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, AtomicSafetyHandle.Create()); for (int i = 0; i < arrLen[0]; i++) { sum = sum + array[i] + 1; } output[0] = sum; }
public static unsafe void FromString(this DynamicBuffer <char> buffer, string name) { if (string.IsNullOrEmpty(name)) { buffer.Clear(); return; } fixed(char *ptr = name) { var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <char>(ptr, name.Length, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, AtomicSafetyHandle.Create()); #endif buffer.CopyFrom(array); } }
private unsafe void HandlePositionsChangedCallback(int count, IntPtr positionsIntPtr) { if (Tilemap.tilemapPositionsChanged == null) { return; } void *positionsPtr = positionsIntPtr.ToPointer(); var positions = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Vector3Int>(positionsPtr, count, Allocator.Invalid); var safety = AtomicSafetyHandle.Create(); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref positions, safety); SendTilemapPositionsChangedCallback(positions); AtomicSafetyHandle.CheckDeallocateAndThrow(safety); AtomicSafetyHandle.Release(safety); }
public unsafe NativeArray <T> GetData <T>(int layer = 0) where T : struct { if (!done || hasError) { throw new InvalidOperationException("Cannot access the data as it is not available"); } if (layer < 0 || layer >= layerCount) { throw new ArgumentException(string.Format("Layer index is out of range {0} / {1}", layer, layerCount)); } int stride = UnsafeUtility.SizeOf <T>(); var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>((void *)GetDataRaw(layer), layerDataSize / stride, Allocator.None); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, GetSafetyHandle()); return(array); }
public unsafe static void SetData (this ComputeBuffer buffer, IntPtr pointer, int count, int stride) { // NativeArray view for the unmanaged memory block var view = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte> ((void *)pointer, count * stride, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS var safety = AtomicSafetyHandle.Create(); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref view, safety); #endif buffer.SetData(view); #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.Release(safety); #endif }
private static unsafe void OnSceneContactModify(PhysicsScene scene, IntPtr buffer, int count, bool isCCD) { var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ModifiableContactPair>(buffer.ToPointer(), count, Allocator.None); var safety = AtomicSafetyHandle.Create(); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, safety); if (!isCCD) { ContactModifyEvent?.Invoke(scene, array); } else { ContactModifyEventCCD?.Invoke(scene, array); } AtomicSafetyHandle.Release(safety); }
GetNativeArray <T>(this ReadOnlySpan <T> span) where T : unmanaged { unsafe { fixed(void *ptr = &span.GetPinnableReference()) { var array = NativeArrayUnsafeUtility. ConvertExistingDataToNativeArray <T> (ptr, span.Length, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS var handle = AtomicSafetyHandle.GetTempUnsafePtrSliceHandle(); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, handle); #endif return(array); } } }