Created
January 18, 2019 12:44
-
-
Save LotteMakesStuff/6198f966e414a88d1337b0360cb891f5 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
using System; | |
using Unity.Collections; | |
using Unity.Collections.LowLevel.Unsafe; | |
using Unity.Mathematics; | |
using UnityEngine; | |
public class NativeMesh : IDisposable | |
{ | |
public NativeArray<float3> VertexBuffer; | |
public NativeArray<float3> NormalBuffer; | |
public NativeArray<float2> UVBuffer; | |
public NativeArray<float2> UV2Buffer; | |
public NativeArray<float4> TangetBuffer; | |
public NativeArray<int> IndexBuffer; | |
public bool HasNormals, HasUV2s, HasTangents; | |
public bool IsInitialized; | |
public int TriangleCount; | |
public int VertexCount; | |
public NativeMesh(Mesh mesh) | |
{ | |
// copy the array data into a NativeArray. This lets us pass it into Jobs | |
var vertexArray = mesh.vertices; | |
VertexBuffer = GetNativeArray(vertexArray); | |
var triangleArray = mesh.triangles; | |
IndexBuffer = GetNativeArray(triangleArray); | |
var normalArray = mesh.normals; | |
HasNormals = normalArray.Length > 0; | |
if (HasNormals) | |
NormalBuffer = GetNativeArray(normalArray); | |
var uvArray = mesh.uv; | |
UVBuffer = GetNativeArray(uvArray); | |
var uv2Array = mesh.uv2; | |
HasUV2s = uv2Array.Length > 0; | |
if (HasUV2s) | |
UV2Buffer = GetNativeArray(uv2Array); | |
var tangentArray = mesh.tangents; | |
HasTangents = tangentArray.Length > 0; | |
if (HasTangents) | |
TangetBuffer = GetNativeArray(tangentArray); | |
// todo what happens if these change? | |
TriangleCount = triangleArray.Length / 3; | |
VertexCount = vertexArray.Length; | |
IsInitialized = true; | |
} | |
#region managed to native | |
unsafe NativeArray<float3> GetNativeArray(Vector3[] source) | |
{ | |
// create a destination NativeArray to hold the vertices | |
NativeArray<float3> verts = new NativeArray<float3>(source.Length, Allocator.Persistent, | |
NativeArrayOptions.UninitializedMemory); | |
// pin the mesh's vertex buffer in place... | |
fixed (void* vertexBufferPointer = source) | |
{ | |
// ...and use memcpy to copy the Vector3[] into a NativeArray<floar3> without casting. whould be fast! | |
UnsafeUtility.MemCpy(NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(verts), | |
vertexBufferPointer, source.Length * (long) UnsafeUtility.SizeOf<float3>()); | |
} | |
// we only hve to fix the .net array in place, the NativeArray is allocated in the C++ side of the engine and | |
// wont move arround unexpectedly. We have a pointer to it not a reference! thats basically what fixed does, | |
// we create a scope where its 'safe' to get a pointer and directly manipulate the array | |
return verts; | |
} | |
unsafe NativeArray<int> GetNativeArray(int[] source) | |
{ | |
NativeArray<int> verts = new NativeArray<int>(source.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); | |
fixed (void* vertexBufferPointer = source) | |
{ | |
UnsafeUtility.MemCpy(NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(verts), | |
vertexBufferPointer, source.Length * (long) UnsafeUtility.SizeOf<int>()); | |
} | |
return verts; | |
} | |
unsafe NativeArray<float2> GetNativeArray(Vector2[] source) | |
{ | |
NativeArray<float2> verts = new NativeArray<float2>(source.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); | |
fixed (void* vertexBufferPointer = source) | |
{ | |
UnsafeUtility.MemCpy(NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(verts), | |
vertexBufferPointer, source.Length * (long) UnsafeUtility.SizeOf<float2>()); | |
} | |
return verts; | |
} | |
unsafe NativeArray<float4> GetNativeArray(Vector4[] source) | |
{ | |
NativeArray<float4> verts = new NativeArray<float4>(source.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); | |
fixed (void* vertexBufferPointer = source) | |
{ | |
UnsafeUtility.MemCpy(NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(verts), | |
vertexBufferPointer, source.Length * (long) UnsafeUtility.SizeOf<float4>()); | |
} | |
return verts; | |
} | |
#endregion | |
#region native to managed | |
unsafe void CopyDataFromNativeArray(NativeArray<float2> source, Vector2[] target) | |
{ | |
// pin the target vertex array and get a pointer to it | |
fixed (void* vertexArrayPointer = target) | |
{ | |
// memcopy the native array over the top | |
UnsafeUtility.MemCpy(vertexArrayPointer, | |
NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(source), | |
target.Length * (long) UnsafeUtility.SizeOf<float2>()); | |
} | |
} | |
unsafe void CopyDataFromNativeArray(NativeArray<float3> source, Vector3[] target) | |
{ | |
fixed (void* vertexArrayPointer = target) | |
{ | |
UnsafeUtility.MemCpy(vertexArrayPointer, | |
NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(source), | |
target.Length * (long) UnsafeUtility.SizeOf<float3>()); | |
} | |
} | |
unsafe void CopyDataFromNativeArray(NativeArray<float4> source, Vector4[] target) | |
{ | |
fixed (void* vertexArrayPointer = target) | |
{ | |
UnsafeUtility.MemCpy(vertexArrayPointer, | |
NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(source), | |
target.Length * (long) UnsafeUtility.SizeOf<float4>()); | |
} | |
} | |
unsafe void CopyDataFromNativeArray(NativeArray<int> source, int[] target) | |
{ | |
fixed (void* vertexArrayPointer = target) | |
{ | |
UnsafeUtility.MemCpy(vertexArrayPointer, | |
NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(source), | |
target.Length * (long) UnsafeUtility.SizeOf<int>()); | |
} | |
} | |
#endregion | |
public void Dispose() | |
{ | |
VertexBuffer.Dispose(); | |
if (HasNormals) NormalBuffer.Dispose(); | |
if (HasUVs) UVBuffer.Dispose(); | |
if (HasUV2s) UV2Buffer.Dispose(); | |
if (HasTangents) TangetBuffer.Dispose(); | |
IndexBuffer.Dispose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment