Advertisement
JontePonte

parallel marchin cubes

Jun 26th, 2025
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.95 KB | None | 0 0
  1. using Unity.Jobs;
  2. using Unity.Burst;
  3. using Unity.Mathematics;
  4. using Unity.Collections;
  5. using Voxels;
  6.  
  7. namespace MarchingCubesAlgorithm
  8. {
  9.     [BurstCompile]
  10.     public struct MarchingCubesJob : IJobParallelFor
  11.     {
  12.         [ReadOnly] public int3 gridSize;
  13.         [ReadOnly] public NativeVoxelGrid voxelGrid;
  14.  
  15.         public NativeQueue<Triangle>.ParallelWriter triangles;
  16.  
  17.         public void Execute(int i)
  18.         {
  19.             int3 index3D = Calculate3DIndex(i);
  20.             MarchCube(index3D.x, index3D.y, index3D.z);
  21.         }
  22.  
  23.         private void MarchCube(int x, int y, int z)
  24.         {
  25.             int voxelCase = GenerateCase(x, y, z);
  26.  
  27.             int numTris = LookupTables.caseToNumTris[voxelCase];
  28.             int edgeStartIndex = voxelCase * 15;
  29.  
  30.             for (int i = 0; i < numTris; i++)
  31.             {
  32.                 int triEdge0 = LookupTables.caseToTriEdges1D[edgeStartIndex + i * 3];
  33.                 int triEdge1 = LookupTables.caseToTriEdges1D[edgeStartIndex + i * 3 + 1];
  34.                 int triEdge2 = LookupTables.caseToTriEdges1D[edgeStartIndex + i * 3 + 2];
  35.  
  36.                 float3 vertex0 = InterpolateVertex(triEdge0, x, y, z);
  37.                 float3 vertex1 = InterpolateVertex(triEdge1, x, y, z);
  38.                 float3 vertex2 = InterpolateVertex(triEdge2, x, y, z);
  39.  
  40.                 triangles.Enqueue(new Triangle()
  41.                 {
  42.                     vertex0 = vertex0,
  43.                     vertex1 = vertex1,
  44.                     vertex2 = vertex2
  45.                 });
  46.             }
  47.         }
  48.  
  49.         private int GenerateCase(int x, int y, int z)
  50.         {
  51.             NativeArray<float> corners = GetCubeCornerValues(x, y, z);
  52.             int caseByte = 0;
  53.  
  54.             // a |= b shorthand for a = a | b with | the bitwise OR operator.
  55.             // 1 << i bitshifts the number 1 (0b_0000_0001) i bits to the left
  56.             for (int i = 0; i < 8; i++)
  57.                 if (corners[i] > 0) { caseByte |= 1 << i; }
  58.  
  59.             corners.Dispose();
  60.  
  61.             return caseByte;
  62.         }
  63.  
  64.         // Change to raw grid if this is slow
  65.         // X, Y, Z is the bottom left corner
  66.         private NativeArray<float> GetCubeCornerValues(int x, int y, int z)
  67.         {
  68.             var corners = new NativeArray<float>(8, Allocator.Temp);
  69.  
  70.             corners[0] = voxelGrid.Get(x, y, z);
  71.             corners[1] = voxelGrid.Get(x, y + 1, z);
  72.             corners[2] = voxelGrid.Get(x + 1, y + 1, z);
  73.             corners[3] = voxelGrid.Get(x + 1, y, z);
  74.             corners[4] = voxelGrid.Get(x, y, z + 1);
  75.             corners[5] = voxelGrid.Get(x, y + 1, z + 1);
  76.             corners[6] = voxelGrid.Get(x + 1, y + 1, z + 1);
  77.             corners[7] = voxelGrid.Get(x + 1, y, z + 1);
  78.  
  79.             return corners;
  80.         }
  81.  
  82.         private float3 InterpolateVertex(int edge, int x, int y, int z)
  83.         {
  84.             int3 edgeCorner0 = LookupTables.nativeEdgeToCorners[edge * 2];
  85.             int3 edgeCorner1 = LookupTables.nativeEdgeToCorners[edge * 2 + 1];
  86.  
  87.             int3 p0 = edgeCorner0;
  88.             int3 p1 = edgeCorner1;
  89.  
  90.             float v0 = voxelGrid.Get(x + p0.x, y + p0.y, z + p0.z);
  91.             float v1 = voxelGrid.Get(x + p1.x, y + p1.y, z + p1.z);
  92.  
  93.             float isolevel = 0f;
  94.             float t = (isolevel - v0) / (v1 - v0);
  95.  
  96.             float3 vertexPosition = new float3(x + p0.x, y + p0.y, z + p0.z) + t * new float3(p1.x - p0.x, p1.y - p0.y, p1.z - p0.z);
  97.             return vertexPosition;
  98.         }
  99.  
  100.         private int3 Calculate3DIndex(int i)
  101.         {
  102.             int area = (gridSize.x - 1) * (gridSize.y - 1);
  103.  
  104.             int z = i / area;
  105.             int rem = i % area;
  106.  
  107.             int y = rem / (gridSize.x - 1);
  108.             int x = rem % (gridSize.x - 1);
  109.  
  110.             return new int3(x, y, z);
  111.         }
  112.  
  113.     }
  114.  
  115.     public struct Triangle
  116.     {
  117.         public float3 vertex0;
  118.         public float3 vertex1;
  119.         public float3 vertex2;
  120.     }
  121. }
  122.  
  123.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement