Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 1 file). Show all
Unified · Split
| @@ -1657,7 +1657,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 1656 unmodified lines | ||
| 1657 | 1657 | crossing.color = colorX[0]; |
| 1658 | 1658 | crossing.material = materialBase[0]; |
| 1659 | 1659 | } |
| 1660 | − crossing.point = glm::vec3(qAlpha(hermite), 0.0f, 0.0f); | |
| 1660 | + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f); | |
| 1661 | 1661 | } |
| 1662 | 1662 | if (middleY) { |
| 1663 | 1663 | if (alpha1 != alpha3) { |
| @@ -1671,7 +1671,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines | ||
| 1671 | 1671 | crossing.color = colorX[1]; |
| 1672 | 1672 | crossing.material = materialBase[1]; |
| 1673 | 1673 | } |
| 1674 | − crossing.point = glm::vec3(EIGHT_BIT_MAXIMUM, qAlpha(hermite), 0.0f); | |
| 1674 | + crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); | |
| 1675 | 1675 | } |
| 1676 | 1676 | if (alpha2 != alpha3) { |
| 1677 | 1677 | QRgb hermite = hermiteBase[hermiteStride]; |
| @@ -1684,7 +1684,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines | ||
| 1684 | 1684 | crossing.color = colorX[size]; |
| 1685 | 1685 | crossing.material = materialBase[size]; |
| 1686 | 1686 | } |
| 1687 | − crossing.point = glm::vec3(qAlpha(hermite), EIGHT_BIT_MAXIMUM, 0.0f); | |
| 1687 | + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f); | |
| 1688 | 1688 | } |
| 1689 | 1689 | if (middleZ) { |
| 1690 | 1690 | if (alpha3 != alpha7) { |
| @@ -1698,7 +1698,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines | ||
| 1698 | 1698 | crossing.color = colorX[offset3]; |
| 1699 | 1699 | crossing.material = materialBase[offset3]; |
| 1700 | 1700 | } |
| 1701 | − crossing.point = glm::vec3(EIGHT_BIT_MAXIMUM, EIGHT_BIT_MAXIMUM, qAlpha(hermite)); | |
| 1701 | + crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); | |
| 1702 | 1702 | } |
| 1703 | 1703 | if (alpha5 != alpha7) { |
| 1704 | 1704 | QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1]; |
| @@ -1711,7 +1711,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines | ||
| 1711 | 1711 | crossing.color = colorX[offset5]; |
| 1712 | 1712 | crossing.material = materialBase[offset5]; |
| 1713 | 1713 | } |
| 1714 | − crossing.point = glm::vec3(EIGHT_BIT_MAXIMUM, qAlpha(hermite), EIGHT_BIT_MAXIMUM); | |
| 1714 | + crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); | |
| 1715 | 1715 | } |
| 1716 | 1716 | if (alpha6 != alpha7) { |
| 1717 | 1717 | QRgb hermite = hermiteBase[hermiteArea + hermiteStride]; |
| @@ -1724,7 +1724,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines | ||
| 1724 | 1724 | crossing.color = colorX[offset6]; |
| 1725 | 1725 | crossing.material = materialBase[offset6]; |
| 1726 | 1726 | } |
| 1727 | − crossing.point = glm::vec3(qAlpha(hermite), EIGHT_BIT_MAXIMUM, EIGHT_BIT_MAXIMUM); | |
| 1727 | + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f); | |
| 1728 | 1728 | } |
| 1729 | 1729 | } |
| 1730 | 1730 | } |
| @@ -1740,7 +1740,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 9 unmodified lines | ||
| 1740 | 1740 | crossing.color = colorX[1]; |
| 1741 | 1741 | crossing.material = materialBase[1]; |
| 1742 | 1742 | } |
| 1743 | − crossing.point = glm::vec3(EIGHT_BIT_MAXIMUM, 0.0f, qAlpha(hermite)); | |
| 1743 | + crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); | |
| 1744 | 1744 | } |
| 1745 | 1745 | if (alpha4 != alpha5) { |
| 1746 | 1746 | QRgb hermite = hermiteBase[hermiteArea]; |
| @@ -1753,7 +1753,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines | ||
| 1753 | 1753 | crossing.color = colorX[area]; |
| 1754 | 1754 | crossing.material = materialBase[area]; |
| 1755 | 1755 | } |
| 1756 | − crossing.point = glm::vec3(qAlpha(hermite), 0.0f, EIGHT_BIT_MAXIMUM); | |
| 1756 | + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f); | |
| 1757 | 1757 | } |
| 1758 | 1758 | } |
| 1759 | 1759 | } |
| @@ -1769,7 +1769,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 9 unmodified lines | ||
| 1769 | 1769 | crossing.color = colorX[0]; |
| 1770 | 1770 | crossing.material = materialBase[0]; |
| 1771 | 1771 | } |
| 1772 | − crossing.point = glm::vec3(0.0f, qAlpha(hermite), 0.0f); | |
| 1772 | + crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); | |
| 1773 | 1773 | } |
| 1774 | 1774 | if (middleZ) { |
| 1775 | 1775 | if (alpha2 != alpha6) { |
| @@ -1783,7 +1783,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines | ||
| 1783 | 1783 | crossing.color = colorX[size]; |
| 1784 | 1784 | crossing.material = materialBase[size]; |
| 1785 | 1785 | } |
| 1786 | − crossing.point = glm::vec3(0.0f, EIGHT_BIT_MAXIMUM, qAlpha(hermite)); | |
| 1786 | + crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); | |
| 1787 | 1787 | } |
| 1788 | 1788 | if (alpha4 != alpha6) { |
| 1789 | 1789 | QRgb hermite = hermiteBase[hermiteArea + 1]; |
| @@ -1796,7 +1796,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines | ||
| 1796 | 1796 | crossing.color = colorX[area]; |
| 1797 | 1797 | crossing.material = materialBase[area]; |
| 1798 | 1798 | } |
| 1799 | − crossing.point = glm::vec3(0.0f, qAlpha(hermite), EIGHT_BIT_MAXIMUM); | |
| 1799 | + crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); | |
| 1800 | 1800 | } |
| 1801 | 1801 | } |
| 1802 | 1802 | } |
| @@ -1811,7 +1811,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines | ||
| 1811 | 1811 | crossing.color = colorX[0]; |
| 1812 | 1812 | crossing.material = materialBase[0]; |
| 1813 | 1813 | } |
| 1814 | − crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite)); | |
| 1814 | + crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); | |
| 1815 | 1815 | } |
| 1816 | 1816 | // at present, we simply average the properties of each crossing as opposed to finding the vertex that |
| 1817 | 1817 | // minimizes the quadratic error function as described in the reference paper |
| @@ -1857,7 +1857,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 39 unmodified lines | ||
| 1857 | 1857 | glm::vec4 bottom; |
| 1858 | 1858 | for (int i = 0; i < crossingCount; i++) { |
| 1859 | 1859 | const EdgeCrossing& crossing = crossings[i]; |
| 1860 | − bottom = glm::vec4(crossing.normal, glm::dot(crossing.normal, crossing.point)); | |
| 1860 | + bottom = glm::vec4(crossing.normal, glm::dot(crossing.normal, crossing.point - center)); | |
| 1861 | 1861 | |
| 1862 | 1862 | for (int j = 0; j < 4; j++) { |
| 1863 | 1863 | float angle = glm::atan(-bottom[j], r[j][j]); |
| @@ -1872,11 +1872,130 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines | ||
| 1872 | 1872 | } |
| 1873 | 1873 | } |
| 1874 | 1874 | |
| 1875 | + // extract the submatrices, form ata | |
| 1876 | + glm::mat3 a(r); | |
| 1877 | + glm::vec3 b(r[3]); | |
| 1878 | + glm::mat3 atrans = glm::transpose(a); | |
| 1879 | + glm::mat3 ata = atrans * a; | |
| 1880 | + | |
| 1881 | + // compute the SVD of ata; first, find the eigenvalues | |
| 1882 | + // (see http://en.wikipedia.org/wiki/Eigenvalue_algorithm#3.C3.973_matrices) | |
| 1883 | + glm::vec3 eigenvalues; | |
| 1884 | + float p1 = ata[0][1] * ata[0][1] + ata[0][2] * ata[0][2] + ata[1][2] * ata[1][2]; | |
| 1885 | + if (p1 < EPSILON) { | |
| 1886 | + eigenvalues = glm::vec3(ata[0][0], ata[1][1], ata[2][2]); | |
| 1887 | + if (eigenvalues[2] < eigenvalues[1]) { | |
| 1888 | + qSwap(eigenvalues[2], eigenvalues[1]); | |
| 1889 | + } | |
| 1890 | + if (eigenvalues[1] < eigenvalues[0]) { | |
| 1891 | + qSwap(eigenvalues[1], eigenvalues[0]); | |
| 1892 | + } | |
| 1893 | + if (eigenvalues[2] < eigenvalues[1]) { | |
| 1894 | + qSwap(eigenvalues[2], eigenvalues[1]); | |
| 1895 | + } | |
| 1896 | + } else { | |
| 1897 | + float q = (ata[0][0] + ata[1][1] + ata[2][2]) / 3.0f; | |
| 1898 | + float d1 = ata[0][0] - q, d2 = ata[1][1] - q, d3 = ata[2][2] - q; | |
| 1899 | + float p2 = d1 * d1 + d2 * d2 + d3 * d3 + 2.0f * p1; | |
| 1900 | + float p = glm::sqrt(p2 / 6.0f); | |
| 1901 | + glm::mat3 b = (ata - glm::mat3(q)) / p; | |
| 1902 | + float r = glm::determinant(b) / 2.0f; | |
| 1903 | + float phi; | |
| 1904 | + if (r <= -1.0f) { | |
| 1905 | + phi = PI / 3.0f; | |
| 1906 | + } else if (r >= 1.0f) { | |
| 1907 | + phi = 0.0f; | |
| 1908 | + } else { | |
| 1909 | + phi = glm::acos(r) / 3.0f; | |
| 1910 | + } | |
| 1911 | + eigenvalues[2] = q + 2.0f * p * glm::cos(phi); | |
| 1912 | + eigenvalues[0] = q + 2.0f * p * glm::cos(phi + (2.0f * PI / 3.0f)); | |
| 1913 | + eigenvalues[1] = 3.0f * q - eigenvalues[0] - eigenvalues[2]; | |
| 1914 | + } | |
| 1915 | + | |
| 1916 | + // form the singular matrix from the eigenvalues | |
| 1917 | + glm::mat3 d; | |
| 1918 | + const float MIN_SINGULAR_THRESHOLD = 0.1f; | |
| 1919 | + d[0][0] = (eigenvalues[0] < MIN_SINGULAR_THRESHOLD) ? 0.0f : 1.0f / eigenvalues[0]; | |
| 1920 | + d[1][1] = (eigenvalues[1] < MIN_SINGULAR_THRESHOLD) ? 0.0f : 1.0f / eigenvalues[1]; | |
| 1921 | + d[2][2] = (eigenvalues[2] < MIN_SINGULAR_THRESHOLD) ? 0.0f : 1.0f / eigenvalues[2]; | |
| 1922 | + | |
| 1923 | + glm::mat3 m[] = { ata - glm::mat3(eigenvalues[0]), ata - glm::mat3(eigenvalues[1]), | |
| 1924 | + ata - glm::mat3(eigenvalues[2]) }; | |
| 1925 | + | |
| 1926 | + // form the orthogonal matrix from the eigenvectors | |
| 1927 | + // see http://www.geometrictools.com/Documentation/EigenSymmetric3x3.pdf | |
| 1928 | + bool same01 = glm::abs(eigenvalues[0] - eigenvalues[1]) < EPSILON; | |
| 1929 | + bool same12 = glm::abs(eigenvalues[1] - eigenvalues[2]) < EPSILON; | |
| 1930 | + glm::mat3 u; | |
| 1931 | + if (!(same01 && same12)) { | |
| 1932 | + if (same01 || same12) { | |
| 1933 | + int i = same01 ? 2 : 0; | |
| 1934 | + for (int j = 0; j < 3; j++) { | |
| 1935 | + glm::vec3 first = glm::vec3(m[i][0][j], m[i][1][j], m[i][2][j]); | |
| 1936 | + int j2 = (j + 1) % 3; | |
| 1937 | + glm::vec3 second = glm::vec3(m[i][0][j2], m[i][1][j2], m[i][2][j2]); | |
| 1938 | + glm::vec3 cross = glm::cross(first, second); | |
| 1939 | + float length = glm::length(cross); | |
| 1940 | + if (length > EPSILON) { | |
| 1941 | + u[0][i] = cross[0] / length; | |
| 1942 | + u[1][i] = cross[1] / length; | |
| 1943 | + u[2][i] = cross[2] / length; | |
| 1944 | + break; | |
| 1945 | + } | |
| 1946 | + } | |
| 1947 | + i = (i + 1) % 3; | |
| 1948 | + for (int j = 0; j < 3; j++) { | |
| 1949 | + glm::vec3 first = glm::vec3(m[i][0][j], m[i][1][j], m[i][2][j]); | |
| 1950 | + float length = glm::length(first); | |
| 1951 | + if (length > EPSILON) { | |
| 1952 | + glm::vec3 second = glm::cross(first, glm::vec3(1.0f, 0.0f, 0.0f)); | |
| 1953 | + length = glm::length(second); | |
| 1954 | + if (length < EPSILON) { | |
| 1955 | + second = glm::cross(first, glm::vec3(0.0f, 1.0f, 0.0f)); | |
| 1956 | + length = glm::length(second); | |
| 1957 | + } | |
| 1958 | + u[0][i] = second[0] / length; | |
| 1959 | + u[1][i] = second[1] / length; | |
| 1960 | + u[2][i] = second[2] / length; | |
| 1961 | + second = glm::normalize(glm::cross(second, first)); | |
| 1962 | + i = (i + 1) % 3; | |
| 1963 | + u[0][i] = second[0]; | |
| 1964 | + u[1][i] = second[1]; | |
| 1965 | + u[2][i] = second[2]; | |
| 1966 | + break; | |
| 1967 | + } | |
| 1968 | + } | |
| 1969 | + } else { | |
| 1970 | + for (int i = 0; i < 3; i++) { | |
| 1971 | + for (int j = 0; j < 3; j++) { | |
| 1972 | + glm::vec3 first = glm::vec3(m[i][0][j], m[i][1][j], m[i][2][j]); | |
| 1973 | + int j2 = (j + 1) % 3; | |
| 1974 | + glm::vec3 second = glm::vec3(m[i][0][j2], m[i][1][j2], m[i][2][j2]); | |
| 1975 | + glm::vec3 cross = glm::cross(first, second); | |
| 1976 | + float length = glm::length(cross); | |
| 1977 | + if (length > EPSILON) { | |
| 1978 | + u[0][i] = cross[0] / length; | |
| 1979 | + u[1][i] = cross[1] / length; | |
| 1980 | + u[2][i] = cross[2] / length; | |
| 1981 | + break; | |
| 1982 | + } | |
| 1983 | + } | |
| 1984 | + } | |
| 1985 | + } | |
| 1986 | + } | |
| 1987 | + | |
| 1988 | + // compute the pseudo-inverse, ataplus | |
| 1989 | + glm::mat3 ataplus = glm::transpose(u) * d * u; | |
| 1990 | + | |
| 1991 | + glm::vec3 solution = (ataplus * atrans * b) + center; | |
| 1992 | + | |
| 1993 | + center = glm::clamp(solution, 0.0f, 1.0f); | |
| 1994 | + | |
| 1875 | 1995 | if (totalWeight > 0.0f) { |
| 1876 | 1996 | materialWeights *= (EIGHT_BIT_MAXIMUM / totalWeight); |
| 1877 | 1997 | } |
| 1878 | − VoxelPoint point = { info.minimum + (glm::vec3(clampedX, clampedY, clampedZ) + | |
| 1879 | − center * EIGHT_BIT_MAXIMUM_RECIPROCAL) * scale, | |
| 1998 | + VoxelPoint point = { info.minimum + (glm::vec3(clampedX, clampedY, clampedZ) + center) * scale, | |
| 1880 | 1999 | { (quint8)(red / crossingCount), (quint8)(green / crossingCount), (quint8)(blue / crossingCount) }, |
| 1881 | 2000 | { (char)(normal.x * 127.0f), (char)(normal.y * 127.0f), (char)(normal.z * 127.0f) }, |
| 1882 | 2001 | { materials[0], materials[1], materials[2], materials[3] }, |