History

More progress towards allowing different resolutions for height and color, material, etc.

Andrzej Kapolka committed 12 years ago

Commit d28da921 parent 32781d55 files · +282 −151Browse files

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

Unified · Split

interface/src/MetavoxelSystem.cpp+228−131
@@ -1006,16 +1006,14 @@ QByteArray HeightfieldBuffer::getUnextendedHeight() const { · 1005 unmodified lines
10061006 return unextended;
10071007 }
10081008
1009−QByteArray HeightfieldBuffer::getUnextendedColor() const {
1010− int srcSize = glm::sqrt(float(_color.size() / DataBlock::COLOR_BYTES));
1011− int destSize = srcSize - 1;
1012− QByteArray unextended(destSize * destSize * DataBlock::COLOR_BYTES, 0);
1013− const char* src = _color.constData();
1014− int srcStride = srcSize * DataBlock::COLOR_BYTES;
1009+QByteArray HeightfieldBuffer::getUnextendedColor(int x, int y) const {
1010+ int unextendedSize = _heightSize - HEIGHT_EXTENSION;
1011+ QByteArray unextended(unextendedSize * unextendedSize * DataBlock::COLOR_BYTES, 0);
10151012 char* dest = unextended.data();
1016− int destStride = destSize * DataBlock::COLOR_BYTES;
1017− for (int z = 0; z < destSize; z++, src += srcStride, dest += destStride) {
1018− memcpy(dest, src, destStride);
1013+ const char* src = _color.constData() + (y * _colorSize + x) * unextendedSize * DataBlock::COLOR_BYTES;
1014+ for (int z = 0; z < unextendedSize; z++, dest += unextendedSize * DataBlock::COLOR_BYTES,
1015+ src += _colorSize * DataBlock::COLOR_BYTES) {
1016+ memcpy(dest, src, unextendedSize * DataBlock::COLOR_BYTES);
10191017 }
10201018 return unextended;
10211019 }
@@ -1702,134 +1700,170 @@ public: · 680 unmodified lines
17021700
17031701 HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections);
17041702
1705− void init(HeightfieldBuffer* buffer) { _buffer = buffer; }
1703+ void init(HeightfieldBuffer* buffer);
17061704
17071705 virtual int visit(MetavoxelInfo& info);
1706+ virtual bool postVisit(MetavoxelInfo& info);
17081707
17091708 private:
17101709
17111710 const QVector<Box>& _intersections;
17121711 HeightfieldBuffer* _buffer;
1712+
1713+ int _heightDepth;
1714+ int _colorDepth;
1715+ int _materialDepth;
17131716 };
17141717
17151718 HeightfieldFetchVisitor::HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections) :
17161719 MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<
1717− AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector<AttributePointer>(), lod),
1720+ AttributeRegistry::getInstance()->getHeightfieldColorAttribute() <<
1721+ AttributeRegistry::getInstance()->getHeightfieldMaterialAttribute(), QVector<AttributePointer>(), lod),
17181722 _intersections(intersections) {
17191723 }
17201724
1725+void HeightfieldFetchVisitor::init(HeightfieldBuffer* buffer) {
1726+ _buffer = buffer;
1727+ _heightDepth = -1;
1728+ _colorDepth = -1;
1729+ _materialDepth = -1;
1730+}
1731+
17211732 int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) {
1722− Box bounds = info.getBounds();
1723− const Box& heightBounds = _buffer->getHeightBounds();
1724− if (!bounds.intersects(heightBounds)) {
1733+ if (!info.getBounds().intersects(_buffer->getHeightBounds())) {
17251734 return STOP_RECURSION;
17261735 }
1727− if (!info.isLeaf && info.size > _buffer->getScale()) {
1736+ if (!info.isLeaf) {
17281737 return DEFAULT_ORDER;
17291738 }
1739+ postVisit(info);
1740+ return STOP_RECURSION;
1741+}
1742+
1743+bool HeightfieldFetchVisitor::postVisit(MetavoxelInfo& info) {
17301744 HeightfieldHeightDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldHeightDataPointer>();
1731− if (!height) {
1732− return STOP_RECURSION;
1745+ if (height || _heightDepth != -1) {
1746+ if (_depth < _heightDepth) {
1747+ height.reset();
1748+ }
1749+ _heightDepth = _depth;
17331750 }
1751+ HeightfieldColorDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>();
1752+ if (color || _colorDepth != -1) {
1753+ if (_depth < _colorDepth) {
1754+ color.reset();
1755+ }
1756+ _colorDepth = _depth;
1757+ }
1758+ HeightfieldMaterialDataPointer material = info.inputValues.at(2).getInlineValue<HeightfieldMaterialDataPointer>();
1759+ if (material || _materialDepth != -1) {
1760+ if (_depth < _materialDepth) {
1761+ material.reset();
1762+ }
1763+ _materialDepth = _depth;
1764+ }
1765+ if (!(height || color || material)) {
1766+ return false;
1767+ }
1768+ Box bounds = info.getBounds();
17341769 foreach (const Box& intersection, _intersections) {
17351770 Box overlap = intersection.getIntersection(bounds);
17361771 if (overlap.isEmpty()) {
17371772 continue;
17381773 }
1739− float heightIncrement = _buffer->getHeightIncrement();
1740− int destX = (overlap.minimum.x - heightBounds.minimum.x) / heightIncrement;
1741− int destY = (overlap.minimum.z - heightBounds.minimum.z) / heightIncrement;
1742− int destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / heightIncrement);
1743− int destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / heightIncrement);
1744− int heightSize = _buffer->getHeightSize();
1745− char* dest = _buffer->getHeight().data() + destY * heightSize + destX;
1746−
1747− const QByteArray& srcHeight = height->getContents();
1748− int srcSize = glm::sqrt(float(srcHeight.size()));
1749− float srcIncrement = info.size / srcSize;
1750−
1751− if (info.size == _buffer->getScale() && srcSize == (heightSize - HeightfieldBuffer::HEIGHT_EXTENSION)) {
1752− // easy case: same resolution
1753− int srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1754− int srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1774+ if (height) {
1775+ float heightIncrement = _buffer->getHeightIncrement();
1776+ const Box& heightBounds = _buffer->getHeightBounds();
1777+ int destX = (overlap.minimum.x - heightBounds.minimum.x) / heightIncrement;
1778+ int destY = (overlap.minimum.z - heightBounds.minimum.z) / heightIncrement;
1779+ int destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / heightIncrement);
1780+ int destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / heightIncrement);
1781+ int heightSize = _buffer->getHeightSize();
1782+ char* dest = _buffer->getHeight().data() + destY * heightSize + destX;
17551783
1756− const char* src = srcHeight.constData() + srcY * srcSize + srcX;
1757− for (int y = 0; y < destHeight; y++, src += srcSize, dest += heightSize) {
1758− memcpy(dest, src, destWidth);
1759− }
1760− } else {
1761− // more difficult: different resolutions
1762− float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1763− float srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1764− float srcAdvance = heightIncrement / srcIncrement;
1765− int shift = 0;
1766− float size = _buffer->getScale();
1767− while (size < info.size) {
1768− shift++;
1769− size *= 2.0f;
1770− }
1771− int subtract = (_buffer->getTranslation().y - info.minimum.y) * EIGHT_BIT_MAXIMUM / _buffer->getScale();
1772− for (int y = 0; y < destHeight; y++, dest += heightSize, srcY += srcAdvance) {
1773− const uchar* src = (const uchar*)srcHeight.constData() + (int)srcY * srcSize;
1774− float lineSrcX = srcX;
1775− for (char* lineDest = dest, *end = dest + destWidth; lineDest != end; lineDest++, lineSrcX += srcAdvance) {
1776− *lineDest = qMin(qMax(0, (src[(int)lineSrcX] << shift) - subtract), EIGHT_BIT_MAXIMUM);
1784+ const QByteArray& srcHeight = height->getContents();
1785+ int srcSize = glm::sqrt((float)srcHeight.size());
1786+ float srcIncrement = info.size / srcSize;
1787+
1788+ if (info.size == _buffer->getScale() && srcSize == (heightSize - HeightfieldBuffer::HEIGHT_EXTENSION)) {
1789+ // easy case: same resolution
1790+ int srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1791+ int srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1792+
1793+ const char* src = srcHeight.constData() + srcY * srcSize + srcX;
1794+ for (int y = 0; y < destHeight; y++, src += srcSize, dest += heightSize) {
1795+ memcpy(dest, src, destWidth);
1796+ }
1797+ } else {
1798+ // more difficult: different resolutions
1799+ float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1800+ float srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1801+ float srcAdvance = heightIncrement / srcIncrement;
1802+ int shift = 0;
1803+ float size = _buffer->getScale();
1804+ while (size < info.size) {
1805+ shift++;
1806+ size *= 2.0f;
1807+ }
1808+ int subtract = (_buffer->getTranslation().y - info.minimum.y) * EIGHT_BIT_MAXIMUM / _buffer->getScale();
1809+ for (int y = 0; y < destHeight; y++, dest += heightSize, srcY += srcAdvance) {
1810+ const uchar* src = (const uchar*)srcHeight.constData() + (int)srcY * srcSize;
1811+ float lineSrcX = srcX;
1812+ for (char* lineDest = dest, *end = dest + destWidth; lineDest != end; lineDest++, lineSrcX += srcAdvance) {
1813+ *lineDest = qMin(qMax(0, (src[(int)lineSrcX] << shift) - subtract), EIGHT_BIT_MAXIMUM);
1814+ }
17771815 }
17781816 }
17791817 }
1780−
1781− int colorSize = _buffer->getColorSize();
1782− if (colorSize == 0) {
1783− continue;
1784− }
1785− HeightfieldColorDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>();
1786− if (!color) {
1787− continue;
1788− }
1789− const Box& colorBounds = _buffer->getColorBounds();
1790− overlap = colorBounds.getIntersection(overlap);
1791− float colorIncrement = _buffer->getColorIncrement();
1792− destX = (overlap.minimum.x - colorBounds.minimum.x) / colorIncrement;
1793− destY = (overlap.minimum.z - colorBounds.minimum.z) / colorIncrement;
1794− destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / colorIncrement);
1795− destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / colorIncrement);
1796− dest = _buffer->getColor().data() + (destY * colorSize + destX) * DataBlock::COLOR_BYTES;
1797− int destStride = colorSize * DataBlock::COLOR_BYTES;
1798− int destBytes = destWidth * DataBlock::COLOR_BYTES;
1799−
1800− const QByteArray& srcColor = color->getContents();
1801− srcSize = glm::sqrt(float(srcColor.size() / DataBlock::COLOR_BYTES));
1802− int srcStride = srcSize * DataBlock::COLOR_BYTES;
1803− srcIncrement = info.size / srcSize;
1804−
1805− if (srcIncrement == colorIncrement) {
1806− // easy case: same resolution
1807− int srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1808− int srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1818+ if (color) {
1819+ const Box& colorBounds = _buffer->getColorBounds();
1820+ overlap = colorBounds.getIntersection(overlap);
1821+ float colorIncrement = _buffer->getColorIncrement();
1822+ int destX = (overlap.minimum.x - colorBounds.minimum.x) / colorIncrement;
1823+ int destY = (overlap.minimum.z - colorBounds.minimum.z) / colorIncrement;
1824+ int destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / colorIncrement);
1825+ int destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / colorIncrement);
1826+ int colorSize = _buffer->getColorSize();
1827+ char* dest = _buffer->getColor().data() + (destY * colorSize + destX) * DataBlock::COLOR_BYTES;
1828+ int destStride = colorSize * DataBlock::COLOR_BYTES;
1829+ int destBytes = destWidth * DataBlock::COLOR_BYTES;
18091830
1810− const char* src = srcColor.constData() + (srcY * srcSize + srcX) * DataBlock::COLOR_BYTES;
1811− for (int y = 0; y < destHeight; y++, src += srcStride, dest += destStride) {
1812− memcpy(dest, src, destBytes);
1813− }
1814− } else {
1815− // more difficult: different resolutions
1816− float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1817− float srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1818− float srcAdvance = colorIncrement / srcIncrement;
1819− for (int y = 0; y < destHeight; y++, dest += destStride, srcY += srcAdvance) {
1820− const char* src = srcColor.constData() + (int)srcY * srcStride;
1821− float lineSrcX = srcX;
1822− for (char* lineDest = dest, *end = dest + destBytes; lineDest != end; lineDest += DataBlock::COLOR_BYTES,
1823− lineSrcX += srcAdvance) {
1824− const char* lineSrc = src + (int)lineSrcX * DataBlock::COLOR_BYTES;
1825− lineDest[0] = lineSrc[0];
1826− lineDest[1] = lineSrc[1];
1827− lineDest[2] = lineSrc[2];
1831+ const QByteArray& srcColor = color->getContents();
1832+ int srcSize = glm::sqrt(float(srcColor.size() / DataBlock::COLOR_BYTES));
1833+ int srcStride = srcSize * DataBlock::COLOR_BYTES;
1834+ float srcIncrement = info.size / srcSize;
1835+
1836+ if (srcIncrement == colorIncrement) {
1837+ // easy case: same resolution
1838+ int srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1839+ int srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1840+
1841+ const char* src = srcColor.constData() + (srcY * srcSize + srcX) * DataBlock::COLOR_BYTES;
1842+ for (int y = 0; y < destHeight; y++, src += srcStride, dest += destStride) {
1843+ memcpy(dest, src, destBytes);
1844+ }
1845+ } else {
1846+ // more difficult: different resolutions
1847+ float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1848+ float srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1849+ float srcAdvance = colorIncrement / srcIncrement;
1850+ for (int y = 0; y < destHeight; y++, dest += destStride, srcY += srcAdvance) {
1851+ const char* src = srcColor.constData() + (int)srcY * srcStride;
1852+ float lineSrcX = srcX;
1853+ for (char* lineDest = dest, *end = dest + destBytes; lineDest != end; lineDest += DataBlock::COLOR_BYTES,
1854+ lineSrcX += srcAdvance) {
1855+ const char* lineSrc = src + (int)lineSrcX * DataBlock::COLOR_BYTES;
1856+ lineDest[0] = lineSrc[0];
1857+ lineDest[1] = lineSrc[1];
1858+ lineDest[2] = lineSrc[2];
1859+ }
18281860 }
18291861 }
18301862 }
1863+ if (material) {
1864+ }
18311865 }
1832− return STOP_RECURSION;
1866+ return false;
18331867 }
18341868
18351869 class HeightfieldRegionVisitor : public MetavoxelVisitor {
@@ -1841,11 +1875,27 @@ public: · 5 unmodified lines
18411875 HeightfieldRegionVisitor(const MetavoxelLOD& lod);
18421876
18431877 virtual int visit(MetavoxelInfo& info);
1878+ virtual bool postVisit(MetavoxelInfo& info);
18441879
18451880 private:
18461881
18471882 void addRegion(const Box& unextended, const Box& extended);
18481883
1884+ int _heightSize;
1885+ int _heightDepth;
1886+
1887+ int _inheritedColorSize;
1888+ int _inheritedColorDepth;
1889+
1890+ int _containedColorSize;
1891+ int _containedColorDepth;
1892+
1893+ int _inheritedMaterialSize;
1894+ int _inheritedMaterialDepth;
1895+
1896+ int _containedMaterialSize;
1897+ int _containedMaterialDepth;
1898+
18491899 QVector<Box> _intersections;
18501900 HeightfieldFetchVisitor _fetchVisitor;
18511901 };
@@ -1857,52 +1907,92 @@ HeightfieldRegionVisitor::HeightfieldRegionVisitor(const MetavoxelLOD& lod) : · 5 unmodified lines
18571907 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>() <<
18581908 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod),
18591909 regionBounds(glm::vec3(FLT_MAX, FLT_MAX, FLT_MAX), glm::vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX)),
1910+ _heightDepth(-1),
1911+ _inheritedColorDepth(-1),
1912+ _containedColorDepth(-1),
1913+ _inheritedMaterialDepth(-1),
1914+ _containedMaterialDepth(-1),
18601915 _fetchVisitor(lod, _intersections) {
18611916 }
18621917
1918+static int signedLeftShift(int value, int shift) {
1919+ return (shift > 0) ? value << shift : value >> (-shift);
1920+}
1921+
18631922 int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) {
1864− if (!info.isLeaf) {
1865− return DEFAULT_ORDER;
1866− }
1867− HeightfieldBuffer* buffer = NULL;
18681923 HeightfieldHeightDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldHeightDataPointer>();
1924+ int order = DEFAULT_ORDER;
18691925 if (height) {
1870− const QByteArray& heightContents = height->getContents();
1871− int size = glm::sqrt(float(heightContents.size()));
1872− int extendedSize = size + HeightfieldBuffer::HEIGHT_EXTENSION;
1873− int heightContentsSize = extendedSize * extendedSize;
1874−
1875− HeightfieldColorDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>();
1876− int colorContentsSize = 0;
1877− if (color) {
1878− const QByteArray& colorContents = color->getContents();
1879− int colorSize = glm::sqrt(float(colorContents.size() / DataBlock::COLOR_BYTES));
1880− int extendedColorSize = colorSize + HeightfieldBuffer::SHARED_EDGE;
1881− colorContentsSize = extendedColorSize * extendedColorSize * DataBlock::COLOR_BYTES;
1926+ _heightSize = glm::sqrt((float)height->getContents().size());
1927+ _heightDepth = _depth;
1928+ order |= ALL_NODES_REST;
1929+ }
1930+ HeightfieldColorDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>();
1931+ if (color) {
1932+ int colorSize = glm::sqrt((float)(color->getContents().size() / DataBlock::COLOR_BYTES));
1933+ if (_heightDepth == -1) {
1934+ _inheritedColorSize = colorSize;
1935+ _inheritedColorDepth = _depth;
1936+
1937+ } else if (_containedColorDepth == -1 ||
1938+ colorSize > signedLeftShift(_containedColorSize, _containedColorDepth - _depth)) {
1939+ _containedColorSize = colorSize;
1940+ _containedColorDepth = _depth;
18821941 }
1883−
1884− HeightfieldMaterialDataPointer material = info.inputValues.at(2).getInlineValue<HeightfieldMaterialDataPointer>();
1885− QByteArray materialContents;
1886− QVector<SharedObjectPointer> materials;
1887− if (material) {
1888− materialContents = material->getContents();
1889− materials = material->getMaterials();
1942+ }
1943+ HeightfieldMaterialDataPointer material = info.inputValues.at(2).getInlineValue<HeightfieldMaterialDataPointer>();
1944+ if (material) {
1945+ int materialSize = glm::sqrt((float)material->getContents().size());
1946+ if (_heightDepth == -1) {
1947+ _inheritedMaterialSize = materialSize;
1948+ _inheritedMaterialDepth = _depth;
1949+
1950+ } else if (_containedMaterialDepth == -1 ||
1951+ materialSize > signedLeftShift(_containedMaterialSize, _containedMaterialDepth - _depth)) {
1952+ _containedMaterialSize = materialSize;
1953+ _containedMaterialDepth = _depth;
18901954 }
1955+ }
1956+ if (!info.isLeaf) {
1957+ return order;
1958+ }
1959+ postVisit(info);
1960+ return STOP_RECURSION;
1961+}
1962+
1963+bool HeightfieldRegionVisitor::postVisit(MetavoxelInfo& info) {
1964+ HeightfieldBuffer* buffer = NULL;
1965+ if (_depth == _heightDepth) {
1966+ int extendedHeightSize = _heightSize + HeightfieldBuffer::HEIGHT_EXTENSION;
1967+ int heightContentsSize = extendedHeightSize * extendedHeightSize;
1968+
1969+ int extendedColorSize = qMax(_inheritedColorDepth == -1 ? 0 :
1970+ signedLeftShift(_inheritedColorSize, _inheritedColorDepth - _depth) + HeightfieldBuffer::SHARED_EDGE,
1971+ _containedColorDepth == -1 ? 0 :
1972+ signedLeftShift(_containedColorSize, _containedColorDepth - _depth) + HeightfieldBuffer::SHARED_EDGE);
1973+ int colorContentsSize = extendedColorSize * extendedColorSize;
1974+
1975+ int extendedMaterialSize = qMax(_inheritedMaterialDepth == -1 ? 0 :
1976+ signedLeftShift(_inheritedMaterialSize, _inheritedMaterialDepth - _depth) + HeightfieldBuffer::SHARED_EDGE,
1977+ _containedMaterialDepth == -1 ? 0 :
1978+ signedLeftShift(_containedMaterialSize, _containedMaterialDepth - _depth) + HeightfieldBuffer::SHARED_EDGE);
1979+ int materialContentsSize = extendedMaterialSize * extendedMaterialSize;
18911980
18921981 const HeightfieldBuffer* existingBuffer = static_cast<const HeightfieldBuffer*>(
18931982 info.inputValues.at(3).getInlineValue<BufferDataPointer>().data());
18941983 Box bounds = info.getBounds();
18951984 if (existingBuffer && existingBuffer->getHeight().size() == heightContentsSize &&
1896− existingBuffer->getColor().size() == colorContentsSize) {
1897− // we already have a buffer of the correct resolution
1985+ existingBuffer->getColor().size() == colorContentsSize &&
1986+ existingBuffer->getMaterial().size() == materialContentsSize) {
1987+ // we already have a buffer of the correct resolution
18981988 addRegion(bounds, existingBuffer->getHeightBounds());
18991989 buffer = new HeightfieldBuffer(info.minimum, info.size, existingBuffer->getHeight(),
1900− existingBuffer->getColor(), materialContents, materials);
1901−
1990+ existingBuffer->getColor(), existingBuffer->getMaterial(), existingBuffer->getMaterials());
1991+
19021992 } else {
19031993 // we must create a new buffer and update its borders
19041994 buffer = new HeightfieldBuffer(info.minimum, info.size, QByteArray(heightContentsSize, 0),
1905− QByteArray(colorContentsSize, 0), materialContents, materials);
1995+ QByteArray(colorContentsSize, 0), QByteArray(materialContentsSize, 0));
19061996 const Box& heightBounds = buffer->getHeightBounds();
19071997 addRegion(bounds, heightBounds);
19081998
@@ -1919,10 +2009,17 @@ int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
19192009 _fetchVisitor.init(buffer);
19202010 _data->guide(_fetchVisitor);
19212011 }
2012+ _heightDepth = _containedColorDepth = _containedMaterialDepth = -1;
2013+ }
2014+ if (_depth == _inheritedColorDepth) {
2015+ _inheritedColorDepth = -1;
2016+ }
2017+ if (_depth == _inheritedMaterialDepth) {
2018+ _inheritedMaterialDepth = -1;
19222019 }
19232020 BufferDataPointer pointer(buffer);
19242021 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer));
1925− return STOP_RECURSION;
2022+ return true;
19262023 }
19272024
19282025 void HeightfieldRegionVisitor::addRegion(const Box& unextended, const Box& extended) {