Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Creating a RenderMesh from within a job

Discussion in 'Graphics for ECS' started by Matt_De_Boss_Developer, Nov 28, 2019.

  1. Matt_De_Boss_Developer

    Matt_De_Boss_Developer

    Joined:
    Oct 17, 2014
    Posts:
    46
    So I basically have a list of vertices, triangles, and normals that I would like to draw. They are created from a job, but I am having issues with creating a mesh for the RenderMesh component. Basically, I cannot edit a mesh from within a job because it is not a value type. So, how would I create a RenderMesh component with all my data from within a job. I need to do it within a job because all of my data for the mesh is also generated within a job and I would like to avoid sync points. Code below:

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Jobs;
    3. using Unity.Collections;
    4. using Unity.Burst;
    5. using UnityEngine;
    6. using Unity.Rendering;
    7.  
    8. using static Unity.Mathematics.math;
    9.  
    10. using Unity.Mathematics;
    11. public class ChunkMeshingSystem : JobComponentSystem
    12. {
    13.     EntityQuery chunksQuery; //and entity query that will grab all the chunks currently in the world
    14.     NativeArray<Entity> chunks;
    15.     Entity chunk;
    16.  
    17.     NativeHashMap<uint, Edge> activeEdges;
    18.     NativeHashMap<uint, uint> activeVoxels;
    19.     NativeHashMap<uint, uint> vertexIndices;
    20.  
    21.  
    22.     NativeArray<int4> AXIS_OFFSET;
    23.     NativeArray<int4> EDGE_NODE_OFFSETS;
    24.     NativeArray<uint> ENCODED_EDGE_OFFSETS;
    25.     NativeArray<uint> ENCODED_EDGE_NODE_OFFSETS;
    26.  
    27.  
    28.     NativeList<float3> vertices;
    29.     NativeList<float3> normals;
    30.     NativeList<int> triangles;
    31.  
    32.  
    33.     static int4[] AXIS_OFFSET_ARRAY =
    34.     {
    35.         int4(1, 0, 0, 0),
    36.         int4(0, 1, 0, 0),
    37.         int4(0, 0, 1, 0)
    38.     };
    39.  
    40.     static int4[] EDGE_NODE_OFFSETS_ARRAY =
    41.     {
    42.         int4(0), int4(0, 0, 1, 0), int4(0, 1, 0, 0), int4(0, 1, 1, 0),
    43.         int4(0), int4(1, 0, 0, 0), int4(0, 0, 1, 0), int4(1, 0, 1, 0),
    44.         int4(0), int4(0, 1, 0, 0), int4(1, 0, 0, 0), int4(1, 1, 0, 0),
    45.     };
    46.  
    47.     static uint[] ENCODED_EDGE_OFFSETS_ARRAY =
    48.         {
    49.         0x00000000,
    50.         0x00100000,
    51.         0x00000400,
    52.         0x00100400,
    53.         0x40000000,
    54.         0x40100000,
    55.         0x40000001,
    56.         0x40100001,
    57.         0x80000000,
    58.         0x80000400,
    59.         0x80000001,
    60.         0x80000401
    61.         };
    62.  
    63.  
    64.     static uint[] ENCODED_EDGE_NODE_OFFSETS_ARRAY =
    65.     {
    66.         0x00000000,
    67.         0x00100000,
    68.         0x00000400,
    69.         0x00100400,
    70.         0x00000000,
    71.         0x00000001,
    72.         0x00100000,
    73.         0x00100001,
    74.         0x00000000,
    75.         0x00000400,
    76.         0x00000001,
    77.         0x00000401,
    78.     };
    79.  
    80.  
    81.     protected override void OnCreate()
    82.     {
    83.         chunksQuery = World.Active.EntityManager.CreateEntityQuery(typeof(NeedsMeshing)); //initialize the chunk query to grab everything with "ChunkInfo" on it
    84.  
    85.         activeEdges = new NativeHashMap<uint, Edge>(64 * 64 * 64 * 3, Allocator.Persistent);
    86.         activeVoxels = new NativeHashMap<uint, uint>(64 * 64 * 64, Allocator.Persistent);
    87.         vertexIndices = new NativeHashMap<uint, uint>(64 * 64 * 64, Allocator.Persistent);
    88.  
    89.         vertices = new NativeList<float3>(64 * 64 * 64, Allocator.Persistent);
    90.         normals = new NativeList<float3>(64 * 64 * 64, Allocator.Persistent);
    91.         triangles = new NativeList<int>(64 * 64 * 64, Allocator.Persistent);
    92.  
    93.         AXIS_OFFSET = new NativeArray<int4>(3, Allocator.Persistent);
    94.         AXIS_OFFSET.CopyFrom(AXIS_OFFSET_ARRAY);
    95.  
    96.         EDGE_NODE_OFFSETS = new NativeArray<int4>(12, Allocator.Persistent);
    97.         EDGE_NODE_OFFSETS.CopyFrom(EDGE_NODE_OFFSETS_ARRAY);
    98.  
    99.         ENCODED_EDGE_OFFSETS = new NativeArray<uint>(12, Allocator.Persistent);
    100.         ENCODED_EDGE_OFFSETS.CopyFrom(ENCODED_EDGE_OFFSETS_ARRAY);
    101.  
    102.         ENCODED_EDGE_NODE_OFFSETS = new NativeArray<uint>(12, Allocator.Persistent);
    103.         ENCODED_EDGE_NODE_OFFSETS.CopyFrom(ENCODED_EDGE_NODE_OFFSETS_ARRAY);
    104.  
    105.  
    106.     }
    107.  
    108.     [BurstCompile]
    109.     public struct ClearBuffersJob : IJob
    110.     {
    111.         public NativeHashMap<uint, Edge> activeEdges;
    112.         public NativeHashMap<uint, uint> activeVoxels;
    113.         public NativeHashMap<uint, uint> vertexIndices;
    114.  
    115.  
    116.         public NativeList<float3> vertices;
    117.         public NativeList<float3> normals;
    118.         public NativeList<int> triangles;
    119.  
    120.         public void Execute()
    121.         {
    122.             activeEdges.Clear();
    123.             activeVoxels.Clear();
    124.             vertices.Clear();
    125.             normals.Clear();
    126.             vertexIndices.Clear();
    127.             triangles.Clear();
    128.         }
    129.     }
    130.  
    131.  
    132.     [BurstCompile]
    133.     public struct assembleRenderMeshJob : IJob
    134.     {
    135.  
    136.         public NativeList<float3> vertices;
    137.         public NativeList<float3> normals;
    138.         public NativeList<int> triangles;
    139.  
    140.         public RenderMesh renderMesh;
    141.  
    142.         public Entity chunk;
    143.  
    144.         public EntityManager em;
    145.  
    146.         public void Execute()
    147.         {
    148.             renderMesh.mesh.SetVertices(vertices.AsArray());
    149.             renderMesh.mesh.SetNormals(normals.AsArray());
    150.             renderMesh.mesh.SetIndices(triangles.AsArray(), MeshTopology.Triangles, 0);
    151.  
    152.  
    153.             em.AddSharedComponentData<RenderMesh>(chunk, renderMesh);
    154.  
    155.         }
    156.     }
    157.  
    158.  
    159.  
    160.  
    161.  
    162.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    163.     {
    164.  
    165.         chunks = chunksQuery.ToEntityArray(Allocator.TempJob);
    166.  
    167.         if(chunks.Length == 0)
    168.         {
    169.             chunks.Dispose();
    170.             return inputDeps;
    171.         }
    172.  
    173.         chunk = chunks[0];
    174.         chunks.Dispose();
    175.         EntityManager.RemoveComponent<NeedsMeshing>(chunk);
    176.  
    177.         ChunkInfo chunkInfo = EntityManager.GetComponentData<ChunkInfo>(chunk);
    178.  
    179.         RenderMesh renderMesh = new RenderMesh()
    180.         {
    181.          
    182.  
    183.         };
    184.  
    185.  
    186.         var ClearBuffers = new ClearBuffersJob()
    187.         {
    188.             activeEdges = activeEdges,
    189.             activeVoxels = activeVoxels,
    190.             vertexIndices = vertexIndices,
    191.             vertices = vertices,
    192.             normals = normals,
    193.             triangles = triangles
    194.  
    195.         };
    196.  
    197.         var FindActiveVoxels = new FindActiveVoxelsAndEdgesJobs() {
    198.             activeEdges = activeEdges.AsParallelWriter(),
    199.             activeVoxels = activeVoxels.AsParallelWriter(),
    200.             AXIS_OFFSET = AXIS_OFFSET,
    201.             EDGE_NODE_OFFSETS = EDGE_NODE_OFFSETS,
    202.             voxelData = EntityManager.GetBuffer<VoxelData>(chunk).Reinterpret<float>().ToNativeArray(Allocator.TempJob),
    203.             SizeX = chunkInfo.size.x,
    204.             SizeY = chunkInfo.size.y,
    205.         };
    206.  
    207.         var GenerateVertexData = new GenerateVertexDataJob
    208.         {
    209.             activeEdges = activeEdges,
    210.             activeVoxels = activeVoxels,
    211.             vertexIndices = vertexIndices,
    212.             vertices = vertices,
    213.             normals = normals,
    214.             ENCODED_EDGE_OFFSETS = ENCODED_EDGE_OFFSETS
    215.            
    216.         };
    217.  
    218.         var GenerateTriangleData = new GenerateTriangleDataJob
    219.         {
    220.             activeEdges = activeEdges,
    221.             vertexIndices = vertexIndices,
    222.             triangles = triangles,
    223.             ENCODED_EDGE_NODE_OFFSETS = ENCODED_EDGE_NODE_OFFSETS
    224.         };
    225.  
    226.         var AssembleRenderMesh = new assembleRenderMeshJob
    227.         {
    228.             renderMesh = renderMesh,
    229.             vertices = vertices,
    230.             normals = normals,
    231.             triangles = triangles,
    232.             em = EntityManager,
    233.             chunk = chunk
    234.  
    235.         };
    236.  
    237.         JobHandle clearBufferHandle = ClearBuffers.Schedule(inputDeps);
    238.         JobHandle FindActiveVoxelsHandle = FindActiveVoxels.Schedule(chunkInfo.size.x * chunkInfo.size.y * chunkInfo.size.z, 1, clearBufferHandle);
    239.         JobHandle GenerateVertexDataHandle = GenerateVertexData.Schedule(FindActiveVoxelsHandle);
    240.         JobHandle GenerateTriangleDataHandle = GenerateTriangleData.Schedule(GenerateVertexDataHandle);
    241.  
    242.         return GenerateTriangleDataHandle;
    243.  
    244.  
    245.     }
    246.     protected override void OnDestroy()
    247.     {
    248.         activeEdges.Dispose();
    249.         activeVoxels.Dispose();
    250.         vertexIndices.Dispose();
    251.  
    252.         vertices.Dispose();
    253.         normals.Dispose();
    254.         triangles.Dispose();
    255.  
    256.         AXIS_OFFSET.Dispose();
    257.         EDGE_NODE_OFFSETS.Dispose();
    258.         ENCODED_EDGE_OFFSETS.Dispose();
    259.         ENCODED_EDGE_NODE_OFFSETS.Dispose();
    260.     }
    261. }
    262.  
     
    Kuptsevych-Yuriy likes this.
  2. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    242
    Did you find a solution for mesh updates?