From e242459ea2d6ec9b6d5e911cce9d7d09b918f06f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 31 Dec 2014 17:33:43 -0800 Subject: [PATCH] More render progress. --- interface/src/MetavoxelSystem.cpp | 69 +++++++++++++++++----------- libraries/metavoxels/src/Spanner.cpp | 11 ++++- libraries/metavoxels/src/Spanner.h | 2 + 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index b477ed41d8..7e5714ef0f 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -2331,42 +2331,57 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g QVector lastIndicesZ(stackWidth + 1); for (int z = 0; z <= stackHeight; z++) { + bool middleZ = (z != 0 && z != stackHeight); const StackArray* lineSrc = src; for (int x = 0; x <= stackWidth; x++) { - if (!lineSrc->isEmpty()) { - int position = lineSrc->getPosition(); - int count = lineSrc->getEntryCount(); - int y = position; + bool middleX = (x != 0 && x != stackWidth); + + // find the y extents of this and the neighboring columns + int minimumY = INT_MAX, maximumY = -1; + lineSrc->getExtents(minimumY, maximumY); + if (middleX) { + lineSrc[1].getExtents(minimumY, maximumY); + if (middleZ) { + lineSrc[stackWidth + 1].getExtents(minimumY, maximumY); + } + } + if (middleZ) { + lineSrc[stackWidth].getExtents(minimumY, maximumY); + } + + if (maximumY >= minimumY) { + int position = minimumY; + int count = maximumY - minimumY + 1; NormalIndex lastIndexY; indicesX.position = position; indicesX.resize(count); indicesZ[x].position = position; indicesZ[x].resize(count); - for (const StackArray::Entry* entry = lineSrc->getEntryData(), *end = entry + lineSrc->getEntryCount(); - entry != end; entry++, y++) { + for (int y = position, end = position + count; y < end; y++) { + const StackArray::Entry& entry = lineSrc->getEntry(y); int clampedX = qMax(x - 1, 0), clampedZ = qMax(z - 1, 0); if (displayHermite && x != 0 && z != 0) { glm::vec3 normal; - float distance = entry->getHermiteX(normal); + float distance = entry.getHermiteX(normal); if (normal != glm::vec3()) { glm::vec3 start = glm::vec3(clampedX + distance, y, clampedZ) * step; hermiteSegments.append(start); hermiteSegments.append(start + normal * step); } - distance = entry->getHermiteY(normal); + distance = entry.getHermiteY(normal); if (normal != glm::vec3()) { glm::vec3 start = glm::vec3(clampedX, y + distance, clampedZ) * step; hermiteSegments.append(start); hermiteSegments.append(start + normal * step); } - distance = entry->getHermiteZ(normal); + distance = entry.getHermiteZ(normal); if (normal != glm::vec3()) { glm::vec3 start = glm::vec3(clampedX, y, clampedZ + distance) * step; hermiteSegments.append(start); hermiteSegments.append(start + normal * step); } } - int alpha0 = qAlpha(entry->color); + int alpha0 = qAlpha(entry.color); int alpha2 = lineSrc->getEntryAlpha(y + 1); int alpha1 = alpha0, alpha3 = alpha2, alpha4 = alpha0, alpha6 = alpha2; int alphaTotal = alpha0 + alpha2; @@ -2374,8 +2389,6 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g // cubes on the edge are two-dimensional: this ensures that their vertices will be shared between // neighboring blocks, which share only one layer of points - bool middleX = (x != 0 && x != stackWidth); - bool middleZ = (z != 0 && z != stackHeight); if (middleZ) { alphaTotal += (alpha4 = lineSrc[stackWidth].getEntryAlpha(y)); possibleTotal += numeric_limits::max(); @@ -2411,8 +2424,8 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g const StackArray::Entry& nextEntryXY = lineSrc[1].getEntry(y + 1); if (alpha0 != alpha1) { EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(entry->getHermiteX(crossing.normal), 0.0f, 0.0f); - crossing.setColorMaterial(alpha0 == 0 ? nextEntryX : *entry); + crossing.point = glm::vec3(entry.getHermiteX(crossing.normal), 0.0f, 0.0f); + crossing.setColorMaterial(alpha0 == 0 ? nextEntryX : entry); } if (alpha1 != alpha3) { EdgeCrossing& crossing = crossings[crossingCount++]; @@ -2460,16 +2473,16 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g } if (alpha0 != alpha2) { EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(0.0f, entry->getHermiteY(crossing.normal), 0.0f); - crossing.setColorMaterial(alpha0 == 0 ? nextEntryY : *entry); + crossing.point = glm::vec3(0.0f, entry.getHermiteY(crossing.normal), 0.0f); + crossing.setColorMaterial(alpha0 == 0 ? nextEntryY : entry); } if (middleZ) { const StackArray::Entry& nextEntryZ = lineSrc[stackWidth].getEntry(y); const StackArray::Entry& nextEntryYZ = lineSrc[stackWidth].getEntry(y + 1); if (alpha0 != alpha4) { EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(0.0f, 0.0f, entry->getHermiteZ(crossing.normal)); - crossing.setColorMaterial(alpha0 == 0 ? nextEntryZ : *entry); + crossing.point = glm::vec3(0.0f, 0.0f, entry.getHermiteZ(crossing.normal)); + crossing.setColorMaterial(alpha0 == 0 ? nextEntryZ : entry); } if (alpha2 != alpha6) { EdgeCrossing& crossing = crossings[crossingCount++]; @@ -2672,13 +2685,13 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g vertices.at(index1.indices[0]).vertex - first); if (alpha0 == 0) { // quad faces negative y - indices.append(index1.getClosestIndex(normal = -normal, vertices)); - indices.append(index2.getClosestIndex(normal, vertices)); - indices.append(index3.getClosestIndex(normal, vertices)); - } else { // quad faces positive y - indices.append(index3.getClosestIndex(normal, vertices)); + indices.append(index3.getClosestIndex(normal = -normal, vertices)); indices.append(index2.getClosestIndex(normal, vertices)); indices.append(index1.getClosestIndex(normal, vertices)); + } else { // quad faces positive y + indices.append(index1.getClosestIndex(normal, vertices)); + indices.append(index2.getClosestIndex(normal, vertices)); + indices.append(index3.getClosestIndex(normal, vertices)); } indices.append(index.getClosestIndex(normal, vertices)); } @@ -2704,13 +2717,13 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g vertices.at(index3.indices[0]).vertex - first); if (alpha0 == 0) { // quad faces negative z - indices.append(index3.getClosestIndex(normal = -normal, vertices)); - indices.append(index2.getClosestIndex(normal, vertices)); - indices.append(index1.getClosestIndex(normal, vertices)); - } else { // quad faces positive z - indices.append(index1.getClosestIndex(normal, vertices)); + indices.append(index1.getClosestIndex(normal = -normal, vertices)); indices.append(index2.getClosestIndex(normal, vertices)); indices.append(index3.getClosestIndex(normal, vertices)); + } else { // quad faces positive z + indices.append(index3.getClosestIndex(normal, vertices)); + indices.append(index2.getClosestIndex(normal, vertices)); + indices.append(index1.getClosestIndex(normal, vertices)); } indices.append(index.getClosestIndex(normal, vertices)); } diff --git a/libraries/metavoxels/src/Spanner.cpp b/libraries/metavoxels/src/Spanner.cpp index e47182326c..8b1983b90b 100644 --- a/libraries/metavoxels/src/Spanner.cpp +++ b/libraries/metavoxels/src/Spanner.cpp @@ -1234,6 +1234,15 @@ const StackArray::Entry& StackArray::getEntry(int y) const { return (relative < count) ? getEntryData()[qMax(relative, 0)] : emptyEntry; } +void StackArray::getExtents(int& minimumY, int& maximumY) const { + int count = getEntryCount(); + if (count > 0) { + int position = getPosition(); + minimumY = qMin(minimumY, position); + maximumY = qMax(maximumY, position + count - 1); + } +} + HeightfieldStack::HeightfieldStack(int width, const QVector& contents, const QVector& materials) : HeightfieldData(width), @@ -2265,7 +2274,7 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons if (stackX >= 0.0f && stackX <= innerStackWidth && stackZ >= 0.0f && stackZ <= innerStackHeight) { StackArray* stackDest = newStackContents.data() + (int)stackZ * stackWidth + (int)stackX; - if (stackDest->isEmpty() && *heightLineDest != 0) { + if (stackDest->isEmpty() && *heightLineDest != 0 && false) { // initialize from heightfield *stackDest = StackArray(1); float voxelHeight = *heightLineDest * voxelScale; diff --git a/libraries/metavoxels/src/Spanner.h b/libraries/metavoxels/src/Spanner.h index a12c677b83..fa51a2f0d8 100644 --- a/libraries/metavoxels/src/Spanner.h +++ b/libraries/metavoxels/src/Spanner.h @@ -523,6 +523,8 @@ public: Entry& getEntry(int y); const Entry& getEntry(int y) const; + void getExtents(int& minimumY, int& maximumY) const; + void removeEntries(int position, int count) { remove(sizeof(quint16) + position * sizeof(Entry), count * sizeof(Entry)); } };