Search Unity

Job System and minecraft like mesh generation question.

Discussion in 'C# Job System' started by Seto, May 9, 2018.

  1. Seto

    Seto

    Joined:
    Oct 10, 2010
    Posts:
    243
    The examples on the github are all about changing the existing vertices. How to make a vertices list with Job System? After I check posts in forum, it seems that NativeList is not thread safe. Then the indices may be changed over time.
     
  2. Seto

    Seto

    Joined:
    Oct 10, 2010
    Posts:
    243
    Anyone helps? How to create a collection instead of modify the collection. The examples in Job System Cookbook is modifying the data.
     
  3. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    You could probably use a NativeQueue for assembly and use an IJob to put into a NativeList if the order isn't important.

    You could split the work amongst smaller native lists (safe on IJob) and reassemble them into a master on another IJob (the AddRange function can take a NativeArray, and NativeList has an implicit operator for that sort of thing.

    If you need to assemble with a specific ordering and know the max index count you can use a NativeHashMap (which has a concurrent writer) for assembly with the intended index number as the key, then iterate through on an IJob to add to a list.
     
    Seto likes this.
  4. Seto

    Seto

    Joined:
    Oct 10, 2010
    Posts:
    243
    Thank you.
    The exception below is reported if I make it readonly.
    Code (CSharp):
    1.  
    2.         [ReadOnly]
    3.         public NativeHashMap<int, NativeList<Vector3>> verticesHashMap;
    4.  
    The exception below is reported if I make it without readonly.
     
  5. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    First off, most containers are paralell-write restricted for good reason, you can disable this safety check if you know what you're doing with the attribute
    NativeDisableParallelForRestriction
    , this can be useful for writing to certain structures if you ARE ABSOLUTELY CERTAIN UNIQUE VALUES WILL BE WRITTEN TO UNIQUE TARGET LOCATIONS.

    What I recommend for your case is this alternative, which maintains safety:

    NativeHashMap and NativeMultiHashMap both have a .Concurrent helper structure that supports parallel/cross-job writes (but no reads).

    You can then read from them in other threads AFTER you've finished writing to them.

    Try using NativeHashMap<int, NativeList<Vector3>>.Concurrent, and if it rejects having a container type as a value (it probably will), you can use a NativeMultiHashMap<int, Vector3> which is similar to a HashMap but it supports multiple values per key.

    You can then iterate like so:

    Code (CSharp):
    1. [ComputeJobOptimization]
    2. struct LinearizeMeshDataJob : IJob
    3. {
    4.     public int numParts;
    5.     [ReadOnly] public NativeMultiHashMap<int, Vector3> input;
    6.  
    7.     public NativeList<Vector3> output;
    8.  
    9.     public void Execute()
    10.     {
    11.         for(int i = 0; i < NumParts; ++i)
    12.         {
    13.             NativeMultiHashMapIterator<int> iterator;
    14.             Vector3 data;
    15.             var found = input.TryGetFirstValue(i, out data, out iterator);
    16.             while(found)
    17.             {
    18.                 output.Add(data);
    19.                 found = input.TryGetNextValue(out data, ref iterator);
    20.             }
    21.         }
    22.     }
    23. }
    If you dig into the Unity.Entities.Transforms package sources you can find TransformSystem.cs that builds and then updates the entire transform hierarchy. I wholeheartedly recommend it.

    I do something similar in an object dependency lifecycle management system I'm building.
     
    Seto likes this.