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}");
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 5
0
        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);
        }
Esempio n. 7
0
        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);
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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);
        }
Esempio n. 16
0
        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);
        }
Esempio n. 17
0
        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);
        }
Esempio n. 18
0
        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}");
            }
        }