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
672672 class BorderFetchVisitor : public MetavoxelVisitor {
673673 public:
674674
675− BorderFetchVisitor(const MetavoxelLOD& lod, QByteArray& height);
675+ BorderFetchVisitor(const MetavoxelLOD& lod, HeightfieldBuffer* buffer);
676676
677677 virtual int visit(MetavoxelInfo& info);
678678
679679 private:
680680
681− QByteArray& _height;
681+ HeightfieldBuffer* _buffer;
682+ Box _expandedBounds;
683+ int _heightSize;
684+ float _heightExtension;
685+ int _colorSize;
686+ float _colorExtension;
687+ Box _colorBounds;
682688 };
683689
684−BorderFetchVisitor::BorderFetchVisitor(const MetavoxelLOD& lod, QByteArray& height) :
685− MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute(),
686− QVector<AttributePointer>(), lod),
687− _height(height) {
690+BorderFetchVisitor::BorderFetchVisitor(const MetavoxelLOD& lod, HeightfieldBuffer* buffer) :
691+ MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<
692+ AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector<AttributePointer>(), lod),
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+ }
688711 }
689712
690713 int 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()) {
692719 return DEFAULT_ORDER;
693720 }
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+
694818 return STOP_RECURSION;
695819 }
696820
@@ -724,6 +848,8 @@ int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) { · 27 unmodified lines
724848 }
725849 }
726850 buffer = new HeightfieldBuffer(info.minimum, info.size, extendedHeightContents, extendedColorContents);
851+ BorderFetchVisitor visitor(_lod, buffer);
852+ _data->guide(visitor);
727853 }
728854 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
729855 return STOP_RECURSION;