Search Unity

NativeArray for Meshes?

Discussion in 'Entity Component System' started by Robber33, Nov 14, 2018.

  1. Robber33

    Robber33

    Joined:
    Feb 22, 2015
    Posts:
    52
    Hi!

    I am super impressed with the jobsystem and burstcompiler!
    you guys have done an amazing job.

    as a new project to experiment with ECS i'm working on a procedurally generated terrain.
    the job system takes care of generating blocks of vertex and normal data which i stream back to the mainthread to a quadtree.

    right now there is a lot of complex managing involved, i schedule a couple of terrainslabs that need updating and the next frame i slice up the data i get from the job and put it back into meshes.

    right now actually copying nativearray slices to the mesh takes up 80% of the time of the terrain generating process, depending how much slabs i schedule in at a time. Still its a huge performance boost.

    Code (CSharp):
    1.    
    2. //vertices and normals are native arrays
    3. //mesh_ arrays are managed / regular arrays
    4. Mesh m = new Mesh();
    5.                    
    6. vertices.Slice(i*vertx_per_slice,vertx_per_slice).CopyTo(mesh_vertices);
    7. normals.Slice(i*vertx_per_slice,vertx_per_slice).CopyTo(mesh_normals);
    8.  
    9. m.vertices=mesh_vertices;
    10. m.normals=mesh_normals;
    11.  
    12. m.uv=mesh_UVs;
    13. m.SetIndices(mesh_triangles,MeshTopology.Triangles,0,false);
    14. m.bounds=mesh_bounds;
    15.  
    16. mesh_filters[scheduled_slab].mesh = m;
    17.  
    Is there a way to update meshes in a job ? or a better way to manipulate meshes then copying from nativeArray to the mesh ? or maybe only manipulate the vertex data and normal data ? my triangle and uv layout are the same for each terrain piece so can i keep them as native memory. Any future plans for this ?

    thanx!

    Rob
     
  2. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    You could pin the managed/reference array, and pass the pointer to the job and do the operation straight on it instead.
     
  3. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    For claritys sake, example code:

    Code (csharp):
    1.  
    2. Vector3[] vertices = new Vector3[1024];
    3. var handle = GCHandle.Alloc(vertices, GCHandleType.Pinned);
    4. var ptr = (Vector3*)handle.AddrOfPinnedObject().ToPointer()
    5.  
    Just be aware that you need to unpin the array when the job is done, etc.

    Edit: Whops... i made a new post instead of editing my old one... it's late, my bad.
     
    Orimay likes this.
  4. Robber33

    Robber33

    Joined:
    Feb 22, 2015
    Posts:
    52
    thank you for the response, can you elaborate a little ?
    I have no idea how to approach your suggestion :)
     
  5. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Replied with an example in a second post, should've edited the first one... my bad.
     
  6. Robber33

    Robber33

    Joined:
    Feb 22, 2015
    Posts:
    52
    thanks for the example!
    so i would pass the pointer to the job ?
    my jobs are IJobParallelFor

    Im gonna do some reseach on pinning / unpinning
     
  7. Robber33

    Robber33

    Joined:
    Feb 22, 2015
    Posts:
    52
    I found this thread and i prefer to do a custom copy
    https://forum.unity.com/threads/allow-setting-mesh-arrays-with-nativearrays.536736/

    but I right now i'm using NativeSlice, to process a couple of meshes in one job.
    Is there a way to get a pointer to a specific adress in nativeArray ?

    I'm using the following code to copy, but preferable i would specify a starting point for the nativebuffer ? similar to AddressOf for the managed array

    Code (CSharp):
    1.      
    2. int byteLength = nativeArray.Length * Marshal.SizeOf(default(T));
    3. void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]);
    4. void* nativeBuffer = nativeArray.GetUnsafePtr();
    5. Buffer.MemoryCopy(nativeBuffer, managedBuffer, byteLength, byteLength);
    6.  
     
  8. Robber33

    Robber33

    Joined:
    Feb 22, 2015
    Posts:
    52
    ok found it,
    there is also NativeSlice.GetUnsafePtr