Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 5 files). Show all
Unified · Split
| @@ -1006,16 +1006,14 @@ QByteArray HeightfieldBuffer::getUnextendedHeight() const { · 1005 unmodified lines | ||
| 1006 | 1006 | return unextended; |
| 1007 | 1007 | } |
| 1008 | 1008 | |
| 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); | |
| 1015 | 1012 | 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); | |
| 1019 | 1017 | } |
| 1020 | 1018 | return unextended; |
| 1021 | 1019 | } |
| @@ -1702,134 +1700,170 @@ public: · 680 unmodified lines | ||
| 1702 | 1700 | |
| 1703 | 1701 | HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections); |
| 1704 | 1702 | |
| 1705 | − void init(HeightfieldBuffer* buffer) { _buffer = buffer; } | |
| 1703 | + void init(HeightfieldBuffer* buffer); | |
| 1706 | 1704 | |
| 1707 | 1705 | virtual int visit(MetavoxelInfo& info); |
| 1706 | + virtual bool postVisit(MetavoxelInfo& info); | |
| 1708 | 1707 | |
| 1709 | 1708 | private: |
| 1710 | 1709 | |
| 1711 | 1710 | const QVector<Box>& _intersections; |
| 1712 | 1711 | HeightfieldBuffer* _buffer; |
| 1712 | + | |
| 1713 | + int _heightDepth; | |
| 1714 | + int _colorDepth; | |
| 1715 | + int _materialDepth; | |
| 1713 | 1716 | }; |
| 1714 | 1717 | |
| 1715 | 1718 | HeightfieldFetchVisitor::HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections) : |
| 1716 | 1719 | MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() << |
| 1717 | − AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector<AttributePointer>(), lod), | |
| 1720 | + AttributeRegistry::getInstance()->getHeightfieldColorAttribute() << | |
| 1721 | + AttributeRegistry::getInstance()->getHeightfieldMaterialAttribute(), QVector<AttributePointer>(), lod), | |
| 1718 | 1722 | _intersections(intersections) { |
| 1719 | 1723 | } |
| 1720 | 1724 | |
| 1725 | +void HeightfieldFetchVisitor::init(HeightfieldBuffer* buffer) { | |
| 1726 | + _buffer = buffer; | |
| 1727 | + _heightDepth = -1; | |
| 1728 | + _colorDepth = -1; | |
| 1729 | + _materialDepth = -1; | |
| 1730 | +} | |
| 1731 | + | |
| 1721 | 1732 | 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())) { | |
| 1725 | 1734 | return STOP_RECURSION; |
| 1726 | 1735 | } |
| 1727 | − if (!info.isLeaf && info.size > _buffer->getScale()) { | |
| 1736 | + if (!info.isLeaf) { | |
| 1728 | 1737 | return DEFAULT_ORDER; |
| 1729 | 1738 | } |
| 1739 | + postVisit(info); | |
| 1740 | + return STOP_RECURSION; | |
| 1741 | +} | |
| 1742 | + | |
| 1743 | +bool HeightfieldFetchVisitor::postVisit(MetavoxelInfo& info) { | |
| 1730 | 1744 | 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; | |
| 1733 | 1750 | } |
| 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(); | |
| 1734 | 1769 | foreach (const Box& intersection, _intersections) { |
| 1735 | 1770 | Box overlap = intersection.getIntersection(bounds); |
| 1736 | 1771 | if (overlap.isEmpty()) { |
| 1737 | 1772 | continue; |
| 1738 | 1773 | } |
| 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; | |
| 1755 | 1783 | |
| 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 | + } | |
| 1777 | 1815 | } |
| 1778 | 1816 | } |
| 1779 | 1817 | } |
| 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; | |
| 1809 | 1830 | |
| 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 | + } | |
| 1828 | 1860 | } |
| 1829 | 1861 | } |
| 1830 | 1862 | } |
| 1863 | + if (material) { | |
| 1864 | + } | |
| 1831 | 1865 | } |
| 1832 | − return STOP_RECURSION; | |
| 1866 | + return false; | |
| 1833 | 1867 | } |
| 1834 | 1868 | |
| 1835 | 1869 | class HeightfieldRegionVisitor : public MetavoxelVisitor { |
| @@ -1841,11 +1875,27 @@ public: · 5 unmodified lines | ||
| 1841 | 1875 | HeightfieldRegionVisitor(const MetavoxelLOD& lod); |
| 1842 | 1876 | |
| 1843 | 1877 | virtual int visit(MetavoxelInfo& info); |
| 1878 | + virtual bool postVisit(MetavoxelInfo& info); | |
| 1844 | 1879 | |
| 1845 | 1880 | private: |
| 1846 | 1881 | |
| 1847 | 1882 | void addRegion(const Box& unextended, const Box& extended); |
| 1848 | 1883 | |
| 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 | + | |
| 1849 | 1899 | QVector<Box> _intersections; |
| 1850 | 1900 | HeightfieldFetchVisitor _fetchVisitor; |
| 1851 | 1901 | }; |
| @@ -1857,52 +1907,92 @@ HeightfieldRegionVisitor::HeightfieldRegionVisitor(const MetavoxelLOD& lod) : · 5 unmodified lines | ||
| 1857 | 1907 | Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>() << |
| 1858 | 1908 | Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod), |
| 1859 | 1909 | 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), | |
| 1860 | 1915 | _fetchVisitor(lod, _intersections) { |
| 1861 | 1916 | } |
| 1862 | 1917 | |
| 1918 | +static int signedLeftShift(int value, int shift) { | |
| 1919 | + return (shift > 0) ? value << shift : value >> (-shift); | |
| 1920 | +} | |
| 1921 | + | |
| 1863 | 1922 | int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) { |
| 1864 | − if (!info.isLeaf) { | |
| 1865 | − return DEFAULT_ORDER; | |
| 1866 | − } | |
| 1867 | − HeightfieldBuffer* buffer = NULL; | |
| 1868 | 1923 | HeightfieldHeightDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldHeightDataPointer>(); |
| 1924 | + int order = DEFAULT_ORDER; | |
| 1869 | 1925 | 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; | |
| 1882 | 1941 | } |
| 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; | |
| 1890 | 1954 | } |
| 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; | |
| 1891 | 1980 | |
| 1892 | 1981 | const HeightfieldBuffer* existingBuffer = static_cast<const HeightfieldBuffer*>( |
| 1893 | 1982 | info.inputValues.at(3).getInlineValue<BufferDataPointer>().data()); |
| 1894 | 1983 | Box bounds = info.getBounds(); |
| 1895 | 1984 | 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 | |
| 1898 | 1988 | addRegion(bounds, existingBuffer->getHeightBounds()); |
| 1899 | 1989 | buffer = new HeightfieldBuffer(info.minimum, info.size, existingBuffer->getHeight(), |
| 1900 | − existingBuffer->getColor(), materialContents, materials); | |
| 1901 | − | |
| 1990 | + existingBuffer->getColor(), existingBuffer->getMaterial(), existingBuffer->getMaterials()); | |
| 1991 | + | |
| 1902 | 1992 | } else { |
| 1903 | 1993 | // we must create a new buffer and update its borders |
| 1904 | 1994 | buffer = new HeightfieldBuffer(info.minimum, info.size, QByteArray(heightContentsSize, 0), |
| 1905 | − QByteArray(colorContentsSize, 0), materialContents, materials); | |
| 1995 | + QByteArray(colorContentsSize, 0), QByteArray(materialContentsSize, 0)); | |
| 1906 | 1996 | const Box& heightBounds = buffer->getHeightBounds(); |
| 1907 | 1997 | addRegion(bounds, heightBounds); |
| 1908 | 1998 | |
| @@ -1919,10 +2009,17 @@ int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines | ||
| 1919 | 2009 | _fetchVisitor.init(buffer); |
| 1920 | 2010 | _data->guide(_fetchVisitor); |
| 1921 | 2011 | } |
| 2012 | + _heightDepth = _containedColorDepth = _containedMaterialDepth = -1; | |
| 2013 | + } | |
| 2014 | + if (_depth == _inheritedColorDepth) { | |
| 2015 | + _inheritedColorDepth = -1; | |
| 2016 | + } | |
| 2017 | + if (_depth == _inheritedMaterialDepth) { | |
| 2018 | + _inheritedMaterialDepth = -1; | |
| 1922 | 2019 | } |
| 1923 | 2020 | BufferDataPointer pointer(buffer); |
| 1924 | 2021 | info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); |
| 1925 | − return STOP_RECURSION; | |
| 2022 | + return true; | |
| 1926 | 2023 | } |
| 1927 | 2024 | |
| 1928 | 2025 | void HeightfieldRegionVisitor::addRegion(const Box& unextended, const Box& extended) { |