Advertisement
cajphrase

HashMapVoxelDataStore

Aug 15th, 2024
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.46 KB | None | 0 0
  1. struct VoxelData
  2. {
  3.     StackArray8<float> data;
  4. }
  5.  
  6. interface IVoxelDataStore
  7. {
  8.     VoxelBounds voxelBounds { get; }
  9.     int ParallelForEachCount { get; }
  10.     bool TryGetCellData(int cellIndex, out VoxelData cellData);
  11.     void StoreForEach<T>(int i, ref T voxelDataSource) where T : VoxelDataSource;
  12. }
  13.  
  14.  
  15. public struct HashMapVoxelDataStore : IVoxelDataStore
  16. {
  17.     VoxelBounds voxelBounds;
  18.     NativeParallelHashMap<int, VoxelData> data;
  19.    
  20.     public int ParallelForEachCount => (1 << startingSubdivisions) ^ 3;
  21.     private int startingSubdivisions => 1;
  22.  
  23.     public bool TryGetCellData(int cellIndex, out VoxelData cellData)
  24.     {
  25.         return data.TryGetValue(int cellIndex, out cellData);
  26.     }
  27.  
  28.     struct SubCell
  29.     {
  30.         public int3 min;
  31.         public int3 max;
  32.     }
  33.  
  34.     public void StoreForEach<T>(int i, ref T voxelDataSource) where T : VoxelDataSource
  35.     {
  36.         // for the recursive subdivision process to work, we would need to ensure the voxelBounds are a power of 2.
  37.         // at the moment we sometimes add a skirt making the bounds +2 above a power of 2.
  38.         // instead we need to use integer division to our advantage
  39.         var mid = voxelBounds.cubeCount / 2;
  40.         var min = mafs.ToBinaryInt3(i) * mid;
  41.         var max = mafs.lerp(mid, voxelBounds.cubeCount, mafs.ToBinaryInt3(i));
  42.  
  43.         var stack = new NativeStack<SubCell>(voxelBounds.subdivs, Allocator.Temp);
  44.         stack.Push(new SubCell(min, max));
  45.         while (stack.Count > 0)
  46.         {
  47.             var subCell = stack.Pop();
  48.             var diff = subCell.max - subCell.min;
  49.             if (mafs.all(diff == 0))
  50.             {
  51.                 var vd = new VoxelData();
  52.                 for (int j = 0; j < 8; j++)
  53.                 {
  54.                     var cnrIdx = voxelBounds.CubeToCornerIndex(subCell.min, j);
  55.                     var pos = voxelBounds.CornerIndexToPosition(cnrIdx);
  56.                     vd[i] = voxelDataSource.Sample(pos);
  57.                 }
  58.                 data.Add(subCell.min);
  59.                 continue;
  60.             }
  61.            
  62.             var size = (subCell.max - subCell.min + 1) * voxelBounds.cellSize;
  63.             var pos = voxelBounds.CubeIndexToPosition(subCell.min) + size / 2;
  64.             var sample = voxelDataSource.Sample(pos);
  65.             const float e = 0.0001f;
  66.             var dx = (voxelDataSource.Sample(pos + new float3(e, 0, 0)) - sample) / e;
  67.             var dy = (voxelDataSource.Sample(pos + new float3(0, e, 0)) - sample) / e;
  68.             var dz = (voxelDataSource.Sample(pos + new float3(0, 0, e)) - sample) / e;
  69.             var grad = new float3(dx, dy, dz);
  70.             var distToSurface = mafs.abs(sample / grad);
  71.             if (all(distToSurface / size) > 2) // 4x min distance should be a safe enough fudge factor
  72.             {
  73.                 continue;
  74.             }
  75.  
  76.             var half = diff / 2;
  77.             mid = subCell.min + half;
  78.             for (int j = 0; j < 8; j++)
  79.             {
  80.                 var k = mafs.ToBinaryInt3(j);
  81.                 min = mafs.lerp(subCell.min, mid, k);
  82.                 max = mafs.lerp(mid, subCell.max, k);
  83.                 stack.Push(new SubCell(min, max));
  84.             }
  85.         }
  86.     }
  87. }
  88.  
  89. public struct GenerateVoxelDataJob<T, U> : IJobParallelFor
  90.     where T : IVoxelDataStore
  91.     where U : IVoxelDataSource
  92. {
  93.     public T voxelDataStore;
  94.     public U voxelDataSource;
  95.  
  96.     public void Execute(int i)
  97.     {
  98.         voxelDataStore.StoreForEach(i, ref voxelDataSource);
  99.     }
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement