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 | return unextended; | 1006 | return unextended; |
| 1007 | } | 1007 | } |
| 1008 | 1008 | ||
| 1009 | QByteArray HeightfieldBuffer::getUnextendedColor() const { | 1009 | QByteArray HeightfieldBuffer::getUnextendedColor(int x, int y) const { |
| 1010 | int srcSize = glm::sqrt(float(_color.size() / DataBlock::COLOR_BYTES)); | 1010 | int unextendedSize = _heightSize - HEIGHT_EXTENSION; |
| 1011 | int destSize = srcSize - 1; | 1011 | QByteArray unextended(unextendedSize * unextendedSize * DataBlock::COLOR_BYTES, 0); |
| 1012 | QByteArray unextended(destSize * destSize * DataBlock::COLOR_BYTES, 0); | ||
| 1013 | const char* src = _color.constData(); | ||
| 1014 | int srcStride = srcSize * DataBlock::COLOR_BYTES; | ||
| 1015 | char* dest = unextended.data(); | 1012 | char* dest = unextended.data(); |
| 1016 | int destStride = destSize * DataBlock::COLOR_BYTES; | 1013 | const char* src = _color.constData() + (y * _colorSize + x) * unextendedSize * DataBlock::COLOR_BYTES; |
| 1017 | for (int z = 0; z < destSize; z++, src += srcStride, dest += destStride) { | 1014 | for (int z = 0; z < unextendedSize; z++, dest += unextendedSize * DataBlock::COLOR_BYTES, |
| 1018 | memcpy(dest, src, destStride); | 1015 | src += _colorSize * DataBlock::COLOR_BYTES) { |
| 1016 | memcpy(dest, src, unextendedSize * DataBlock::COLOR_BYTES); | ||
| 1019 | } | 1017 | } |
| 1020 | return unextended; | 1018 | return unextended; |
| 1021 | } | 1019 | } |
| @@ -1702,134 +1700,170 @@ public: · 680 unmodified lines | |||
| 1702 | 1700 | ||
| 1703 | HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections); | 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 | virtual int visit(MetavoxelInfo& info); | 1705 | virtual int visit(MetavoxelInfo& info); |
| 1706 | virtual bool postVisit(MetavoxelInfo& info); | ||
| 1708 | 1707 | ||
| 1709 | private: | 1708 | private: |
| 1710 | 1709 | ||
| 1711 | const QVector<Box>& _intersections; | 1710 | const QVector<Box>& _intersections; |
| 1712 | HeightfieldBuffer* _buffer; | 1711 | HeightfieldBuffer* _buffer; |
| 1712 | |||
| 1713 | int _heightDepth; | ||
| 1714 | int _colorDepth; | ||
| 1715 | int _materialDepth; | ||
| 1713 | }; | 1716 | }; |
| 1714 | 1717 | ||
| 1715 | HeightfieldFetchVisitor::HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections) : | 1718 | HeightfieldFetchVisitor::HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections) : |
| 1716 | MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() << | 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 | _intersections(intersections) { | 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 | int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) { | 1732 | int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) { |
| 1722 | Box bounds = info.getBounds(); | 1733 | if (!info.getBounds().intersects(_buffer->getHeightBounds())) { |
| 1723 | const Box& heightBounds = _buffer->getHeightBounds(); | ||
| 1724 | if (!bounds.intersects(heightBounds)) { | ||
| 1725 | return STOP_RECURSION; | 1734 | return STOP_RECURSION; |
| 1726 | } | 1735 | } |
| 1727 | if (!info.isLeaf && info.size > _buffer->getScale()) { | 1736 | if (!info.isLeaf) { |
| 1728 | return DEFAULT_ORDER; | 1737 | return DEFAULT_ORDER; |
| 1729 | } | 1738 | } |
| 1739 | postVisit(info); | ||
| 1740 | return STOP_RECURSION; | ||
| 1741 | } | ||
| 1742 | |||
| 1743 | bool HeightfieldFetchVisitor::postVisit(MetavoxelInfo& info) { | ||
| 1730 | HeightfieldHeightDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldHeightDataPointer>(); | 1744 | HeightfieldHeightDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldHeightDataPointer>(); |
| 1731 | if (!height) { | 1745 | if (height || _heightDepth != -1) { |
| 1732 | return STOP_RECURSION; | 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 | foreach (const Box& intersection, _intersections) { | 1769 | foreach (const Box& intersection, _intersections) { |
| 1735 | Box overlap = intersection.getIntersection(bounds); | 1770 | Box overlap = intersection.getIntersection(bounds); |
| 1736 | if (overlap.isEmpty()) { | 1771 | if (overlap.isEmpty()) { |
| 1737 | continue; | 1772 | continue; |
| 1738 | } | 1773 | } |
| 1739 | float heightIncrement = _buffer->getHeightIncrement(); | 1774 | if (height) { |
| 1740 | int destX = (overlap.minimum.x - heightBounds.minimum.x) / heightIncrement; | 1775 | float heightIncrement = _buffer->getHeightIncrement(); |
| 1741 | int destY = (overlap.minimum.z - heightBounds.minimum.z) / heightIncrement; | 1776 | const Box& heightBounds = _buffer->getHeightBounds(); |
| 1742 | int destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / heightIncrement); | 1777 | int destX = (overlap.minimum.x - heightBounds.minimum.x) / heightIncrement; |
| 1743 | int destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / heightIncrement); | 1778 | int destY = (overlap.minimum.z - heightBounds.minimum.z) / heightIncrement; |
| 1744 | int heightSize = _buffer->getHeightSize(); | 1779 | int destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / heightIncrement); |
| 1745 | char* dest = _buffer->getHeight().data() + destY * heightSize + destX; | 1780 | int destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / heightIncrement); |
| 1746 | 1781 | int heightSize = _buffer->getHeightSize(); | |
| 1747 | const QByteArray& srcHeight = height->getContents(); | 1782 | char* dest = _buffer->getHeight().data() + destY * heightSize + destX; |
| 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; | ||
| 1755 | 1783 | ||
| 1756 | const char* src = srcHeight.constData() + srcY * srcSize + srcX; | 1784 | const QByteArray& srcHeight = height->getContents(); |
| 1757 | for (int y = 0; y < destHeight; y++, src += srcSize, dest += heightSize) { | 1785 | int srcSize = glm::sqrt((float)srcHeight.size()); |
| 1758 | memcpy(dest, src, destWidth); | 1786 | float srcIncrement = info.size / srcSize; |
| 1759 | } | 1787 | |
| 1760 | } else { | 1788 | if (info.size == _buffer->getScale() && srcSize == (heightSize - HeightfieldBuffer::HEIGHT_EXTENSION)) { |
| 1761 | // more difficult: different resolutions | 1789 | // easy case: same resolution |
| 1762 | float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement; | 1790 | int srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement; |
| 1763 | float srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement; | 1791 | int srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement; |
| 1764 | float srcAdvance = heightIncrement / srcIncrement; | 1792 | |
| 1765 | int shift = 0; | 1793 | const char* src = srcHeight.constData() + srcY * srcSize + srcX; |
| 1766 | float size = _buffer->getScale(); | 1794 | for (int y = 0; y < destHeight; y++, src += srcSize, dest += heightSize) { |
| 1767 | while (size < info.size) { | 1795 | memcpy(dest, src, destWidth); |
| 1768 | shift++; | 1796 | } |
| 1769 | size *= 2.0f; | 1797 | } else { |
| 1770 | } | 1798 | // more difficult: different resolutions |
| 1771 | int subtract = (_buffer->getTranslation().y - info.minimum.y) * EIGHT_BIT_MAXIMUM / _buffer->getScale(); | 1799 | float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement; |
| 1772 | for (int y = 0; y < destHeight; y++, dest += heightSize, srcY += srcAdvance) { | 1800 | float srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement; |
| 1773 | const uchar* src = (const uchar*)srcHeight.constData() + (int)srcY * srcSize; | 1801 | float srcAdvance = heightIncrement / srcIncrement; |
| 1774 | float lineSrcX = srcX; | 1802 | int shift = 0; |
| 1775 | for (char* lineDest = dest, *end = dest + destWidth; lineDest != end; lineDest++, lineSrcX += srcAdvance) { | 1803 | float size = _buffer->getScale(); |
| 1776 | *lineDest = qMin(qMax(0, (src[(int)lineSrcX] << shift) - subtract), EIGHT_BIT_MAXIMUM); | 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 | 1818 | if (color) { | |
| 1781 | int colorSize = _buffer->getColorSize(); | 1819 | const Box& colorBounds = _buffer->getColorBounds(); |
| 1782 | if (colorSize == 0) { | 1820 | overlap = colorBounds.getIntersection(overlap); |
| 1783 | continue; | 1821 | float colorIncrement = _buffer->getColorIncrement(); |
| 1784 | } | 1822 | int destX = (overlap.minimum.x - colorBounds.minimum.x) / colorIncrement; |
| 1785 | HeightfieldColorDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>(); | 1823 | int destY = (overlap.minimum.z - colorBounds.minimum.z) / colorIncrement; |
| 1786 | if (!color) { | 1824 | int destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / colorIncrement); |
| 1787 | continue; | 1825 | int destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / colorIncrement); |
| 1788 | } | 1826 | int colorSize = _buffer->getColorSize(); |
| 1789 | const Box& colorBounds = _buffer->getColorBounds(); | 1827 | char* dest = _buffer->getColor().data() + (destY * colorSize + destX) * DataBlock::COLOR_BYTES; |
| 1790 | overlap = colorBounds.getIntersection(overlap); | 1828 | int destStride = colorSize * DataBlock::COLOR_BYTES; |
| 1791 | float colorIncrement = _buffer->getColorIncrement(); | 1829 | int destBytes = destWidth * DataBlock::COLOR_BYTES; |
| 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; | ||
| 1809 | 1830 | ||
| 1810 | const char* src = srcColor.constData() + (srcY * srcSize + srcX) * DataBlock::COLOR_BYTES; | 1831 | const QByteArray& srcColor = color->getContents(); |
| 1811 | for (int y = 0; y < destHeight; y++, src += srcStride, dest += destStride) { | 1832 | int srcSize = glm::sqrt(float(srcColor.size() / DataBlock::COLOR_BYTES)); |
| 1812 | memcpy(dest, src, destBytes); | 1833 | int srcStride = srcSize * DataBlock::COLOR_BYTES; |
| 1813 | } | 1834 | float srcIncrement = info.size / srcSize; |
| 1814 | } else { | 1835 | |
| 1815 | // more difficult: different resolutions | 1836 | if (srcIncrement == colorIncrement) { |
| 1816 | float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement; | 1837 | // easy case: same resolution |
| 1817 | float srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement; | 1838 | int srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement; |
| 1818 | float srcAdvance = colorIncrement / srcIncrement; | 1839 | int srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement; |
| 1819 | for (int y = 0; y < destHeight; y++, dest += destStride, srcY += srcAdvance) { | 1840 | |
| 1820 | const char* src = srcColor.constData() + (int)srcY * srcStride; | 1841 | const char* src = srcColor.constData() + (srcY * srcSize + srcX) * DataBlock::COLOR_BYTES; |
| 1821 | float lineSrcX = srcX; | 1842 | for (int y = 0; y < destHeight; y++, src += srcStride, dest += destStride) { |
| 1822 | for (char* lineDest = dest, *end = dest + destBytes; lineDest != end; lineDest += DataBlock::COLOR_BYTES, | 1843 | memcpy(dest, src, destBytes); |
| 1823 | lineSrcX += srcAdvance) { | 1844 | } |
| 1824 | const char* lineSrc = src + (int)lineSrcX * DataBlock::COLOR_BYTES; | 1845 | } else { |
| 1825 | lineDest[0] = lineSrc[0]; | 1846 | // more difficult: different resolutions |
| 1826 | lineDest[1] = lineSrc[1]; | 1847 | float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement; |
| 1827 | lineDest[2] = lineSrc[2]; | 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 | class HeightfieldRegionVisitor : public MetavoxelVisitor { | 1869 | class HeightfieldRegionVisitor : public MetavoxelVisitor { |
| @@ -1841,11 +1875,27 @@ public: · 5 unmodified lines | |||
| 1841 | HeightfieldRegionVisitor(const MetavoxelLOD& lod); | 1875 | HeightfieldRegionVisitor(const MetavoxelLOD& lod); |
| 1842 | 1876 | ||
| 1843 | virtual int visit(MetavoxelInfo& info); | 1877 | virtual int visit(MetavoxelInfo& info); |
| 1878 | virtual bool postVisit(MetavoxelInfo& info); | ||
| 1844 | 1879 | ||
| 1845 | private: | 1880 | private: |
| 1846 | 1881 | ||
| 1847 | void addRegion(const Box& unextended, const Box& extended); | 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 | QVector<Box> _intersections; | 1899 | QVector<Box> _intersections; |
| 1850 | HeightfieldFetchVisitor _fetchVisitor; | 1900 | HeightfieldFetchVisitor _fetchVisitor; |
| 1851 | }; | 1901 | }; |
| @@ -1857,52 +1907,92 @@ HeightfieldRegionVisitor::HeightfieldRegionVisitor(const MetavoxelLOD& lod) : · 5 unmodified lines | |||
| 1857 | Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>() << | 1907 | Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>() << |
| 1858 | Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod), | 1908 | Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod), |
| 1859 | regionBounds(glm::vec3(FLT_MAX, FLT_MAX, FLT_MAX), glm::vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX)), | 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 | _fetchVisitor(lod, _intersections) { | 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 | int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) { | 1922 | int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) { |
| 1864 | if (!info.isLeaf) { | ||
| 1865 | return DEFAULT_ORDER; | ||
| 1866 | } | ||
| 1867 | HeightfieldBuffer* buffer = NULL; | ||
| 1868 | HeightfieldHeightDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldHeightDataPointer>(); | 1923 | HeightfieldHeightDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldHeightDataPointer>(); |
| 1924 | int order = DEFAULT_ORDER; | ||
| 1869 | if (height) { | 1925 | if (height) { |
| 1870 | const QByteArray& heightContents = height->getContents(); | 1926 | _heightSize = glm::sqrt((float)height->getContents().size()); |
| 1871 | int size = glm::sqrt(float(heightContents.size())); | 1927 | _heightDepth = _depth; |
| 1872 | int extendedSize = size + HeightfieldBuffer::HEIGHT_EXTENSION; | 1928 | order |= ALL_NODES_REST; |
| 1873 | int heightContentsSize = extendedSize * extendedSize; | 1929 | } |
| 1874 | 1930 | HeightfieldColorDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>(); | |
| 1875 | HeightfieldColorDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>(); | 1931 | if (color) { |
| 1876 | int colorContentsSize = 0; | 1932 | int colorSize = glm::sqrt((float)(color->getContents().size() / DataBlock::COLOR_BYTES)); |
| 1877 | if (color) { | 1933 | if (_heightDepth == -1) { |
| 1878 | const QByteArray& colorContents = color->getContents(); | 1934 | _inheritedColorSize = colorSize; |
| 1879 | int colorSize = glm::sqrt(float(colorContents.size() / DataBlock::COLOR_BYTES)); | 1935 | _inheritedColorDepth = _depth; |
| 1880 | int extendedColorSize = colorSize + HeightfieldBuffer::SHARED_EDGE; | 1936 | |
| 1881 | colorContentsSize = extendedColorSize * extendedColorSize * DataBlock::COLOR_BYTES; | 1937 | } else if (_containedColorDepth == -1 || |
| 1938 | colorSize > signedLeftShift(_containedColorSize, _containedColorDepth - _depth)) { | ||
| 1939 | _containedColorSize = colorSize; | ||
| 1940 | _containedColorDepth = _depth; | ||
| 1882 | } | 1941 | } |
| 1883 | 1942 | } | |
| 1884 | HeightfieldMaterialDataPointer material = info.inputValues.at(2).getInlineValue<HeightfieldMaterialDataPointer>(); | 1943 | HeightfieldMaterialDataPointer material = info.inputValues.at(2).getInlineValue<HeightfieldMaterialDataPointer>(); |
| 1885 | QByteArray materialContents; | 1944 | if (material) { |
| 1886 | QVector<SharedObjectPointer> materials; | 1945 | int materialSize = glm::sqrt((float)material->getContents().size()); |
| 1887 | if (material) { | 1946 | if (_heightDepth == -1) { |
| 1888 | materialContents = material->getContents(); | 1947 | _inheritedMaterialSize = materialSize; |
| 1889 | materials = material->getMaterials(); | 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 | const HeightfieldBuffer* existingBuffer = static_cast<const HeightfieldBuffer*>( | 1981 | const HeightfieldBuffer* existingBuffer = static_cast<const HeightfieldBuffer*>( |
| 1893 | info.inputValues.at(3).getInlineValue<BufferDataPointer>().data()); | 1982 | info.inputValues.at(3).getInlineValue<BufferDataPointer>().data()); |
| 1894 | Box bounds = info.getBounds(); | 1983 | Box bounds = info.getBounds(); |
| 1895 | if (existingBuffer && existingBuffer->getHeight().size() == heightContentsSize && | 1984 | if (existingBuffer && existingBuffer->getHeight().size() == heightContentsSize && |
| 1896 | existingBuffer->getColor().size() == colorContentsSize) { | 1985 | existingBuffer->getColor().size() == colorContentsSize && |
| 1897 | // we already have a buffer of the correct resolution | 1986 | existingBuffer->getMaterial().size() == materialContentsSize) { |
| 1987 | // we already have a buffer of the correct resolution | ||
| 1898 | addRegion(bounds, existingBuffer->getHeightBounds()); | 1988 | addRegion(bounds, existingBuffer->getHeightBounds()); |
| 1899 | buffer = new HeightfieldBuffer(info.minimum, info.size, existingBuffer->getHeight(), | 1989 | buffer = new HeightfieldBuffer(info.minimum, info.size, existingBuffer->getHeight(), |
| 1900 | existingBuffer->getColor(), materialContents, materials); | 1990 | existingBuffer->getColor(), existingBuffer->getMaterial(), existingBuffer->getMaterials()); |
| 1901 | 1991 | ||
| 1902 | } else { | 1992 | } else { |
| 1903 | // we must create a new buffer and update its borders | 1993 | // we must create a new buffer and update its borders |
| 1904 | buffer = new HeightfieldBuffer(info.minimum, info.size, QByteArray(heightContentsSize, 0), | 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 | const Box& heightBounds = buffer->getHeightBounds(); | 1996 | const Box& heightBounds = buffer->getHeightBounds(); |
| 1907 | addRegion(bounds, heightBounds); | 1997 | addRegion(bounds, heightBounds); |
| 1908 | 1998 | ||
| @@ -1919,10 +2009,17 @@ int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines | |||
| 1919 | _fetchVisitor.init(buffer); | 2009 | _fetchVisitor.init(buffer); |
| 1920 | _data->guide(_fetchVisitor); | 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 | BufferDataPointer pointer(buffer); | 2020 | BufferDataPointer pointer(buffer); |
| 1924 | info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); | 2021 | info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); |
| 1925 | return STOP_RECURSION; | 2022 | return true; |
| 1926 | } | 2023 | } |
| 1927 | 2024 | ||
| 1928 | void HeightfieldRegionVisitor::addRegion(const Box& unextended, const Box& extended) { | 2025 | void HeightfieldRegionVisitor::addRegion(const Box& unextended, const Box& extended) { |