History

Generate additional vertices with different normals when normals differ by "crease" angle.

Andrzej Kapolka committed 12 years ago

Commit c67f4211 parent 27099f62 files · +104 −22Browse files

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

Unified · Split

interface/src/MetavoxelSystem.cpp+102−22
@@ -964,6 +964,12 @@ void HeightfieldPreview::render(const glm::vec3& translation, float scale) const · 963 unmodified lines
964 Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);964 Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
965}965}
966 966
967void VoxelPoint::setNormal(const glm::vec3& normal) {
968 this->normal[0] = (char)(normal.x * 127.0f);
969 this->normal[1] = (char)(normal.y * 127.0f);
970 this->normal[2] = (char)(normal.z * 127.0f);
971}
972
967VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices,973VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices,
968 const QVector<SharedObjectPointer>& materials) :974 const QVector<SharedObjectPointer>& materials) :
969 _vertices(vertices),975 _vertices(vertices),
@@ -1535,6 +1541,14 @@ public: · 565 unmodified lines
1535 glm::vec3 normal;1541 glm::vec3 normal;
1536 QRgb color;1542 QRgb color;
1537 char material;1543 char material;
1544 int axis;
1545};
1546
1547class AxisIndex {
1548public:
1549 int x, y, z;
1550
1551 AxisIndex(int x = -1, int y = -1, int z = -1) : x(x), y(y), z(z) { }
1538};1552};
1539 1553
1540int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {1554int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
@@ -1575,10 +1589,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 34 unmodified lines
1575 // as we scan down the cube generating vertices between grid points, we remember the indices of the last1589 // as we scan down the cube generating vertices between grid points, we remember the indices of the last
1576 // (element, line, section--x, y, z) so that we can connect generated vertices as quads1590 // (element, line, section--x, y, z) so that we can connect generated vertices as quads
1577 int expanded = size + 1;1591 int expanded = size + 1;
1578 QVector<int> lineIndices(expanded, -1);1592 QVector<AxisIndex> lineIndices(expanded);
1579 QVector<int> lastLineIndices(expanded, -1);1593 QVector<AxisIndex> lastLineIndices(expanded);
1580 QVector<int> planeIndices(expanded * expanded, -1);1594 QVector<AxisIndex> planeIndices(expanded * expanded);
1581 QVector<int> lastPlaneIndices(expanded * expanded, -1);1595 QVector<AxisIndex> lastPlaneIndices(expanded * expanded);
1582 1596
1583 const int EDGES_PER_CUBE = 12;1597 const int EDGES_PER_CUBE = 12;
1584 EdgeCrossing crossings[EDGES_PER_CUBE];1598 EdgeCrossing crossings[EDGES_PER_CUBE];
@@ -1589,7 +1603,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 4 unmodified lines
1589 for (int z = 0; z < expanded; z++) {1603 for (int z = 0; z < expanded; z++) {
1590 const QRgb* colorY = colorZ;1604 const QRgb* colorY = colorZ;
1591 for (int y = 0; y < expanded; y++) {1605 for (int y = 0; y < expanded; y++) {
1592 int lastIndex = 0;1606 AxisIndex lastIndex;
1593 const QRgb* colorX = colorY;1607 const QRgb* colorX = colorY;
1594 for (int x = 0; x < expanded; x++) {1608 for (int x = 0; x < expanded; x++) {
1595 int alpha0 = colorX[0] >> ALPHA_OFFSET;1609 int alpha0 = colorX[0] >> ALPHA_OFFSET;
@@ -1663,6 +1677,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 67 unmodified lines
1663 crossing.material = materialBase[0];1677 crossing.material = materialBase[0];
1664 }1678 }
1665 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f);1679 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f);
1680 crossing.axis = 0;
1666 }1681 }
1667 if (middleY) {1682 if (middleY) {
1668 if (alpha1 != alpha3) {1683 if (alpha1 != alpha3) {
@@ -1677,6 +1692,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines
1677 crossing.material = materialBase[1];1692 crossing.material = materialBase[1];
1678 }1693 }
1679 crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);1694 crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);
1695 crossing.axis = 1;
1680 }1696 }
1681 if (alpha2 != alpha3) {1697 if (alpha2 != alpha3) {
1682 QRgb hermite = hermiteBase[hermiteStride];1698 QRgb hermite = hermiteBase[hermiteStride];
@@ -1690,6 +1706,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
1690 crossing.material = materialBase[size];1706 crossing.material = materialBase[size];
1691 }1707 }
1692 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f);1708 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f);
1709 crossing.axis = 0;
1693 }1710 }
1694 if (middleZ) {1711 if (middleZ) {
1695 if (alpha3 != alpha7) {1712 if (alpha3 != alpha7) {
@@ -1704,6 +1721,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines
1704 crossing.material = materialBase[offset3];1721 crossing.material = materialBase[offset3];
1705 }1722 }
1706 crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);1723 crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1724 crossing.axis = 2;
1707 }1725 }
1708 if (alpha5 != alpha7) {1726 if (alpha5 != alpha7) {
1709 QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1];1727 QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1];
@@ -1717,6 +1735,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
1717 crossing.material = materialBase[offset5];1735 crossing.material = materialBase[offset5];
1718 }1736 }
1719 crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);1737 crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);
1738 crossing.axis = 1;
1720 }1739 }
1721 if (alpha6 != alpha7) {1740 if (alpha6 != alpha7) {
1722 QRgb hermite = hermiteBase[hermiteArea + hermiteStride];1741 QRgb hermite = hermiteBase[hermiteArea + hermiteStride];
@@ -1730,6 +1749,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
1730 crossing.material = materialBase[offset6];1749 crossing.material = materialBase[offset6];
1731 }1750 }
1732 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f);1751 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f);
1752 crossing.axis = 0;
1733 }1753 }
1734 }1754 }
1735 }1755 }
@@ -1746,6 +1766,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
1746 crossing.material = materialBase[1];1766 crossing.material = materialBase[1];
1747 }1767 }
1748 crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);1768 crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1769 crossing.axis = 2;
1749 }1770 }
1750 if (alpha4 != alpha5) {1771 if (alpha4 != alpha5) {
1751 QRgb hermite = hermiteBase[hermiteArea];1772 QRgb hermite = hermiteBase[hermiteArea];
@@ -1759,6 +1780,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
1759 crossing.material = materialBase[area];1780 crossing.material = materialBase[area];
1760 }1781 }
1761 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f);1782 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f);
1783 crossing.axis = 0;
1762 }1784 }
1763 }1785 }
1764 }1786 }
@@ -1775,6 +1797,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
1775 crossing.material = materialBase[0];1797 crossing.material = materialBase[0];
1776 }1798 }
1777 crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);1799 crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);
1800 crossing.axis = 1;
1778 }1801 }
1779 if (middleZ) {1802 if (middleZ) {
1780 if (alpha2 != alpha6) {1803 if (alpha2 != alpha6) {
@@ -1789,6 +1812,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines
1789 crossing.material = materialBase[size];1812 crossing.material = materialBase[size];
1790 }1813 }
1791 crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);1814 crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1815 crossing.axis = 2;
1792 }1816 }
1793 if (alpha4 != alpha6) {1817 if (alpha4 != alpha6) {
1794 QRgb hermite = hermiteBase[hermiteArea + 1];1818 QRgb hermite = hermiteBase[hermiteArea + 1];
@@ -1802,6 +1826,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
1802 crossing.material = materialBase[area];1826 crossing.material = materialBase[area];
1803 }1827 }
1804 crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);1828 crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);
1829 crossing.axis = 1;
1805 }1830 }
1806 }1831 }
1807 }1832 }
@@ -1817,11 +1842,12 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 9 unmodified lines
1817 crossing.material = materialBase[0];1842 crossing.material = materialBase[0];
1818 }1843 }
1819 crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);1844 crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1845 crossing.axis = 2;
1820 }1846 }
1821 // at present, we simply average the properties of each crossing as opposed to finding the vertex that1847 // at present, we simply average the properties of each crossing as opposed to finding the vertex that
1822 // minimizes the quadratic error function as described in the reference paper1848 // minimizes the quadratic error function as described in the reference paper
1823 glm::vec3 center;1849 glm::vec3 center;
1824 glm::vec3 normal;1850 glm::vec3 axisNormals[3];
1825 const int MAX_MATERIALS_PER_VERTEX = 4;1851 const int MAX_MATERIALS_PER_VERTEX = 4;
1826 quint8 materials[] = { 0, 0, 0, 0 };1852 quint8 materials[] = { 0, 0, 0, 0 };
1827 glm::vec4 materialWeights;1853 glm::vec4 materialWeights;
@@ -1830,7 +1856,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 2 unmodified lines
1830 for (int i = 0; i < crossingCount; i++) {1856 for (int i = 0; i < crossingCount; i++) {
1831 const EdgeCrossing& crossing = crossings[i];1857 const EdgeCrossing& crossing = crossings[i];
1832 center += crossing.point;1858 center += crossing.point;
1833 normal += crossing.normal;1859 axisNormals[crossing.axis] += crossing.normal;
1834 red += qRed(crossing.color);1860 red += qRed(crossing.color);
1835 green += qGreen(crossing.color);1861 green += qGreen(crossing.color);
1836 blue += qBlue(crossing.color);1862 blue += qBlue(crossing.color);
@@ -1853,16 +1879,18 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 16 unmodified lines
1853 }1879 }
1854 }1880 }
1855 }1881 }
1856 normal = glm::normalize(normal);1882 glm::vec3 normal = glm::normalize(axisNormals[0] + axisNormals[1] + axisNormals[2]);
1857 center /= crossingCount;1883 center /= crossingCount;
1858 1884
1859 // use a sequence of Givens rotations to perform a QR decomposition1885 // use a sequence of Givens rotations to perform a QR decomposition
1860 // see http://www.cs.rice.edu/~jwarren/papers/techreport02408.pdf1886 // see http://www.cs.rice.edu/~jwarren/papers/techreport02408.pdf
1861 glm::mat4 r(0.0f);1887 glm::mat4 r(0.0f);
1862 glm::vec4 bottom;1888 glm::vec4 bottom;
1889 float smallestCosNormal = 1.0f;
1863 for (int i = 0; i < crossingCount; i++) {1890 for (int i = 0; i < crossingCount; i++) {
1864 const EdgeCrossing& crossing = crossings[i];1891 const EdgeCrossing& crossing = crossings[i];
1865 bottom = glm::vec4(crossing.normal, glm::dot(crossing.normal, crossing.point - center));1892 bottom = glm::vec4(crossing.normal, glm::dot(crossing.normal, crossing.point - center));
1893 smallestCosNormal = qMin(smallestCosNormal, glm::dot(crossing.normal, normal));
1866 1894
1867 for (int j = 0; j < 4; j++) {1895 for (int j = 0; j < 4; j++) {
1868 float angle = glm::atan(-bottom[j], r[j][j]);1896 float angle = glm::atan(-bottom[j], r[j][j]);
@@ -1931,17 +1959,69 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 62 unmodified lines
1931 { materials[0], materials[1], materials[2], materials[3] },1959 { materials[0], materials[1], materials[2], materials[3] },
1932 { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2],1960 { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2],
1933 (quint8)materialWeights[3] } };1961 (quint8)materialWeights[3] } };
1934 int index = vertices.size();1962
1935 vertices.append(point);1963 // determine whether we must "crease" by generating directional normals
1964 const float CREASE_COS_NORMAL = glm::cos(glm::radians(40.0f));
1965 AxisIndex index(vertices.size(), vertices.size(), vertices.size());
1966 if (smallestCosNormal > CREASE_COS_NORMAL) {
1967 vertices.append(point);
1968
1969 } else {
1970 axisNormals[0] = glm::normalize(axisNormals[0]);
1971 axisNormals[1] = glm::normalize(axisNormals[1]);
1972 axisNormals[2] = glm::normalize(axisNormals[2]);
1973 glm::vec3 normalXY(glm::normalize(axisNormals[0] + axisNormals[1]));
1974 glm::vec3 normalXZ(glm::normalize(axisNormals[0] + axisNormals[2]));
1975 glm::vec3 normalYZ(glm::normalize(axisNormals[1] + axisNormals[2]));
1976 if (glm::dot(axisNormals[0], normalXY) > CREASE_COS_NORMAL &&
1977 glm::dot(axisNormals[1], normalXY) > CREASE_COS_NORMAL) {
1978 point.setNormal(normalXY);
1979 vertices.append(point);
1980
1981 point.setNormal(axisNormals[2]);
1982 index.z = vertices.size();
1983 vertices.append(point);
1984
1985 } else if (glm::dot(axisNormals[0], normalXZ) > CREASE_COS_NORMAL &&
1986 glm::dot(axisNormals[2], normalXZ) > CREASE_COS_NORMAL) {
1987 point.setNormal(normalXZ);
1988 vertices.append(point);
1989
1990 point.setNormal(axisNormals[1]);
1991 index.y = vertices.size();
1992 vertices.append(point);
1993
1994 } else if (glm::dot(axisNormals[1], normalYZ) > CREASE_COS_NORMAL &&
1995 glm::dot(axisNormals[2], normalYZ) > CREASE_COS_NORMAL) {
1996 point.setNormal(normalYZ);
1997 vertices.append(point);
1998
1999 point.setNormal(axisNormals[0]);
2000 index.x = vertices.size();
2001 vertices.append(point);
2002
2003 } else {
2004 point.setNormal(axisNormals[0]);
2005 vertices.append(point);
2006
2007 point.setNormal(axisNormals[1]);
2008 index.y = vertices.size();
2009 vertices.append(point);
2010
2011 point.setNormal(axisNormals[2]);
2012 index.z = vertices.size();
2013 vertices.append(point);
2014 }
2015 }
1936 2016
1937 // the first x, y, and z are repeated for the boundary edge; past that, we consider generating2017 // the first x, y, and z are repeated for the boundary edge; past that, we consider generating
1938 // quads for each edge that includes a transition, using indices of previously generated vertices2018 // quads for each edge that includes a transition, using indices of previously generated vertices
1939 if (x != 0 && y != 0 && z != 0) {2019 if (x != 0 && y != 0 && z != 0) {
1940 if (alpha0 != alpha1) {2020 if (alpha0 != alpha1) {
1941 indices.append(index);2021 indices.append(index.x);
1942 int index1 = lastLineIndices.at(x);2022 int index1 = lastLineIndices.at(x).x;
1943 int index2 = lastPlaneIndices.at((y - 1) * expanded + x);2023 int index2 = lastPlaneIndices.at((y - 1) * expanded + x).x;
1944 int index3 = lastPlaneIndices.at(y * expanded + x);2024 int index3 = lastPlaneIndices.at(y * expanded + x).x;
1945 if (alpha0 == 0) { // quad faces negative x2025 if (alpha0 == 0) { // quad faces negative x
1946 indices.append(index3);2026 indices.append(index3);
1947 indices.append(index2);2027 indices.append(index2);
@@ -1954,10 +2034,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
1954 }2034 }
1955 2035
1956 if (alpha0 != alpha2) {2036 if (alpha0 != alpha2) {
1957 indices.append(index);2037 indices.append(index.y);
1958 int index1 = lastIndex;2038 int index1 = lastIndex.y;
1959 int index2 = lastPlaneIndices.at(y * expanded + x - 1);2039 int index2 = lastPlaneIndices.at(y * expanded + x - 1).y;
1960 int index3 = lastPlaneIndices.at(y * expanded + x);2040 int index3 = lastPlaneIndices.at(y * expanded + x).y;
1961 if (alpha0 == 0) { // quad faces negative y2041 if (alpha0 == 0) { // quad faces negative y
1962 indices.append(index1);2042 indices.append(index1);
1963 indices.append(index2);2043 indices.append(index2);
@@ -1970,10 +2050,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
1970 }2050 }
1971 2051
1972 if (alpha0 != alpha4) {2052 if (alpha0 != alpha4) {
1973 indices.append(index);2053 indices.append(index.z);
1974 int index1 = lastIndex;2054 int index1 = lastIndex.z;
1975 int index2 = lastLineIndices.at(x - 1);2055 int index2 = lastLineIndices.at(x - 1).z;
1976 int index3 = lastLineIndices.at(x);2056 int index3 = lastLineIndices.at(x).z;
1977 if (alpha0 == 0) { // quad faces negative z2057 if (alpha0 == 0) { // quad faces negative z
1978 indices.append(index3);2058 indices.append(index3);
1979 indices.append(index2);2059 indices.append(index2);