History

More work on edge rejiggery.

Andrzej Kapolka committed 12 years ago

Commit 21d6c3c1 parent ee01d854 files · +148 −9Browse files

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

Unified · Split

interface/src/MetavoxelSystem.cpp+133−7
@@ -672,25 +672,149 @@ HeightfieldAugmentVisitor::HeightfieldAugmentVisitor(const MetavoxelLOD& lod) : · 671 unmodified lines
672class BorderFetchVisitor : public MetavoxelVisitor {672class BorderFetchVisitor : public MetavoxelVisitor {
673public:673public:
674 674
675 BorderFetchVisitor(const MetavoxelLOD& lod, QByteArray& height);675 BorderFetchVisitor(const MetavoxelLOD& lod, HeightfieldBuffer* buffer);
676 676
677 virtual int visit(MetavoxelInfo& info);677 virtual int visit(MetavoxelInfo& info);
678 678
679private:679private:
680 680
681 QByteArray& _height;681 HeightfieldBuffer* _buffer;
682 Box _expandedBounds;
683 int _heightSize;
684 float _heightExtension;
685 int _colorSize;
686 float _colorExtension;
687 Box _colorBounds;
682};688};
683 689
684BorderFetchVisitor::BorderFetchVisitor(const MetavoxelLOD& lod, QByteArray& height) :690BorderFetchVisitor::BorderFetchVisitor(const MetavoxelLOD& lod, HeightfieldBuffer* buffer) :
685 MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute(),691 MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<
686 QVector<AttributePointer>(), lod),692 AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector<AttributePointer>(), lod),
687 _height(height) {693 _buffer(buffer),
694 _expandedBounds(_buffer->getTranslation(), _buffer->getTranslation() +
695 glm::vec3(_buffer->getScale(), _buffer->getScale(), _buffer->getScale())),
696 _heightSize(glm::sqrt(buffer->getHeight().size())),
697 _heightExtension(_buffer->getScale() / (_heightSize - HeightfieldBuffer::HEIGHT_EXTENSION)),
698 _colorSize(glm::sqrt(buffer->getColor().size() / HeightfieldData::COLOR_BYTES)),
699 _colorBounds(_expandedBounds) {
700
701 _expandedBounds.minimum.x -= _heightExtension * HeightfieldBuffer::HEIGHT_BORDER;
702 _expandedBounds.minimum.z -= _heightExtension * HeightfieldBuffer::HEIGHT_BORDER;
703 _expandedBounds.maximum.x += _heightExtension * (HeightfieldBuffer::HEIGHT_BORDER + HeightfieldBuffer::SHARED_EDGE);
704 _expandedBounds.maximum.z += _heightExtension * (HeightfieldBuffer::HEIGHT_BORDER + HeightfieldBuffer::SHARED_EDGE);
705
706 if (_colorSize > 0) {
707 _colorExtension = buffer->getScale() / (_colorSize - HeightfieldBuffer::SHARED_EDGE);
708 _colorBounds.maximum.x += _colorExtension * HeightfieldBuffer::SHARED_EDGE;
709 _colorBounds.maximum.z += _colorExtension * HeightfieldBuffer::SHARED_EDGE;
710 }
688}711}
689 712
690int BorderFetchVisitor::visit(MetavoxelInfo& info) {713int BorderFetchVisitor::visit(MetavoxelInfo& info) {
691 if (!info.isLeaf) {714 Box bounds = info.getBounds();
715 if (!bounds.intersects(_expandedBounds)) {
716 return STOP_RECURSION;
717 }
718 if (!info.isLeaf && info.size > _buffer->getScale()) {
692 return DEFAULT_ORDER;719 return DEFAULT_ORDER;
693 }720 }
721 if (_expandedBounds.contains(bounds)) {
722 return STOP_RECURSION; // this is the principal, which we've already filled in
723 }
724 HeightfieldDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldDataPointer>();
725 if (!height) {
726 return STOP_RECURSION;
727 }
728 Box intersection = bounds.getIntersection(_expandedBounds);
729 int destX = glm::round((intersection.minimum.x - _expandedBounds.minimum.x) / _heightExtension);
730 int destY = glm::round((intersection.minimum.z - _expandedBounds.minimum.z) / _heightExtension);
731 int destWidth = glm::round((intersection.maximum.x - intersection.minimum.x) / _heightExtension);
732 int destHeight = glm::round((intersection.maximum.z - intersection.minimum.z) / _heightExtension);
733 char* dest = _buffer->getHeight().data() + destY * _heightSize + destX;
734
735 const QByteArray& srcHeight = height->getContents();
736 int srcSize = glm::sqrt(srcHeight.size());
737 float srcExtension = info.size / srcSize;
738
739 if (info.size == _buffer->getScale() && srcSize == (_heightSize - HeightfieldBuffer::HEIGHT_EXTENSION)) {
740 // easy case: same resolution
741 int srcX = glm::round((intersection.minimum.x - info.minimum.x) / srcExtension);
742 int srcY = glm::round((intersection.minimum.z - info.minimum.z) / srcExtension);
743
744 const char* src = srcHeight.constData() + srcY * srcSize + srcX;
745 for (int y = 0; y < destHeight; y++, src += srcSize, dest += _heightSize) {
746 memcpy(dest, src, destWidth);
747 }
748 } else {
749 // more difficult: different resolutions
750 float srcX = (intersection.minimum.x - info.minimum.x) / srcExtension;
751 float srcY = (intersection.minimum.z - info.minimum.z) / srcExtension;
752 float srcIncrement = _heightExtension / srcExtension;
753 int shift = 0;
754 float size = _buffer->getScale();
755 while (size < info.size) {
756 shift++;
757 size *= 2.0f;
758 }
759 const int EIGHT_BIT_MAXIMUM = 255;
760 int subtract = (_buffer->getTranslation().y - info.minimum.y) * EIGHT_BIT_MAXIMUM / _buffer->getScale();
761 for (int y = 0; y < destHeight; y++, dest += _heightSize, srcY += srcIncrement) {
762 const uchar* src = (const uchar*)srcHeight.constData() + (int)srcY * srcSize;
763 float lineSrcX = srcX;
764 for (char* lineDest = dest, *end = dest + destWidth; lineDest != end; lineDest++, lineSrcX += srcIncrement) {
765 *lineDest = qMin(qMax(0, (src[(int)lineSrcX] << shift) - subtract), EIGHT_BIT_MAXIMUM);
766 }
767 }
768 }
769
770 if (_colorSize == 0) {
771 return STOP_RECURSION;
772 }
773 HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
774 if (!color) {
775 return STOP_RECURSION;
776 }
777 intersection = bounds.getIntersection(_colorBounds);
778 destX = glm::round((intersection.minimum.x - _colorBounds.minimum.x) / _colorExtension);
779 destY = glm::round((intersection.minimum.z - _colorBounds.minimum.z) / _colorExtension);
780 destWidth = glm::round((intersection.maximum.x - intersection.minimum.x) / _colorExtension);
781 destHeight = glm::round((intersection.maximum.z - intersection.minimum.z) / _colorExtension);
782 dest = _buffer->getColor().data() + (destY * _colorSize + destX) * HeightfieldData::COLOR_BYTES;
783 int destStride = _colorSize * HeightfieldData::COLOR_BYTES;
784 int destBytes = destWidth * HeightfieldData::COLOR_BYTES;
785
786 const QByteArray& srcColor = color->getContents();
787 srcSize = glm::sqrt(srcColor.size() / HeightfieldData::COLOR_BYTES);
788 int srcStride = srcSize * HeightfieldData::COLOR_BYTES;
789 srcExtension = info.size / srcSize;
790
791 if (srcExtension == _colorExtension) {
792 // easy case: same resolution
793 int srcX = glm::round((intersection.minimum.x - info.minimum.x) / srcExtension);
794 int srcY = glm::round((intersection.minimum.z - info.minimum.z) / srcExtension);
795
796 const char* src = srcColor.constData() + (srcY * srcSize + srcX) * HeightfieldData::COLOR_BYTES;
797 for (int y = 0; y < destHeight; y++, src += srcStride, dest += destStride) {
798 memcpy(dest, src, destBytes);
799 }
800 } else {
801 // more difficult: different resolutions
802 float srcX = (intersection.minimum.x - info.minimum.x) / srcExtension;
803 float srcY = (intersection.minimum.z - info.minimum.z) / srcExtension;
804 float srcIncrement = _colorExtension / srcExtension;
805 for (int y = 0; y < destHeight; y++, dest += destStride, srcY += srcIncrement) {
806 const char* src = srcColor.constData() + (int)srcY * srcStride;
807 float lineSrcX = srcX;
808 for (char* lineDest = dest, *end = dest + destBytes; lineDest != end; lineDest += HeightfieldData::COLOR_BYTES,
809 lineSrcX += srcIncrement) {
810 const char* lineSrc = src + (int)lineSrcX * HeightfieldData::COLOR_BYTES;
811 lineDest[0] = lineSrc[0];
812 lineDest[1] = lineSrc[1];
813 lineDest[2] = lineSrc[2];
814 }
815 }
816 }
817
694 return STOP_RECURSION;818 return STOP_RECURSION;
695}819}
696 820
@@ -724,6 +848,8 @@ int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) { · 27 unmodified lines
724 }848 }
725 }849 }
726 buffer = new HeightfieldBuffer(info.minimum, info.size, extendedHeightContents, extendedColorContents);850 buffer = new HeightfieldBuffer(info.minimum, info.size, extendedHeightContents, extendedColorContents);
851 BorderFetchVisitor visitor(_lod, buffer);
852 _data->guide(visitor);
727 }853 }
728 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));854 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
729 return STOP_RECURSION;855 return STOP_RECURSION;