History

Ridiculously complicated minimization code.

Andrzej Kapolka committed 12 years ago

Commit 8ebb2a71 parent aa0b3a11 file · +134 −15Browse files

Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 1 file). Show all

Unified · Split

interface/src/MetavoxelSystem.cpp+134−15
@@ -1657,7 +1657,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 1656 unmodified lines
1657 crossing.color = colorX[0];1657 crossing.color = colorX[0];
1658 crossing.material = materialBase[0];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 if (middleY) {1662 if (middleY) {
1663 if (alpha1 != alpha3) {1663 if (alpha1 != alpha3) {
@@ -1671,7 +1671,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
1671 crossing.color = colorX[1];1671 crossing.color = colorX[1];
1672 crossing.material = materialBase[1];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 if (alpha2 != alpha3) {1676 if (alpha2 != alpha3) {
1677 QRgb hermite = hermiteBase[hermiteStride];1677 QRgb hermite = hermiteBase[hermiteStride];
@@ -1684,7 +1684,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
1684 crossing.color = colorX[size];1684 crossing.color = colorX[size];
1685 crossing.material = materialBase[size];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 if (middleZ) {1689 if (middleZ) {
1690 if (alpha3 != alpha7) {1690 if (alpha3 != alpha7) {
@@ -1698,7 +1698,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
1698 crossing.color = colorX[offset3];1698 crossing.color = colorX[offset3];
1699 crossing.material = materialBase[offset3];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 if (alpha5 != alpha7) {1703 if (alpha5 != alpha7) {
1704 QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1];1704 QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1];
@@ -1711,7 +1711,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
1711 crossing.color = colorX[offset5];1711 crossing.color = colorX[offset5];
1712 crossing.material = materialBase[offset5];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 if (alpha6 != alpha7) {1716 if (alpha6 != alpha7) {
1717 QRgb hermite = hermiteBase[hermiteArea + hermiteStride];1717 QRgb hermite = hermiteBase[hermiteArea + hermiteStride];
@@ -1724,7 +1724,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
1724 crossing.color = colorX[offset6];1724 crossing.color = colorX[offset6];
1725 crossing.material = materialBase[offset6];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 crossing.color = colorX[1];1740 crossing.color = colorX[1];
1741 crossing.material = materialBase[1];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 if (alpha4 != alpha5) {1745 if (alpha4 != alpha5) {
1746 QRgb hermite = hermiteBase[hermiteArea];1746 QRgb hermite = hermiteBase[hermiteArea];
@@ -1753,7 +1753,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
1753 crossing.color = colorX[area];1753 crossing.color = colorX[area];
1754 crossing.material = materialBase[area];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 crossing.color = colorX[0];1769 crossing.color = colorX[0];
1770 crossing.material = materialBase[0];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 if (middleZ) {1774 if (middleZ) {
1775 if (alpha2 != alpha6) {1775 if (alpha2 != alpha6) {
@@ -1783,7 +1783,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
1783 crossing.color = colorX[size];1783 crossing.color = colorX[size];
1784 crossing.material = materialBase[size];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 if (alpha4 != alpha6) {1788 if (alpha4 != alpha6) {
1789 QRgb hermite = hermiteBase[hermiteArea + 1];1789 QRgb hermite = hermiteBase[hermiteArea + 1];
@@ -1796,7 +1796,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
1796 crossing.color = colorX[area];1796 crossing.color = colorX[area];
1797 crossing.material = materialBase[area];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 crossing.color = colorX[0];1811 crossing.color = colorX[0];
1812 crossing.material = materialBase[0];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 // at present, we simply average the properties of each crossing as opposed to finding the vertex that1816 // at present, we simply average the properties of each crossing as opposed to finding the vertex that
1817 // minimizes the quadratic error function as described in the reference paper1817 // minimizes the quadratic error function as described in the reference paper
@@ -1857,7 +1857,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 39 unmodified lines
1857 glm::vec4 bottom;1857 glm::vec4 bottom;
1858 for (int i = 0; i < crossingCount; i++) {1858 for (int i = 0; i < crossingCount; i++) {
1859 const EdgeCrossing& crossing = crossings[i];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 for (int j = 0; j < 4; j++) {1862 for (int j = 0; j < 4; j++) {
1863 float angle = glm::atan(-bottom[j], r[j][j]);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 if (totalWeight > 0.0f) {1995 if (totalWeight > 0.0f) {
1876 materialWeights *= (EIGHT_BIT_MAXIMUM / totalWeight);1996 materialWeights *= (EIGHT_BIT_MAXIMUM / totalWeight);
1877 }1997 }
1878 VoxelPoint point = { info.minimum + (glm::vec3(clampedX, clampedY, clampedZ) +1998 VoxelPoint point = { info.minimum + (glm::vec3(clampedX, clampedY, clampedZ) + center) * scale,
1879 center * EIGHT_BIT_MAXIMUM_RECIPROCAL) * scale,
1880 { (quint8)(red / crossingCount), (quint8)(green / crossingCount), (quint8)(blue / crossingCount) },1999 { (quint8)(red / crossingCount), (quint8)(green / crossingCount), (quint8)(blue / crossingCount) },
1881 { (char)(normal.x * 127.0f), (char)(normal.y * 127.0f), (char)(normal.z * 127.0f) },2000 { (char)(normal.x * 127.0f), (char)(normal.y * 127.0f), (char)(normal.z * 127.0f) },
1882 { materials[0], materials[1], materials[2], materials[3] },2001 { materials[0], materials[1], materials[2], materials[3] },