-
-
Save DaZombieKiller/b42e5847d650781a2dadc64695504f95 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#nullable enable | |
using System; | |
using System.Collections.Generic; | |
using System.Runtime.CompilerServices; | |
namespace NewBlood.Collections | |
{ | |
public static class ListUtility | |
{ | |
public static T[] GetUnderlyingArray<T>(List<T> list) | |
{ | |
if (list == null) | |
throw new ArgumentNullException(nameof(list)); | |
return Unsafe.As<RawList<T>>(list)._items; | |
} | |
class RawList<T> | |
{ | |
#pragma warning disable CS0649 | |
#pragma warning disable CS8618 | |
public T[] _items; | |
#pragma warning restore CS8618 | |
public int _size; | |
public int _version; | |
#pragma warning restore CS0649 | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
namespace NewBlood.Rendering | |
{ | |
public readonly struct MeshDataArraySegment | |
{ | |
public Mesh.MeshDataArray Array { get; } | |
public int Offset { get; } | |
public int Count { get; } | |
public MeshDataArraySegment(Mesh.MeshDataArray array, int offset, int count) | |
{ | |
#if UNITY_64 | |
if ((ulong)offset + (ulong)count > (ulong)array.Length) | |
throw new ArgumentOutOfRangeException(); | |
#else | |
if ((uint)offset > (uint)array.Length || (uint)count > (uint)(array.Length - offset)) | |
throw new ArgumentOutOfRangeException(); | |
#endif | |
Array = array; | |
Offset = offset; | |
Count = count; | |
} | |
public Mesh.MeshData this[int index] | |
{ | |
get | |
{ | |
if ((uint)index >= (uint)Count) | |
throw new IndexOutOfRangeException(); | |
return Array[Offset + index]; | |
} | |
} | |
public static implicit operator MeshDataArraySegment(Mesh.MeshDataArray array) | |
{ | |
return new MeshDataArraySegment(array, 0, array.Length); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
using System.Collections.Generic; | |
using System.Runtime.CompilerServices; | |
using UnityEngine; | |
using UnityEngine.Rendering; | |
using Unity.Collections.LowLevel.Unsafe; | |
using NewBlood.Collections; | |
namespace NewBlood.Rendering | |
{ | |
public static class MeshDataExtensions | |
{ | |
public static unsafe void ApplyToMeshes(ref this Mesh.MeshDataArray array, List<Mesh> meshes, MeshUpdateFlags flags = MeshUpdateFlags.Default) | |
{ | |
ApplyToMeshes(ref array, ListUtility.GetUnderlyingArray(meshes), flags); | |
} | |
public static unsafe void ApplyToMeshes(ref this Mesh.MeshDataArray array, Mesh[] meshes, MeshUpdateFlags flags = MeshUpdateFlags.Default) | |
{ | |
s_ApplyToMeshes(meshes, GetPointers(array), array.Length, flags); | |
} | |
public static unsafe void ApplyToMesh(ref this Mesh.MeshDataArray array, Mesh mesh, MeshUpdateFlags flags = MeshUpdateFlags.Default) | |
{ | |
s_ApplyToMesh(mesh, *GetPointers(array), flags); | |
} | |
public static unsafe void ApplyToMeshes(ref this MeshDataArraySegment array, List<Mesh> meshes, MeshUpdateFlags flags = MeshUpdateFlags.Default) | |
{ | |
ApplyToMeshes(ref array, ListUtility.GetUnderlyingArray(meshes), flags); | |
} | |
public static unsafe void ApplyToMeshes(ref this MeshDataArraySegment segment, Mesh[] meshes, MeshUpdateFlags flags = MeshUpdateFlags.Default) | |
{ | |
if (segment.Count == 0) | |
return; | |
s_ApplyToMeshes(meshes, GetPointers(segment.Array) + segment.Offset, segment.Count, flags); | |
} | |
public static unsafe void ApplyToMesh(ref this MeshDataArraySegment segment, Mesh mesh, MeshUpdateFlags flags = MeshUpdateFlags.Default) | |
{ | |
if (segment.Count == 0) | |
return; | |
s_ApplyToMesh(mesh, *(GetPointers(segment.Array) + segment.Offset), flags); | |
} | |
public static void ApplyToMesh(ref this Mesh.MeshData data, Mesh mesh, MeshUpdateFlags flags = MeshUpdateFlags.Default) | |
{ | |
s_ApplyToMesh(mesh, GetPointer(data), flags); | |
} | |
unsafe static IntPtr* GetPointers(Mesh.MeshDataArray array) | |
{ | |
return Unsafe.As<Mesh.MeshDataArray, RawMeshDataArray>(ref array).m_Ptrs; | |
} | |
static IntPtr GetPointer(Mesh.MeshData data) | |
{ | |
return Unsafe.As<Mesh.MeshData, RawMeshData>(ref data).m_Ptr; | |
} | |
static readonly ApplyToMeshesDelegate s_ApplyToMeshes = typeof(Mesh.MeshDataArray) | |
.GetMethod("ApplyToMeshesImpl", BindingFlags.Static | BindingFlags.NonPublic) | |
.CreateDelegate<ApplyToMeshesDelegate>(); | |
static readonly ApplyToMeshDelegate s_ApplyToMesh = typeof(Mesh.MeshDataArray) | |
.GetMethod("ApplyToMeshImpl", BindingFlags.Static | BindingFlags.NonPublic) | |
.CreateDelegate<ApplyToMeshDelegate>(); | |
unsafe delegate void ApplyToMeshesDelegate(Mesh[] meshes, IntPtr* datas, int count, MeshUpdateFlags flags); | |
delegate void ApplyToMeshDelegate(Mesh mesh, IntPtr data, MeshUpdateFlags flags); | |
unsafe struct RawMeshDataArray | |
{ | |
public IntPtr* m_Ptrs; | |
public int m_Length; | |
public int m_MinIndex; | |
public int m_MaxIndex; | |
public AtomicSafetyHandle m_Safety; | |
public DisposeSentinel m_DisposeSentinel; | |
} | |
struct RawMeshData | |
{ | |
public IntPtr m_Ptr; | |
public AtomicSafetyHandle m_Safety; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
namespace NewBlood | |
{ | |
public static class ReflectionExtensions | |
{ | |
public static T CreateDelegate<T>(this MethodInfo method) | |
where T : Delegate | |
{ | |
return (T)method.CreateDelegate(typeof(T)); | |
} | |
public static T CreateDelegate<T>(this MethodInfo method, object target) | |
where T : Delegate | |
{ | |
return (T)method.CreateDelegate(typeof(T), target); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment