public void GenerateVertexList_Test1() { // Arrange VoxelCorners <byte> densities = new VoxelCorners <byte> { Corner1 = 255, Corner2 = 255, Corner3 = 255, Corner4 = 0, Corner5 = 255, Corner6 = 255, Corner7 = 255, Corner8 = 255 }; int edgeIndex = 0b1000_0000_1100; byte isolevel = 127; VertexList expected = new VertexList(); expected[2] = new float3(0.5f, 0f, 1f); expected[3] = new float3(0f, 0f, 0.5f); expected[11] = new float3(0f, 0.5f, 1f); // Act IEnumerable <float3> actual = MarchingCubesFunctions.GenerateVertexList(densities, new int3(0, 0, 0), edgeIndex, isolevel); // Assert for (int i = 0; i < 12; i++) { var actualPosition = actual.ElementAt(i); Assert.AreEqual(0, math.distance(expected[i], actualPosition), 0.011f, $"Expected: {expected[i]}, Actual: {actualPosition}"); } }
public void GenerateVertexList_Test3() { // Arrange VoxelCorners <byte> densities = new VoxelCorners <byte> { Corner1 = 140, Corner2 = 25, Corner3 = 189, Corner4 = 89, Corner5 = 192, Corner6 = 204, Corner7 = 255, Corner8 = 229 }; byte isolevel = 191; int edgeIndex = 0b1111_0000_0000; VertexList expected = new VertexList(); expected[8] = new float3(-56f, -0.02439022f, 9f); expected[9] = new float3(-55f, -0.07142866f, 9f); expected[10] = new float3(-55f, -0.9803922f, 10f); expected[11] = new float3(-56f, -0.272727272727f, 10f); // Act IEnumerable <float3> actual = MarchingCubesFunctions.GenerateVertexList(densities, new int3(-56, -1, 9), edgeIndex, isolevel); // Assert for (int i = 0; i < 12; i++) { var actualPosition = actual.ElementAt(i); Assert.AreEqual(0, math.distance(expected[i], actualPosition), 0.011f, $"Expected: {expected[i]}, Actual: {actualPosition}"); } }
private VertexList GenerateVertexList( VoxelCorners <float> voxelDensities, VoxelCorners <int3> voxelCorners, int edgeIndex, float isolevel) { var vertexList = new VertexList(); for (var i = 0; i < 12; i++) { if ((edgeIndex & (1 << i)) == 0) { continue; } var edgeStartIndex = MarchingCubesTables.EdgeIndexTable[2 * i + 0]; var edgeEndIndex = MarchingCubesTables.EdgeIndexTable[2 * i + 1]; var corner1 = (float3)voxelCorners[edgeStartIndex] * voxelSize; var corner2 = (float3)voxelCorners[edgeEndIndex] * voxelSize; var density1 = voxelDensities[edgeStartIndex]; var density2 = voxelDensities[edgeEndIndex]; vertexList[i] = VertexInterpolate(corner1, corner2, density1, density2, isolevel); } return(vertexList); }
public static VertexList GenerateVertexList(VoxelCorners <float> voxelDensities, VoxelCorners <int3> voxelCorners, int edgeIndex, float isolevel) { VertexList vertexList = new VertexList(); for (int i = 0; i < 12; i++) { if ((edgeIndex & (1 << i)) == 0) { continue; } int edgeStartIndex = MarchingCubesLookupTables.EdgeIndexTable[2 * i + 0]; int edgeEndIndex = MarchingCubesLookupTables.EdgeIndexTable[2 * i + 1]; int3 corner1 = voxelCorners[edgeStartIndex]; int3 corner2 = voxelCorners[edgeEndIndex]; float density1 = voxelDensities[edgeStartIndex]; float density2 = voxelDensities[edgeEndIndex]; vertexList[i] = VertexInterpolate(corner1, corner2, density1, density2, isolevel); } return(vertexList); }
private VoxelCorners <int3> GetCorners(int3 position) { var corners = new VoxelCorners <int3>(); for (var i = 0; i < 8; i++) { corners[i] = (position + MarchingCubesTables.CubeCorners[i]); } return(corners); }
public static VoxelCorners <int3> GetCorners(int3 position) { VoxelCorners <int3> corners = new VoxelCorners <int3>(); for (int i = 0; i < 8; i++) { corners[i] = position + LookupTables.CubeCorners[i]; } return(corners); }
private VoxelCorners <float> GetDensities(int3 localPosition) { var voxelDensities = new VoxelCorners <float>(); for (var i = 0; i < 8; i++) { var voxelCorner = localPosition + MarchingCubesTables.CubeCorners[i]; var densityIndex = voxelCorner.x * (chunkSize + 1) * (chunkSize + 1) + voxelCorner.y * (chunkSize + 1) + voxelCorner.z; voxelDensities[i] = densities[densityIndex]; } return(voxelDensities); }
public static byte CalculateCubeIndex(VoxelCorners <byte> voxelDensities, byte isolevel) { byte cubeIndex = (byte)math.select(0, 1, voxelDensities.Corner1 < isolevel); cubeIndex |= (byte)math.select(0, 2, voxelDensities.Corner2 < isolevel); cubeIndex |= (byte)math.select(0, 4, voxelDensities.Corner3 < isolevel); cubeIndex |= (byte)math.select(0, 8, voxelDensities.Corner4 < isolevel); cubeIndex |= (byte)math.select(0, 16, voxelDensities.Corner5 < isolevel); cubeIndex |= (byte)math.select(0, 32, voxelDensities.Corner6 < isolevel); cubeIndex |= (byte)math.select(0, 64, voxelDensities.Corner7 < isolevel); cubeIndex |= (byte)math.select(0, 128, voxelDensities.Corner8 < isolevel); return(cubeIndex); }
/// <summary> /// Gets a cube-shaped volume of voxel data from <paramref name="voxelDataArray"/>. The size of the cube is 1 unit. /// </summary> /// <param name="voxelDataArray">The voxel data array to get the voxel data from</param> /// <param name="localPosition">The origin of the cube</param> /// <returns>A cube-shaped volume of voxel data. The size of the cube is 1 unit.</returns> public static VoxelCorners <T> GetVoxelDataUnitCube <T>(this VoxelDataVolume <T> voxelDataArray, int3 localPosition) where T : struct { VoxelCorners <T> voxelDataCorners = new VoxelCorners <T>(); for (int i = 0; i < 8; i++) { int3 voxelCorner = localPosition + LookupTables.CubeCorners[i]; if (voxelDataArray.TryGetVoxelData(voxelCorner, out T voxelData)) { voxelDataCorners[i] = voxelData; } } return(voxelDataCorners); }
/// <summary> /// Gets a cube-shaped volume of voxel data from <paramref name="voxelDataVolume"/>. The size of the cube is 1 unit. /// </summary> /// <param name="voxelDataVolume">The voxel data volume to get the voxel data from</param> /// <param name="localPosition">The origin of the cube</param> /// <returns>A cube-shaped volume of voxel data. The size of the cube is 1 unit.</returns> public static VoxelCorners <float> GetVoxelDataUnitCube(this VoxelDataVolume voxelDataVolume, int3 localPosition) { VoxelCorners <float> voxelDataCorners = new VoxelCorners <float>(); for (int i = 0; i < 8; i++) { int3 voxelCorner = localPosition + LookupTables.CubeCorners[i]; if (voxelDataVolume.TryGetVoxelData(voxelCorner.x, voxelCorner.y, voxelCorner.z, out float voxelData)) { voxelDataCorners[i] = voxelData; } } return(voxelDataCorners); }
// --------------------------------------------------------------------------------------------- // // --------------------------------------------------------------------------------------------- public static VoxelCorners createVoxelCorners(VoxelVector3Int pos, int width, int height, int depth) { VoxelCorners vc = new VoxelCorners(); vc.bot_left_front = new VoxelVector3Int(pos.x, pos.y, pos.z); vc.bot_left_back = new VoxelVector3Int(pos.x, pos.y, pos.z + depth - 1); vc.bot_right_back = new VoxelVector3Int(pos.x + width - 1, pos.y, pos.z + depth - 1); vc.bot_right_front = new VoxelVector3Int(pos.x + width - 1, pos.y, pos.z); vc.top_left_front = new VoxelVector3Int(pos.x, pos.y + height - 1, pos.z); vc.top_left_back = new VoxelVector3Int(pos.x, pos.y + height - 1, pos.z + depth - 1); vc.top_right_back = new VoxelVector3Int(pos.x + width - 1, pos.y + height - 1, pos.z + depth - 1); vc.top_right_front = new VoxelVector3Int(pos.x + width - 1, pos.y + height - 1, pos.z); return(vc); }
private int CalculateCubeIndex(VoxelCorners <float> voxelDensities, float isolevel) { var cubeIndex = 0; if (voxelDensities.Corner1 < isolevel) { cubeIndex |= 1; } if (voxelDensities.Corner2 < isolevel) { cubeIndex |= 2; } if (voxelDensities.Corner3 < isolevel) { cubeIndex |= 4; } if (voxelDensities.Corner4 < isolevel) { cubeIndex |= 8; } if (voxelDensities.Corner5 < isolevel) { cubeIndex |= 16; } if (voxelDensities.Corner6 < isolevel) { cubeIndex |= 32; } if (voxelDensities.Corner7 < isolevel) { cubeIndex |= 64; } if (voxelDensities.Corner8 < isolevel) { cubeIndex |= 128; } return(cubeIndex); }
public void GenerateVertexList_Test2() { // Arrange VoxelCorners <float> densities = new VoxelCorners <float>() { Corner1 = 1f, Corner2 = 0f, Corner3 = 1f, Corner4 = 1f, Corner5 = 1f, Corner6 = 1f, Corner7 = 0f, Corner8 = 0f }; VoxelCorners <int3> corners = new VoxelCorners <int3>() { Corner1 = new int3(6, -13, 100), Corner2 = new int3(7, -13, 100), Corner3 = new int3(7, -13, 101), Corner4 = new int3(6, -13, 101), Corner5 = new int3(6, -12, 100), Corner6 = new int3(7, -12, 100), Corner7 = new int3(7, -12, 101), Corner8 = new int3(6, -12, 101) }; float isolevel = 0.75f; int edgeIndex = 0b1110_1010_0011; VertexList expected = new VertexList(); expected[0] = new float3(6.25f, -13f, 100f); expected[1] = new float3(7f, -13f, 100.75f); expected[5] = new float3(7f, -12f, 100.25f); expected[7] = new float3(6f, -12f, 100.25f); expected[9] = new float3(7f, -12.25f, 100f); expected[10] = new float3(7f, -12.75f, 101f); expected[11] = new float3(6f, -12.75f, 101f); // Act VertexList actual = MarchingCubesFunctions.GenerateVertexList(densities, corners, edgeIndex, isolevel); // Assert Assert.AreEqual(expected, actual); }
public void GenerateVertexList_Test3() { // Arrange VoxelCorners <float> densities = new VoxelCorners <float>() { Corner1 = 0.55f, Corner2 = 0.1f, Corner3 = 0.745f, Corner4 = 0.35f, Corner5 = 0.755f, Corner6 = 0.8f, Corner7 = 1f, Corner8 = 0.9f }; VoxelCorners <int3> corners = new VoxelCorners <int3>() { Corner1 = new int3(-56, -1, 9), Corner2 = new int3(-57, -1, 9), Corner3 = new int3(-57, -1, 10), Corner4 = new int3(-56, -1, 10), Corner5 = new int3(-56, 0, 9), Corner6 = new int3(-57, 0, 9), Corner7 = new int3(-57, 0, 10), Corner8 = new int3(-56, 0, 10) }; float isolevel = 0.75f; int edgeIndex = 0b1111_0000_0000; VertexList expected = new VertexList(); expected[8] = new float3(-56f, -0.02439022f, 9f); expected[9] = new float3(-57f, -0.07142866f, 9f); expected[10] = new float3(-57f, -0.9803922f, 10f); expected[11] = new float3(-56f, -0.272727272727f, 10f); // Act VertexList actual = MarchingCubesFunctions.GenerateVertexList(densities, corners, edgeIndex, isolevel); // Assert for (int i = 0; i < 12; i++) { Assert.AreEqual(0, math.distance(expected[i], actual[i]), 0.0001f); } }
public void CalculateCubeIndex_Test(byte c1, byte c2, byte c3, byte c4, byte c5, byte c6, byte c7, byte c8, byte isolevel, byte expectedCubeIndex) { VoxelCorners <byte> densities = new VoxelCorners <byte> { Corner1 = c1, Corner2 = c2, Corner3 = c3, Corner4 = c4, Corner5 = c5, Corner6 = c6, Corner7 = c7, Corner8 = c8 }; byte cubeIndex = MarchingCubesFunctions.CalculateCubeIndex(densities, isolevel); Assert.AreEqual(expectedCubeIndex, cubeIndex); }
public void CalculateCubeIndex_Test(float c1, float c2, float c3, float c4, float c5, float c6, float c7, float c8, float isolevel, int expectedCubeIndex) { VoxelCorners <float> densities = new VoxelCorners <float>() { Corner1 = c1, Corner2 = c2, Corner3 = c3, Corner4 = c4, Corner5 = c5, Corner6 = c6, Corner7 = c7, Corner8 = c8 }; int cubeIndex = MarchingCubesFunctions.CalculateCubeIndex(densities, isolevel); Assert.AreEqual(expectedCubeIndex, cubeIndex); }
public void GetCorners_Test(int x, int y, int z) { int3 pos = new int3(x, y, z); VoxelCorners <int3> corners = MarchingCubesFunctions.GetCorners(pos); VoxelCorners <int3> expected = new VoxelCorners <int3>() { Corner1 = new int3(x, y, z), Corner2 = new int3(x + 1, y, z), Corner3 = new int3(x + 1, y, z + 1), Corner4 = new int3(x, y, z + 1), Corner5 = new int3(x, y + 1, z), Corner6 = new int3(x + 1, y + 1, z), Corner7 = new int3(x + 1, y + 1, z + 1), Corner8 = new int3(x, y + 1, z + 1) }; Assert.AreEqual(expected, corners); }
public void GenerateVertexList_Test1() { // Arrange VoxelCorners <float> densities = new VoxelCorners <float>() { Corner1 = 1f, Corner2 = 1f, Corner3 = 1f, Corner4 = 0f, Corner5 = 1f, Corner6 = 1f, Corner7 = 1f, Corner8 = 1f }; VoxelCorners <int3> corners = new VoxelCorners <int3>() { Corner1 = new int3(0, 0, 0), Corner2 = new int3(1, 0, 0), Corner3 = new int3(1, 0, 1), Corner4 = new int3(0, 0, 1), Corner5 = new int3(0, 1, 0), Corner6 = new int3(1, 1, 0), Corner7 = new int3(1, 1, 1), Corner8 = new int3(0, 1, 1) }; int edgeIndex = 0b1000_0000_1100; float isolevel = 0.5f; VertexList expected = new VertexList(); expected[2] = new float3(0.5f, 0f, 1f); expected[3] = new float3(0f, 0f, 0.5f); expected[11] = new float3(0f, 0.5f, 1f); // Act VertexList actual = MarchingCubesFunctions.GenerateVertexList(densities, corners, edgeIndex, isolevel); // Assert Assert.AreEqual(expected, actual); }
public void GenerateVertexList_Test2() { // Arrange VoxelCorners <byte> densities = new VoxelCorners <byte> { Corner1 = 255, Corner2 = 0, Corner3 = 255, Corner4 = 255, Corner5 = 255, Corner6 = 255, Corner7 = 0, Corner8 = 0 }; byte isolevel = 191; int edgeIndex = 0b1110_1010_0011; VertexList expected = new VertexList(); expected[0] = new float3(6.25f, -13f, 100f); expected[1] = new float3(7f, -13f, 100.75f); expected[5] = new float3(7f, -12f, 100.25f); expected[7] = new float3(6f, -12f, 100.25f); expected[9] = new float3(7f, -12.25f, 100f); expected[10] = new float3(7f, -12.75f, 101f); expected[11] = new float3(6f, -12.75f, 101f); // Act IEnumerable <float3> actual = MarchingCubesFunctions.GenerateVertexList(densities, new int3(6, -13, 100), edgeIndex, isolevel); // Assert for (int i = 0; i < 12; i++) { var actualPosition = actual.ElementAt(i); Assert.AreEqual(0, math.distance(expected[i], actualPosition), 0.011f, $"Expected: {expected[i]}, Actual: {actualPosition}"); } }