Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Unity.Jobs;
- using Unity.Burst;
- using Unity.Mathematics;
- using Unity.Collections;
- using Voxels;
- namespace MarchingCubesAlgorithm
- {
- [BurstCompile]
- public struct MarchingCubesJob : IJobParallelFor
- {
- [ReadOnly] public int3 gridSize;
- [ReadOnly] public NativeVoxelGrid voxelGrid;
- public NativeQueue<Triangle>.ParallelWriter triangles;
- public void Execute(int i)
- {
- int3 index3D = Calculate3DIndex(i);
- MarchCube(index3D.x, index3D.y, index3D.z);
- }
- private void MarchCube(int x, int y, int z)
- {
- int voxelCase = GenerateCase(x, y, z);
- int numTris = LookupTables.caseToNumTris[voxelCase];
- int edgeStartIndex = voxelCase * 15;
- for (int i = 0; i < numTris; i++)
- {
- int triEdge0 = LookupTables.caseToTriEdges1D[edgeStartIndex + i * 3];
- int triEdge1 = LookupTables.caseToTriEdges1D[edgeStartIndex + i * 3 + 1];
- int triEdge2 = LookupTables.caseToTriEdges1D[edgeStartIndex + i * 3 + 2];
- float3 vertex0 = InterpolateVertex(triEdge0, x, y, z);
- float3 vertex1 = InterpolateVertex(triEdge1, x, y, z);
- float3 vertex2 = InterpolateVertex(triEdge2, x, y, z);
- triangles.Enqueue(new Triangle()
- {
- vertex0 = vertex0,
- vertex1 = vertex1,
- vertex2 = vertex2
- });
- }
- }
- private int GenerateCase(int x, int y, int z)
- {
- NativeArray<float> corners = GetCubeCornerValues(x, y, z);
- int caseByte = 0;
- // a |= b shorthand for a = a | b with | the bitwise OR operator.
- // 1 << i bitshifts the number 1 (0b_0000_0001) i bits to the left
- for (int i = 0; i < 8; i++)
- if (corners[i] > 0) { caseByte |= 1 << i; }
- corners.Dispose();
- return caseByte;
- }
- // Change to raw grid if this is slow
- // X, Y, Z is the bottom left corner
- private NativeArray<float> GetCubeCornerValues(int x, int y, int z)
- {
- var corners = new NativeArray<float>(8, Allocator.Temp);
- corners[0] = voxelGrid.Get(x, y, z);
- corners[1] = voxelGrid.Get(x, y + 1, z);
- corners[2] = voxelGrid.Get(x + 1, y + 1, z);
- corners[3] = voxelGrid.Get(x + 1, y, z);
- corners[4] = voxelGrid.Get(x, y, z + 1);
- corners[5] = voxelGrid.Get(x, y + 1, z + 1);
- corners[6] = voxelGrid.Get(x + 1, y + 1, z + 1);
- corners[7] = voxelGrid.Get(x + 1, y, z + 1);
- return corners;
- }
- private float3 InterpolateVertex(int edge, int x, int y, int z)
- {
- int3 edgeCorner0 = LookupTables.nativeEdgeToCorners[edge * 2];
- int3 edgeCorner1 = LookupTables.nativeEdgeToCorners[edge * 2 + 1];
- int3 p0 = edgeCorner0;
- int3 p1 = edgeCorner1;
- float v0 = voxelGrid.Get(x + p0.x, y + p0.y, z + p0.z);
- float v1 = voxelGrid.Get(x + p1.x, y + p1.y, z + p1.z);
- float isolevel = 0f;
- float t = (isolevel - v0) / (v1 - v0);
- 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);
- return vertexPosition;
- }
- private int3 Calculate3DIndex(int i)
- {
- int area = (gridSize.x - 1) * (gridSize.y - 1);
- int z = i / area;
- int rem = i % area;
- int y = rem / (gridSize.x - 1);
- int x = rem % (gridSize.x - 1);
- return new int3(x, y, z);
- }
- }
- public struct Triangle
- {
- public float3 vertex0;
- public float3 vertex1;
- public float3 vertex2;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement