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
964964 Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
965965 }
966966
967+void 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+
967973 VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices,
968974 const QVector<SharedObjectPointer>& materials) :
969975 _vertices(vertices),
@@ -1535,6 +1541,14 @@ public: · 565 unmodified lines
15351541 glm::vec3 normal;
15361542 QRgb color;
15371543 char material;
1544+ int axis;
1545+};
1546+
1547+class AxisIndex {
1548+public:
1549+ int x, y, z;
1550+
1551+ AxisIndex(int x = -1, int y = -1, int z = -1) : x(x), y(y), z(z) { }
15381552 };
15391553
15401554 int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
@@ -1575,10 +1589,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 34 unmodified lines
15751589 // as we scan down the cube generating vertices between grid points, we remember the indices of the last
15761590 // (element, line, section--x, y, z) so that we can connect generated vertices as quads
15771591 int expanded = size + 1;
1578− QVector<int> lineIndices(expanded, -1);
1579− QVector<int> lastLineIndices(expanded, -1);
1580− QVector<int> planeIndices(expanded * expanded, -1);
1581− QVector<int> lastPlaneIndices(expanded * expanded, -1);
1592+ QVector<AxisIndex> lineIndices(expanded);
1593+ QVector<AxisIndex> lastLineIndices(expanded);
1594+ QVector<AxisIndex> planeIndices(expanded * expanded);
1595+ QVector<AxisIndex> lastPlaneIndices(expanded * expanded);
15821596
15831597 const int EDGES_PER_CUBE = 12;
15841598 EdgeCrossing crossings[EDGES_PER_CUBE];
@@ -1589,7 +1603,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 4 unmodified lines
15891603 for (int z = 0; z < expanded; z++) {
15901604 const QRgb* colorY = colorZ;
15911605 for (int y = 0; y < expanded; y++) {
1592− int lastIndex = 0;
1606+ AxisIndex lastIndex;
15931607 const QRgb* colorX = colorY;
15941608 for (int x = 0; x < expanded; x++) {
15951609 int alpha0 = colorX[0] >> ALPHA_OFFSET;
@@ -1663,6 +1677,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 67 unmodified lines
16631677 crossing.material = materialBase[0];
16641678 }
16651679 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f);
1680+ crossing.axis = 0;
16661681 }
16671682 if (middleY) {
16681683 if (alpha1 != alpha3) {
@@ -1677,6 +1692,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines
16771692 crossing.material = materialBase[1];
16781693 }
16791694 crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);
1695+ crossing.axis = 1;
16801696 }
16811697 if (alpha2 != alpha3) {
16821698 QRgb hermite = hermiteBase[hermiteStride];
@@ -1690,6 +1706,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
16901706 crossing.material = materialBase[size];
16911707 }
16921708 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f);
1709+ crossing.axis = 0;
16931710 }
16941711 if (middleZ) {
16951712 if (alpha3 != alpha7) {
@@ -1704,6 +1721,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines
17041721 crossing.material = materialBase[offset3];
17051722 }
17061723 crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1724+ crossing.axis = 2;
17071725 }
17081726 if (alpha5 != alpha7) {
17091727 QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1];
@@ -1717,6 +1735,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
17171735 crossing.material = materialBase[offset5];
17181736 }
17191737 crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);
1738+ crossing.axis = 1;
17201739 }
17211740 if (alpha6 != alpha7) {
17221741 QRgb hermite = hermiteBase[hermiteArea + hermiteStride];
@@ -1730,6 +1749,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
17301749 crossing.material = materialBase[offset6];
17311750 }
17321751 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f);
1752+ crossing.axis = 0;
17331753 }
17341754 }
17351755 }
@@ -1746,6 +1766,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
17461766 crossing.material = materialBase[1];
17471767 }
17481768 crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1769+ crossing.axis = 2;
17491770 }
17501771 if (alpha4 != alpha5) {
17511772 QRgb hermite = hermiteBase[hermiteArea];
@@ -1759,6 +1780,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
17591780 crossing.material = materialBase[area];
17601781 }
17611782 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f);
1783+ crossing.axis = 0;
17621784 }
17631785 }
17641786 }
@@ -1775,6 +1797,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
17751797 crossing.material = materialBase[0];
17761798 }
17771799 crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);
1800+ crossing.axis = 1;
17781801 }
17791802 if (middleZ) {
17801803 if (alpha2 != alpha6) {
@@ -1789,6 +1812,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines
17891812 crossing.material = materialBase[size];
17901813 }
17911814 crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1815+ crossing.axis = 2;
17921816 }
17931817 if (alpha4 != alpha6) {
17941818 QRgb hermite = hermiteBase[hermiteArea + 1];
@@ -1802,6 +1826,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
18021826 crossing.material = materialBase[area];
18031827 }
18041828 crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);
1829+ crossing.axis = 1;
18051830 }
18061831 }
18071832 }
@@ -1817,11 +1842,12 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 9 unmodified lines
18171842 crossing.material = materialBase[0];
18181843 }
18191844 crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1845+ crossing.axis = 2;
18201846 }
18211847 // at present, we simply average the properties of each crossing as opposed to finding the vertex that
18221848 // minimizes the quadratic error function as described in the reference paper
18231849 glm::vec3 center;
1824− glm::vec3 normal;
1850+ glm::vec3 axisNormals[3];
18251851 const int MAX_MATERIALS_PER_VERTEX = 4;
18261852 quint8 materials[] = { 0, 0, 0, 0 };
18271853 glm::vec4 materialWeights;
@@ -1830,7 +1856,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 2 unmodified lines
18301856 for (int i = 0; i < crossingCount; i++) {
18311857 const EdgeCrossing& crossing = crossings[i];
18321858 center += crossing.point;
1833− normal += crossing.normal;
1859+ axisNormals[crossing.axis] += crossing.normal;
18341860 red += qRed(crossing.color);
18351861 green += qGreen(crossing.color);
18361862 blue += qBlue(crossing.color);
@@ -1853,16 +1879,18 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 16 unmodified lines
18531879 }
18541880 }
18551881 }
1856− normal = glm::normalize(normal);
1882+ glm::vec3 normal = glm::normalize(axisNormals[0] + axisNormals[1] + axisNormals[2]);
18571883 center /= crossingCount;
18581884
18591885 // use a sequence of Givens rotations to perform a QR decomposition
18601886 // see http://www.cs.rice.edu/~jwarren/papers/techreport02408.pdf
18611887 glm::mat4 r(0.0f);
18621888 glm::vec4 bottom;
1889+ float smallestCosNormal = 1.0f;
18631890 for (int i = 0; i < crossingCount; i++) {
18641891 const EdgeCrossing& crossing = crossings[i];
18651892 bottom = glm::vec4(crossing.normal, glm::dot(crossing.normal, crossing.point - center));
1893+ smallestCosNormal = qMin(smallestCosNormal, glm::dot(crossing.normal, normal));
18661894
18671895 for (int j = 0; j < 4; j++) {
18681896 float angle = glm::atan(-bottom[j], r[j][j]);
@@ -1931,17 +1959,69 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 62 unmodified lines
19311959 { materials[0], materials[1], materials[2], materials[3] },
19321960 { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2],
19331961 (quint8)materialWeights[3] } };
1934− int index = vertices.size();
1935− vertices.append(point);
1962+
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+ }
19362016
19372017 // the first x, y, and z are repeated for the boundary edge; past that, we consider generating
19382018 // quads for each edge that includes a transition, using indices of previously generated vertices
19392019 if (x != 0 && y != 0 && z != 0) {
19402020 if (alpha0 != alpha1) {
1941− indices.append(index);
1942− int index1 = lastLineIndices.at(x);
1943− int index2 = lastPlaneIndices.at((y - 1) * expanded + x);
1944− int index3 = lastPlaneIndices.at(y * expanded + x);
2021+ indices.append(index.x);
2022+ int index1 = lastLineIndices.at(x).x;
2023+ int index2 = lastPlaneIndices.at((y - 1) * expanded + x).x;
2024+ int index3 = lastPlaneIndices.at(y * expanded + x).x;
19452025 if (alpha0 == 0) { // quad faces negative x
19462026 indices.append(index3);
19472027 indices.append(index2);
@@ -1954,10 +2034,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
19542034 }
19552035
19562036 if (alpha0 != alpha2) {
1957− indices.append(index);
1958− int index1 = lastIndex;
1959− int index2 = lastPlaneIndices.at(y * expanded + x - 1);
1960− int index3 = lastPlaneIndices.at(y * expanded + x);
2037+ indices.append(index.y);
2038+ int index1 = lastIndex.y;
2039+ int index2 = lastPlaneIndices.at(y * expanded + x - 1).y;
2040+ int index3 = lastPlaneIndices.at(y * expanded + x).y;
19612041 if (alpha0 == 0) { // quad faces negative y
19622042 indices.append(index1);
19632043 indices.append(index2);
@@ -1970,10 +2050,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
19702050 }
19712051
19722052 if (alpha0 != alpha4) {
1973− indices.append(index);
1974− int index1 = lastIndex;
1975− int index2 = lastLineIndices.at(x - 1);
1976− int index3 = lastLineIndices.at(x);
2053+ indices.append(index.z);
2054+ int index1 = lastIndex.z;
2055+ int index2 = lastLineIndices.at(x - 1).z;
2056+ int index3 = lastLineIndices.at(x).z;
19772057 if (alpha0 == 0) { // quad faces negative z
19782058 indices.append(index3);
19792059 indices.append(index2);