History

Alllmost ready with the big edge sharing rejiggery.

Andrzej Kapolka committed 12 years ago

Commit 05d6b621 parent 62b84ed5 files · +297 −177Browse files

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

Unified · Split

interface/src/MetavoxelSystem.cpp+273−176
@@ -37,6 +37,9 @@ void MetavoxelSystem::init() { · 36 unmodified lines
3737 _pointBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(new BufferDataAttribute("pointBuffer"));
3838 _heightfieldBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(
3939 new BufferDataAttribute("heightfieldBuffer"));
40+
41+ _heightfieldBufferAttribute->setLODThresholdMultiplier(
42+ AttributeRegistry::getInstance()->getHeightfieldAttribute()->getLODThresholdMultiplier());
4043 }
4144
4245 MetavoxelLOD MetavoxelSystem::getLOD() {
@@ -382,7 +385,7 @@ float MetavoxelSystem::getHeightfieldHeight(const glm::vec3& location) { · 339 unmodified lines
382385 class HeightfieldCursorRenderVisitor : public MetavoxelVisitor {
383386 public:
384387
385− HeightfieldCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds);
388+ HeightfieldCursorRenderVisitor(const Box& bounds);
386389
387390 virtual int visit(MetavoxelInfo& info);
388391
@@ -391,9 +394,9 @@ private: · 2 unmodified lines
391394 Box _bounds;
392395 };
393396
394−HeightfieldCursorRenderVisitor::HeightfieldCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds) :
397+HeightfieldCursorRenderVisitor::HeightfieldCursorRenderVisitor(const Box& bounds) :
395398 MetavoxelVisitor(QVector<AttributePointer>() <<
396− Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>(), lod),
399+ Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute()),
397400 _bounds(bounds) {
398401 }
399402
@@ -433,7 +436,7 @@ void MetavoxelSystem::renderHeightfieldCursor(const glm::vec3& position, float r · 33 unmodified lines
433436 glActiveTexture(GL_TEXTURE0);
434437
435438 glm::vec3 extents(radius, radius, radius);
436− HeightfieldCursorRenderVisitor visitor(getLOD(), Box(position - extents, position + extents));
439+ HeightfieldCursorRenderVisitor visitor(Box(position - extents, position + extents));
437440 guideToAugmented(visitor);
438441
439442 DefaultMetavoxelRendererImplementation::getHeightfieldCursorProgram().release();
@@ -601,11 +604,24 @@ HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale, · 161 unmodified lines
601604 const QByteArray& height, const QByteArray& color) :
602605 _translation(translation),
603606 _scale(scale),
607+ _heightBounds(translation, translation + glm::vec3(scale, scale, scale)),
608+ _colorBounds(_heightBounds),
604609 _height(height),
605610 _color(color),
606611 _heightTextureID(0),
607612 _colorTextureID(0),
608− _heightSize(glm::sqrt(height.size())) {
613+ _heightSize(glm::sqrt(height.size())),
614+ _heightIncrement(scale / (_heightSize - HEIGHT_EXTENSION)),
615+ _colorSize(glm::sqrt(color.size() / HeightfieldData::COLOR_BYTES)),
616+ _colorIncrement(scale / (_colorSize - SHARED_EDGE)) {
617+
618+ _heightBounds.minimum.x -= _heightIncrement * HEIGHT_BORDER;
619+ _heightBounds.minimum.z -= _heightIncrement * HEIGHT_BORDER;
620+ _heightBounds.maximum.x += _heightIncrement * (SHARED_EDGE + HEIGHT_BORDER);
621+ _heightBounds.maximum.z += _heightIncrement * (SHARED_EDGE + HEIGHT_BORDER);
622+
623+ _colorBounds.maximum.x += _colorIncrement * SHARED_EDGE;
624+ _colorBounds.maximum.z += _colorIncrement * SHARED_EDGE;
609625 }
610626
611627 HeightfieldBuffer::~HeightfieldBuffer() {
@@ -807,17 +823,19 @@ BufferDataAttribute::BufferDataAttribute(const QString& name) : · 195 unmodified lines
807823 }
808824
809825 bool BufferDataAttribute::merge(void*& parent, void* children[], bool postRead) const {
810− BufferDataPointer firstChild = decodeInline<BufferDataPointer>(children[0]);
811− for (int i = 1; i < MERGE_COUNT; i++) {
812− if (firstChild != decodeInline<BufferDataPointer>(children[i])) {
813− *(BufferDataPointer*)&parent = _defaultValue;
826+ *(BufferDataPointer*)&parent = _defaultValue;
827+ for (int i = 0; i < MERGE_COUNT; i++) {
828+ if (decodeInline<BufferDataPointer>(children[i])) {
814829 return false;
815830 }
816831 }
817− *(BufferDataPointer*)&parent = firstChild;
818832 return true;
819833 }
820834
835+AttributeValue BufferDataAttribute::inherit(const AttributeValue& parentValue) const {
836+ return AttributeValue(parentValue.getAttribute());
837+}
838+
821839 void DefaultMetavoxelRendererImplementation::init() {
822840 if (!_pointProgram.isLinked()) {
823841 _pointProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert");
@@ -923,206 +941,279 @@ bool PointAugmentVisitor::postVisit(MetavoxelInfo& info) { · 99 unmodified lines
923941 return true;
924942 }
925943
926−class HeightfieldAugmentVisitor : public MetavoxelVisitor {
944+class HeightfieldFetchVisitor : public MetavoxelVisitor {
927945 public:
928−
929− HeightfieldAugmentVisitor(const MetavoxelLOD& lod);
930946
931− virtual int visit(MetavoxelInfo& info);
932−};
933−
934−HeightfieldAugmentVisitor::HeightfieldAugmentVisitor(const MetavoxelLOD& lod) :
935− MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<
936− AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector<AttributePointer>() <<
937− Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod) {
938−}
939−
940−class BorderFetchVisitor : public MetavoxelVisitor {
941−public:
947+ HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections);
942948
943− BorderFetchVisitor(const MetavoxelLOD& lod, HeightfieldBuffer* buffer);
949+ void init(HeightfieldBuffer* buffer) { _buffer = buffer; }
944950
945951 virtual int visit(MetavoxelInfo& info);
946952
947953 private:
948954
955+ const QVector<Box>& _intersections;
949956 HeightfieldBuffer* _buffer;
950− Box _expandedBounds;
951− int _heightSize;
952− float _heightExtension;
953− int _colorSize;
954− float _colorExtension;
955− Box _colorBounds;
956957 };
957958
958−BorderFetchVisitor::BorderFetchVisitor(const MetavoxelLOD& lod, HeightfieldBuffer* buffer) :
959+HeightfieldFetchVisitor::HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections) :
959960 MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<
960961 AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector<AttributePointer>(), lod),
961− _buffer(buffer),
962− _expandedBounds(_buffer->getTranslation(), _buffer->getTranslation() +
963− glm::vec3(_buffer->getScale(), _buffer->getScale(), _buffer->getScale())),
964− _heightSize(glm::sqrt(buffer->getHeight().size())),
965− _heightExtension(_buffer->getScale() / (_heightSize - HeightfieldBuffer::HEIGHT_EXTENSION)),
966− _colorSize(glm::sqrt(buffer->getColor().size() / HeightfieldData::COLOR_BYTES)),
967− _colorBounds(_expandedBounds) {
968−
969− _expandedBounds.minimum.x -= _heightExtension * HeightfieldBuffer::HEIGHT_BORDER;
970− _expandedBounds.minimum.z -= _heightExtension * HeightfieldBuffer::HEIGHT_BORDER;
971− _expandedBounds.maximum.x += _heightExtension * (HeightfieldBuffer::HEIGHT_BORDER + HeightfieldBuffer::SHARED_EDGE);
972− _expandedBounds.maximum.z += _heightExtension * (HeightfieldBuffer::HEIGHT_BORDER + HeightfieldBuffer::SHARED_EDGE);
973−
974− if (_colorSize > 0) {
975− _colorExtension = buffer->getScale() / (_colorSize - HeightfieldBuffer::SHARED_EDGE);
976− _colorBounds.maximum.x += _colorExtension * HeightfieldBuffer::SHARED_EDGE;
977− _colorBounds.maximum.z += _colorExtension * HeightfieldBuffer::SHARED_EDGE;
978− }
962+ _intersections(intersections) {
979963 }
980964
981−int BorderFetchVisitor::visit(MetavoxelInfo& info) {
965+int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) {
982966 Box bounds = info.getBounds();
983− if (!bounds.intersects(_expandedBounds)) {
967+ const Box& heightBounds = _buffer->getHeightBounds();
968+ if (!bounds.intersects(heightBounds)) {
984969 return STOP_RECURSION;
985970 }
986971 if (!info.isLeaf && info.size > _buffer->getScale()) {
987972 return DEFAULT_ORDER;
988973 }
989− if (_expandedBounds.contains(bounds)) {
990− return STOP_RECURSION; // this is the principal, which we've already filled in
991− }
992974 HeightfieldDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldDataPointer>();
993975 if (!height) {
994976 return STOP_RECURSION;
995977 }
996− Box intersection = bounds.getIntersection(_expandedBounds);
997− int destX = glm::round((intersection.minimum.x - _expandedBounds.minimum.x) / _heightExtension);
998− int destY = glm::round((intersection.minimum.z - _expandedBounds.minimum.z) / _heightExtension);
999− int destWidth = glm::round((intersection.maximum.x - intersection.minimum.x) / _heightExtension);
1000− int destHeight = glm::round((intersection.maximum.z - intersection.minimum.z) / _heightExtension);
1001− char* dest = _buffer->getHeight().data() + destY * _heightSize + destX;
1002−
1003− const QByteArray& srcHeight = height->getContents();
1004− int srcSize = glm::sqrt(srcHeight.size());
1005− float srcExtension = info.size / srcSize;
1006−
1007− if (info.size == _buffer->getScale() && srcSize == (_heightSize - HeightfieldBuffer::HEIGHT_EXTENSION)) {
1008− // easy case: same resolution
1009− int srcX = glm::round((intersection.minimum.x - info.minimum.x) / srcExtension);
1010− int srcY = glm::round((intersection.minimum.z - info.minimum.z) / srcExtension);
978+ foreach (const Box& intersection, _intersections) {
979+ Box overlap = intersection.getIntersection(bounds);
980+ if (overlap.isEmpty()) {
981+ continue;
982+ }
983+ float heightIncrement = _buffer->getHeightIncrement();
984+ int destX = (overlap.minimum.x - heightBounds.minimum.x) / heightIncrement;
985+ int destY = (overlap.minimum.z - heightBounds.minimum.z) / heightIncrement;
986+ int destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / heightIncrement);
987+ int destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / heightIncrement);
988+ int heightSize = _buffer->getHeightSize();
989+ char* dest = _buffer->getHeight().data() + destY * heightSize + destX;
1011990
1012− const char* src = srcHeight.constData() + srcY * srcSize + srcX;
1013− for (int y = 0; y < destHeight; y++, src += srcSize, dest += _heightSize) {
1014− memcpy(dest, src, destWidth);
991+ const QByteArray& srcHeight = height->getContents();
992+ int srcSize = glm::sqrt(srcHeight.size());
993+ float srcIncrement = info.size / srcSize;
994+
995+ if (info.size == _buffer->getScale() && srcSize == (heightSize - HeightfieldBuffer::HEIGHT_EXTENSION)) {
996+ // easy case: same resolution
997+ int srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
998+ int srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
999+
1000+ const char* src = srcHeight.constData() + srcY * srcSize + srcX;
1001+ for (int y = 0; y < destHeight; y++, src += srcSize, dest += heightSize) {
1002+ memcpy(dest, src, destWidth);
1003+ }
1004+ } else {
1005+ // more difficult: different resolutions
1006+ float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1007+ float srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1008+ float srcAdvance = heightIncrement / srcIncrement;
1009+ int shift = 0;
1010+ float size = _buffer->getScale();
1011+ while (size < info.size) {
1012+ shift++;
1013+ size *= 2.0f;
1014+ }
1015+ const int EIGHT_BIT_MAXIMUM = 255;
1016+ int subtract = (_buffer->getTranslation().y - info.minimum.y) * EIGHT_BIT_MAXIMUM / _buffer->getScale();
1017+ for (int y = 0; y < destHeight; y++, dest += heightSize, srcY += srcAdvance) {
1018+ const uchar* src = (const uchar*)srcHeight.constData() + (int)srcY * srcSize;
1019+ float lineSrcX = srcX;
1020+ for (char* lineDest = dest, *end = dest + destWidth; lineDest != end; lineDest++, lineSrcX += srcAdvance) {
1021+ *lineDest = qMin(qMax(0, (src[(int)lineSrcX] << shift) - subtract), EIGHT_BIT_MAXIMUM);
1022+ }
1023+ }
10151024 }
1016− } else {
1017− // more difficult: different resolutions
1018− float srcX = (intersection.minimum.x - info.minimum.x) / srcExtension;
1019− float srcY = (intersection.minimum.z - info.minimum.z) / srcExtension;
1020− float srcIncrement = _heightExtension / srcExtension;
1021− int shift = 0;
1022− float size = _buffer->getScale();
1023− while (size < info.size) {
1024− shift++;
1025− size *= 2.0f;
1025+
1026+ int colorSize = _buffer->getColorSize();
1027+ if (colorSize == 0) {
1028+ return STOP_RECURSION;
1029+ }
1030+ HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
1031+ if (!color) {
1032+ return STOP_RECURSION;
10261033 }
1027− const int EIGHT_BIT_MAXIMUM = 255;
1028− int subtract = (_buffer->getTranslation().y - info.minimum.y) * EIGHT_BIT_MAXIMUM / _buffer->getScale();
1029− for (int y = 0; y < destHeight; y++, dest += _heightSize, srcY += srcIncrement) {
1030− const uchar* src = (const uchar*)srcHeight.constData() + (int)srcY * srcSize;
1031− float lineSrcX = srcX;
1032− for (char* lineDest = dest, *end = dest + destWidth; lineDest != end; lineDest++, lineSrcX += srcIncrement) {
1033− *lineDest = qMin(qMax(0, (src[(int)lineSrcX] << shift) - subtract), EIGHT_BIT_MAXIMUM);
1034+ const Box& colorBounds = _buffer->getColorBounds();
1035+ overlap = colorBounds.getIntersection(overlap);
1036+ float colorIncrement = _buffer->getColorIncrement();
1037+ destX = (overlap.minimum.x - colorBounds.minimum.x) / colorIncrement;
1038+ destY = (overlap.minimum.z - colorBounds.minimum.z) / colorIncrement;
1039+ destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / colorIncrement);
1040+ destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / colorIncrement);
1041+ dest = _buffer->getColor().data() + (destY * colorSize + destX) * HeightfieldData::COLOR_BYTES;
1042+ int destStride = colorSize * HeightfieldData::COLOR_BYTES;
1043+ int destBytes = destWidth * HeightfieldData::COLOR_BYTES;
1044+
1045+ const QByteArray& srcColor = color->getContents();
1046+ srcSize = glm::sqrt(srcColor.size() / HeightfieldData::COLOR_BYTES);
1047+ int srcStride = srcSize * HeightfieldData::COLOR_BYTES;
1048+ srcIncrement = info.size / srcSize;
1049+
1050+ if (srcIncrement == colorIncrement) {
1051+ // easy case: same resolution
1052+ int srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1053+ int srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1054+
1055+ const char* src = srcColor.constData() + (srcY * srcSize + srcX) * HeightfieldData::COLOR_BYTES;
1056+ for (int y = 0; y < destHeight; y++, src += srcStride, dest += destStride) {
1057+ memcpy(dest, src, destBytes);
1058+ }
1059+ } else {
1060+ // more difficult: different resolutions
1061+ float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1062+ float srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1063+ float srcAdvance = colorIncrement / srcIncrement;
1064+ for (int y = 0; y < destHeight; y++, dest += destStride, srcY += srcAdvance) {
1065+ const char* src = srcColor.constData() + (int)srcY * srcStride;
1066+ float lineSrcX = srcX;
1067+ for (char* lineDest = dest, *end = dest + destBytes; lineDest != end; lineDest += HeightfieldData::COLOR_BYTES,
1068+ lineSrcX += srcAdvance) {
1069+ const char* lineSrc = src + (int)lineSrcX * HeightfieldData::COLOR_BYTES;
1070+ lineDest[0] = lineSrc[0];
1071+ lineDest[1] = lineSrc[1];
1072+ lineDest[2] = lineSrc[2];
1073+ }
10341074 }
10351075 }
10361076 }
1077+ return STOP_RECURSION;
1078+}
1079+
1080+class HeightfieldRegionVisitor : public MetavoxelVisitor {
1081+public:
10371082
1038− if (_colorSize == 0) {
1039− return STOP_RECURSION;
1040− }
1041− HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
1042− if (!color) {
1043− return STOP_RECURSION;
1044− }
1045− intersection = bounds.getIntersection(_colorBounds);
1046− destX = glm::round((intersection.minimum.x - _colorBounds.minimum.x) / _colorExtension);
1047− destY = glm::round((intersection.minimum.z - _colorBounds.minimum.z) / _colorExtension);
1048− destWidth = glm::round((intersection.maximum.x - intersection.minimum.x) / _colorExtension);
1049− destHeight = glm::round((intersection.maximum.z - intersection.minimum.z) / _colorExtension);
1050− dest = _buffer->getColor().data() + (destY * _colorSize + destX) * HeightfieldData::COLOR_BYTES;
1051− int destStride = _colorSize * HeightfieldData::COLOR_BYTES;
1052− int destBytes = destWidth * HeightfieldData::COLOR_BYTES;
1053−
1054− const QByteArray& srcColor = color->getContents();
1055− srcSize = glm::sqrt(srcColor.size() / HeightfieldData::COLOR_BYTES);
1056− int srcStride = srcSize * HeightfieldData::COLOR_BYTES;
1057− srcExtension = info.size / srcSize;
1083+ QVector<Box> regions;
1084+ Box regionBounds;
1085+
1086+ HeightfieldRegionVisitor(const MetavoxelLOD& lod);
10581087
1059− if (srcExtension == _colorExtension) {
1060− // easy case: same resolution
1061− int srcX = glm::round((intersection.minimum.x - info.minimum.x) / srcExtension);
1062− int srcY = glm::round((intersection.minimum.z - info.minimum.z) / srcExtension);
1088+ virtual int visit(MetavoxelInfo& info);
1089+
1090+private:
1091+
1092+ void addRegion(const Box& unextended, const Box& extended);
1093+
1094+ QVector<Box> _intersections;
1095+ HeightfieldFetchVisitor _fetchVisitor;
1096+};
1097+
1098+HeightfieldRegionVisitor::HeightfieldRegionVisitor(const MetavoxelLOD& lod) :
1099+ MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<
1100+ AttributeRegistry::getInstance()->getHeightfieldColorAttribute() <<
1101+ Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>() <<
1102+ Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod),
1103+ regionBounds(glm::vec3(FLT_MAX, FLT_MAX, FLT_MAX), glm::vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX)),
1104+ _fetchVisitor(lod, _intersections) {
1105+}
1106+
1107+int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) {
1108+ if (!info.isLeaf) {
1109+ return DEFAULT_ORDER;
1110+ }
1111+ HeightfieldBuffer* buffer = NULL;
1112+ HeightfieldDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldDataPointer>();
1113+ if (height) {
1114+ const QByteArray& heightContents = height->getContents();
1115+ int size = glm::sqrt(heightContents.size());
1116+ int extendedSize = size + HeightfieldBuffer::HEIGHT_EXTENSION;
1117+ int heightContentsSize = extendedSize * extendedSize;
10631118
1064− const char* src = srcColor.constData() + (srcY * srcSize + srcX) * HeightfieldData::COLOR_BYTES;
1065− for (int y = 0; y < destHeight; y++, src += srcStride, dest += destStride) {
1066− memcpy(dest, src, destBytes);
1119+ HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
1120+ int colorContentsSize = 0;
1121+ if (color) {
1122+ const QByteArray& colorContents = color->getContents();
1123+ int colorSize = glm::sqrt(colorContents.size() / HeightfieldData::COLOR_BYTES);
1124+ int extendedColorSize = colorSize + HeightfieldBuffer::SHARED_EDGE;
1125+ colorContentsSize = extendedColorSize * extendedColorSize * HeightfieldData::COLOR_BYTES;
10671126 }
1068− } else {
1069− // more difficult: different resolutions
1070− float srcX = (intersection.minimum.x - info.minimum.x) / srcExtension;
1071− float srcY = (intersection.minimum.z - info.minimum.z) / srcExtension;
1072− float srcIncrement = _colorExtension / srcExtension;
1073− for (int y = 0; y < destHeight; y++, dest += destStride, srcY += srcIncrement) {
1074− const char* src = srcColor.constData() + (int)srcY * srcStride;
1075− float lineSrcX = srcX;
1076− for (char* lineDest = dest, *end = dest + destBytes; lineDest != end; lineDest += HeightfieldData::COLOR_BYTES,
1077− lineSrcX += srcIncrement) {
1078− const char* lineSrc = src + (int)lineSrcX * HeightfieldData::COLOR_BYTES;
1079− lineDest[0] = lineSrc[0];
1080− lineDest[1] = lineSrc[1];
1081− lineDest[2] = lineSrc[2];
1082− }
1127+
1128+ const HeightfieldBuffer* existingBuffer = static_cast<const HeightfieldBuffer*>(
1129+ info.inputValues.at(2).getInlineValue<BufferDataPointer>().data());
1130+ Box bounds = info.getBounds();
1131+ if (existingBuffer && existingBuffer->getHeight().size() == heightContentsSize &&
1132+ existingBuffer->getColor().size() == colorContentsSize) {
1133+ // we already have a buffer of the correct resolution
1134+ addRegion(bounds, existingBuffer->getHeightBounds());
1135+ return STOP_RECURSION;
10831136 }
1137+ // we must create a new buffer and update its borders
1138+ buffer = new HeightfieldBuffer(info.minimum, info.size, QByteArray(heightContentsSize, 0),
1139+ QByteArray(colorContentsSize, 0));
1140+ const Box& heightBounds = buffer->getHeightBounds();
1141+ addRegion(bounds, heightBounds);
1142+
1143+ _intersections.clear();
1144+ _intersections.append(Box(heightBounds.minimum,
1145+ glm::vec3(bounds.maximum.x, heightBounds.maximum.y, bounds.minimum.z)));
1146+ _intersections.append(Box(glm::vec3(bounds.maximum.x, heightBounds.minimum.y, heightBounds.minimum.z),
1147+ glm::vec3(heightBounds.maximum.x, heightBounds.maximum.y, bounds.maximum.z)));
1148+ _intersections.append(Box(glm::vec3(bounds.minimum.x, heightBounds.minimum.y, bounds.maximum.z),
1149+ heightBounds.maximum));
1150+ _intersections.append(Box(glm::vec3(heightBounds.minimum.x, heightBounds.minimum.y, bounds.minimum.z),
1151+ glm::vec3(bounds.minimum.x, heightBounds.maximum.y, heightBounds.maximum.z)));
1152+
1153+ _fetchVisitor.init(buffer);
1154+ _data->guide(_fetchVisitor);
10841155 }
1085−
1156+ info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
10861157 return STOP_RECURSION;
10871158 }
10881159
1089−int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) {
1090− if (info.isLeaf) {
1091− HeightfieldBuffer* buffer = NULL;
1092− HeightfieldDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldDataPointer>();
1093− if (height) {
1094− const QByteArray& heightContents = height->getContents();
1095− int size = glm::sqrt(heightContents.size());
1096− int extendedSize = size + HeightfieldBuffer::HEIGHT_EXTENSION;
1097− QByteArray extendedHeightContents(extendedSize * extendedSize, 0);
1098− char* dest = extendedHeightContents.data() + (extendedSize + 1) * HeightfieldBuffer::HEIGHT_BORDER;
1099− const char* src = heightContents.constData();
1100− for (int z = 0; z < size; z++, src += size, dest += extendedSize) {
1101− memcpy(dest, src, size);
1102− }
1103− QByteArray extendedColorContents;
1104− HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
1105− if (color) {
1106− const QByteArray& colorContents = color->getContents();
1107− int colorSize = glm::sqrt(colorContents.size() / HeightfieldData::COLOR_BYTES);
1108− int extendedColorSize = colorSize + HeightfieldBuffer::SHARED_EDGE;
1109− extendedColorContents = QByteArray(extendedColorSize * extendedColorSize * HeightfieldData::COLOR_BYTES, 0);
1110− char* dest = extendedColorContents.data();
1111− const char* src = colorContents.constData();
1112− int srcStride = colorSize * HeightfieldData::COLOR_BYTES;
1113− int destStride = extendedColorSize * HeightfieldData::COLOR_BYTES;
1114− for (int z = 0; z < colorSize; z++, src += srcStride, dest += destStride) {
1115− memcpy(dest, src, srcStride);
1116− }
1117− }
1118− buffer = new HeightfieldBuffer(info.minimum, info.size, extendedHeightContents, extendedColorContents);
1119− BorderFetchVisitor visitor(_lod, buffer);
1120− _data->guide(visitor);
1160+void HeightfieldRegionVisitor::addRegion(const Box& unextended, const Box& extended) {
1161+ regions.append(unextended);
1162+ regionBounds.add(extended);
1163+}
1164+
1165+class HeightfieldUpdateVisitor : public MetavoxelVisitor {
1166+public:
1167+
1168+ HeightfieldUpdateVisitor(const MetavoxelLOD& lod, const QVector<Box>& regions, const Box& regionBounds);
1169+
1170+ virtual int visit(MetavoxelInfo& info);
1171+
1172+private:
1173+
1174+ const QVector<Box>& _regions;
1175+ const Box& _regionBounds;
1176+ QVector<Box> _intersections;
1177+ HeightfieldFetchVisitor _fetchVisitor;
1178+};
1179+
1180+HeightfieldUpdateVisitor::HeightfieldUpdateVisitor(const MetavoxelLOD& lod, const QVector<Box>& regions,
1181+ const Box& regionBounds) :
1182+ MetavoxelVisitor(QVector<AttributePointer>() <<
1183+ Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>() <<
1184+ Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod),
1185+ _regions(regions),
1186+ _regionBounds(regionBounds),
1187+ _fetchVisitor(lod, _intersections) {
1188+}
1189+
1190+int HeightfieldUpdateVisitor::visit(MetavoxelInfo& info) {
1191+ if (!info.getBounds().intersects(_regionBounds)) {
1192+ return STOP_RECURSION;
1193+ }
1194+ if (!info.isLeaf) {
1195+ return DEFAULT_ORDER;
1196+ }
1197+ const HeightfieldBuffer* buffer = static_cast<const HeightfieldBuffer*>(
1198+ info.inputValues.at(0).getInlineValue<BufferDataPointer>().data());
1199+ if (!buffer) {
1200+ return STOP_RECURSION;
1201+ }
1202+ _intersections.clear();
1203+ foreach (const Box& region, _regions) {
1204+ if (region.intersects(buffer->getHeightBounds())) {
1205+ _intersections.append(region.getIntersection(buffer->getHeightBounds()));
11211206 }
1122− info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
1207+ }
1208+ if (_intersections.isEmpty()) {
11231209 return STOP_RECURSION;
11241210 }
1125− return DEFAULT_ORDER;
1211+ HeightfieldBuffer* newBuffer = new HeightfieldBuffer(info.minimum, info.size,
1212+ buffer->getHeight(), buffer->getColor());
1213+ _fetchVisitor.init(newBuffer);
1214+ _data->guide(_fetchVisitor);
1215+ info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(newBuffer)));
1216+ return STOP_RECURSION;
11261217 }
11271218
11281219 void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous,
@@ -1149,8 +1240,12 @@ void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const · 20 unmodified lines
11491240 PointAugmentVisitor pointAugmentVisitor(lod);
11501241 data.guideToDifferent(expandedPrevious, pointAugmentVisitor);
11511242
1152− HeightfieldAugmentVisitor heightfieldAugmentVisitor(lod);
1153− data.guideToDifferent(expandedPrevious, heightfieldAugmentVisitor);
1243+ HeightfieldRegionVisitor heightfieldRegionVisitor(lod);
1244+ data.guideToDifferent(expandedPrevious, heightfieldRegionVisitor);
1245+
1246+ HeightfieldUpdateVisitor heightfieldUpdateVisitor(lod, heightfieldRegionVisitor.regions,
1247+ heightfieldRegionVisitor.regionBounds);
1248+ data.guide(heightfieldUpdateVisitor);
11541249 }
11551250
11561251 class SpannerSimulateVisitor : public SpannerVisitor {
@@ -1222,7 +1317,7 @@ bool SpannerRenderVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, · 65 unmodified lines
12221317 class BufferRenderVisitor : public MetavoxelVisitor {
12231318 public:
12241319
1225− BufferRenderVisitor(const AttributePointer& attribute, const MetavoxelLOD& lod);
1320+ BufferRenderVisitor(const AttributePointer& attribute);
12261321
12271322 virtual int visit(MetavoxelInfo& info);
12281323
@@ -1232,8 +1327,8 @@ private: · 3 unmodified lines
12321327 int _containmentDepth;
12331328 };
12341329
1235−BufferRenderVisitor::BufferRenderVisitor(const AttributePointer& attribute, const MetavoxelLOD& lod) :
1236− MetavoxelVisitor(QVector<AttributePointer>() << attribute, QVector<AttributePointer>(), lod),
1330+BufferRenderVisitor::BufferRenderVisitor(const AttributePointer& attribute) :
1331+ MetavoxelVisitor(QVector<AttributePointer>() << attribute),
12371332 _order(encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())),
12381333 _containmentDepth(INT_MAX) {
12391334 }
@@ -1247,11 +1342,14 @@ int BufferRenderVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
12471342 }
12481343 _containmentDepth = (intersection == Frustum::CONTAINS_INTERSECTION) ? _depth : INT_MAX;
12491344 }
1345+ if (!info.isLeaf) {
1346+ return _order;
1347+ }
12501348 BufferDataPointer buffer = info.inputValues.at(0).getInlineValue<BufferDataPointer>();
12511349 if (buffer) {
12521350 buffer->render();
12531351 }
1254− return info.isLeaf ? STOP_RECURSION : _order;
1352+ return STOP_RECURSION;
12551353 }
12561354
12571355 void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod) {
@@ -1280,7 +1378,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox · 22 unmodified lines
12801378
12811379 glDisable(GL_BLEND);
12821380
1283− BufferRenderVisitor pointRenderVisitor(Application::getInstance()->getMetavoxels()->getPointBufferAttribute(), lod);
1381+ BufferRenderVisitor pointRenderVisitor(Application::getInstance()->getMetavoxels()->getPointBufferAttribute());
12841382 data.guide(pointRenderVisitor);
12851383
12861384 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
@@ -1300,8 +1398,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox · 13 unmodified lines
13001398
13011399 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
13021400
1303− BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(),
1304− lod);
1401+ BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute());
13051402 data.guide(heightfieldRenderVisitor);
13061403
13071404 _heightfieldProgram.release();