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
37 _pointBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(new BufferDataAttribute("pointBuffer"));37 _pointBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(new BufferDataAttribute("pointBuffer"));
38 _heightfieldBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(38 _heightfieldBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(
39 new BufferDataAttribute("heightfieldBuffer"));39 new BufferDataAttribute("heightfieldBuffer"));
40
41 _heightfieldBufferAttribute->setLODThresholdMultiplier(
42 AttributeRegistry::getInstance()->getHeightfieldAttribute()->getLODThresholdMultiplier());
40}43}
41 44
42MetavoxelLOD MetavoxelSystem::getLOD() {45MetavoxelLOD MetavoxelSystem::getLOD() {
@@ -382,7 +385,7 @@ float MetavoxelSystem::getHeightfieldHeight(const glm::vec3& location) { · 339 unmodified lines
382class HeightfieldCursorRenderVisitor : public MetavoxelVisitor {385class HeightfieldCursorRenderVisitor : public MetavoxelVisitor {
383public:386public:
384 387
385 HeightfieldCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds);388 HeightfieldCursorRenderVisitor(const Box& bounds);
386 389
387 virtual int visit(MetavoxelInfo& info);390 virtual int visit(MetavoxelInfo& info);
388 391
@@ -391,9 +394,9 @@ private: · 2 unmodified lines
391 Box _bounds;394 Box _bounds;
392};395};
393 396
394HeightfieldCursorRenderVisitor::HeightfieldCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds) :397HeightfieldCursorRenderVisitor::HeightfieldCursorRenderVisitor(const Box& bounds) :
395 MetavoxelVisitor(QVector<AttributePointer>() <<398 MetavoxelVisitor(QVector<AttributePointer>() <<
396 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>(), lod),399 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute()),
397 _bounds(bounds) {400 _bounds(bounds) {
398}401}
399 402
@@ -433,7 +436,7 @@ void MetavoxelSystem::renderHeightfieldCursor(const glm::vec3& position, float r · 33 unmodified lines
433 glActiveTexture(GL_TEXTURE0);436 glActiveTexture(GL_TEXTURE0);
434 437
435 glm::vec3 extents(radius, radius, radius);438 glm::vec3 extents(radius, radius, radius);
436 HeightfieldCursorRenderVisitor visitor(getLOD(), Box(position - extents, position + extents));439 HeightfieldCursorRenderVisitor visitor(Box(position - extents, position + extents));
437 guideToAugmented(visitor);440 guideToAugmented(visitor);
438 441
439 DefaultMetavoxelRendererImplementation::getHeightfieldCursorProgram().release();442 DefaultMetavoxelRendererImplementation::getHeightfieldCursorProgram().release();
@@ -601,11 +604,24 @@ HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale, · 161 unmodified lines
601 const QByteArray& height, const QByteArray& color) :604 const QByteArray& height, const QByteArray& color) :
602 _translation(translation),605 _translation(translation),
603 _scale(scale),606 _scale(scale),
607 _heightBounds(translation, translation + glm::vec3(scale, scale, scale)),
608 _colorBounds(_heightBounds),
604 _height(height),609 _height(height),
605 _color(color),610 _color(color),
606 _heightTextureID(0),611 _heightTextureID(0),
607 _colorTextureID(0),612 _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;
609}625}
610 626
611HeightfieldBuffer::~HeightfieldBuffer() {627HeightfieldBuffer::~HeightfieldBuffer() {
@@ -807,17 +823,19 @@ BufferDataAttribute::BufferDataAttribute(const QString& name) : · 195 unmodified lines
807}823}
808 824
809bool BufferDataAttribute::merge(void*& parent, void* children[], bool postRead) const {825bool BufferDataAttribute::merge(void*& parent, void* children[], bool postRead) const {
810 BufferDataPointer firstChild = decodeInline<BufferDataPointer>(children[0]);826 *(BufferDataPointer*)&parent = _defaultValue;
811 for (int i = 1; i < MERGE_COUNT; i++) {827 for (int i = 0; i < MERGE_COUNT; i++) {
812 if (firstChild != decodeInline<BufferDataPointer>(children[i])) {828 if (decodeInline<BufferDataPointer>(children[i])) {
813 *(BufferDataPointer*)&parent = _defaultValue;
814 return false;829 return false;
815 }830 }
816 }831 }
817 *(BufferDataPointer*)&parent = firstChild;
818 return true;832 return true;
819}833}
820 834
835AttributeValue BufferDataAttribute::inherit(const AttributeValue& parentValue) const {
836 return AttributeValue(parentValue.getAttribute());
837}
838
821void DefaultMetavoxelRendererImplementation::init() {839void DefaultMetavoxelRendererImplementation::init() {
822 if (!_pointProgram.isLinked()) {840 if (!_pointProgram.isLinked()) {
823 _pointProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert");841 _pointProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert");
@@ -923,206 +941,279 @@ bool PointAugmentVisitor::postVisit(MetavoxelInfo& info) { · 99 unmodified lines
923 return true;941 return true;
924}942}
925 943
926class HeightfieldAugmentVisitor : public MetavoxelVisitor {944class HeightfieldFetchVisitor : public MetavoxelVisitor {
927public:945public:
928
929 HeightfieldAugmentVisitor(const MetavoxelLOD& lod);
930 946
931 virtual int visit(MetavoxelInfo& info);947 HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections);
932};
933
934HeightfieldAugmentVisitor::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
940class BorderFetchVisitor : public MetavoxelVisitor {
941public:
942 948
943 BorderFetchVisitor(const MetavoxelLOD& lod, HeightfieldBuffer* buffer);949 void init(HeightfieldBuffer* buffer) { _buffer = buffer; }
944 950
945 virtual int visit(MetavoxelInfo& info);951 virtual int visit(MetavoxelInfo& info);
946 952
947private:953private:
948 954
955 const QVector<Box>& _intersections;
949 HeightfieldBuffer* _buffer;956 HeightfieldBuffer* _buffer;
950 Box _expandedBounds;
951 int _heightSize;
952 float _heightExtension;
953 int _colorSize;
954 float _colorExtension;
955 Box _colorBounds;
956};957};
957 958
958BorderFetchVisitor::BorderFetchVisitor(const MetavoxelLOD& lod, HeightfieldBuffer* buffer) :959HeightfieldFetchVisitor::HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections) :
959 MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<960 MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<
960 AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector<AttributePointer>(), lod),961 AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector<AttributePointer>(), lod),
961 _buffer(buffer),962 _intersections(intersections) {
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 }
979}963}
980 964
981int BorderFetchVisitor::visit(MetavoxelInfo& info) {965int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) {
982 Box bounds = info.getBounds();966 Box bounds = info.getBounds();
983 if (!bounds.intersects(_expandedBounds)) {967 const Box& heightBounds = _buffer->getHeightBounds();
968 if (!bounds.intersects(heightBounds)) {
984 return STOP_RECURSION;969 return STOP_RECURSION;
985 }970 }
986 if (!info.isLeaf && info.size > _buffer->getScale()) {971 if (!info.isLeaf && info.size > _buffer->getScale()) {
987 return DEFAULT_ORDER;972 return DEFAULT_ORDER;
988 }973 }
989 if (_expandedBounds.contains(bounds)) {
990 return STOP_RECURSION; // this is the principal, which we've already filled in
991 }
992 HeightfieldDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldDataPointer>();974 HeightfieldDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldDataPointer>();
993 if (!height) {975 if (!height) {
994 return STOP_RECURSION;976 return STOP_RECURSION;
995 }977 }
996 Box intersection = bounds.getIntersection(_expandedBounds);978 foreach (const Box& intersection, _intersections) {
997 int destX = glm::round((intersection.minimum.x - _expandedBounds.minimum.x) / _heightExtension);979 Box overlap = intersection.getIntersection(bounds);
998 int destY = glm::round((intersection.minimum.z - _expandedBounds.minimum.z) / _heightExtension);980 if (overlap.isEmpty()) {
999 int destWidth = glm::round((intersection.maximum.x - intersection.minimum.x) / _heightExtension);981 continue;
1000 int destHeight = glm::round((intersection.maximum.z - intersection.minimum.z) / _heightExtension);982 }
1001 char* dest = _buffer->getHeight().data() + destY * _heightSize + destX;983 float heightIncrement = _buffer->getHeightIncrement();
1002 984 int destX = (overlap.minimum.x - heightBounds.minimum.x) / heightIncrement;
1003 const QByteArray& srcHeight = height->getContents();985 int destY = (overlap.minimum.z - heightBounds.minimum.z) / heightIncrement;
1004 int srcSize = glm::sqrt(srcHeight.size());986 int destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / heightIncrement);
1005 float srcExtension = info.size / srcSize;987 int destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / heightIncrement);
1006 988 int heightSize = _buffer->getHeightSize();
1007 if (info.size == _buffer->getScale() && srcSize == (_heightSize - HeightfieldBuffer::HEIGHT_EXTENSION)) {989 char* dest = _buffer->getHeight().data() + destY * heightSize + destX;
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);
1011 990
1012 const char* src = srcHeight.constData() + srcY * srcSize + srcX;991 const QByteArray& srcHeight = height->getContents();
1013 for (int y = 0; y < destHeight; y++, src += srcSize, dest += _heightSize) {992 int srcSize = glm::sqrt(srcHeight.size());
1014 memcpy(dest, src, destWidth);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 }
1015 }1024 }
1016 } else {1025
1017 // more difficult: different resolutions1026 int colorSize = _buffer->getColorSize();
1018 float srcX = (intersection.minimum.x - info.minimum.x) / srcExtension;1027 if (colorSize == 0) {
1019 float srcY = (intersection.minimum.z - info.minimum.z) / srcExtension;1028 return STOP_RECURSION;
1020 float srcIncrement = _heightExtension / srcExtension;1029 }
1021 int shift = 0;1030 HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
1022 float size = _buffer->getScale();1031 if (!color) {
1023 while (size < info.size) {1032 return STOP_RECURSION;
1024 shift++;
1025 size *= 2.0f;
1026 }1033 }
1027 const int EIGHT_BIT_MAXIMUM = 255;1034 const Box& colorBounds = _buffer->getColorBounds();
1028 int subtract = (_buffer->getTranslation().y - info.minimum.y) * EIGHT_BIT_MAXIMUM / _buffer->getScale();1035 overlap = colorBounds.getIntersection(overlap);
1029 for (int y = 0; y < destHeight; y++, dest += _heightSize, srcY += srcIncrement) {1036 float colorIncrement = _buffer->getColorIncrement();
1030 const uchar* src = (const uchar*)srcHeight.constData() + (int)srcY * srcSize;1037 destX = (overlap.minimum.x - colorBounds.minimum.x) / colorIncrement;
1031 float lineSrcX = srcX;1038 destY = (overlap.minimum.z - colorBounds.minimum.z) / colorIncrement;
1032 for (char* lineDest = dest, *end = dest + destWidth; lineDest != end; lineDest++, lineSrcX += srcIncrement) {1039 destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / colorIncrement);
1033 *lineDest = qMin(qMax(0, (src[(int)lineSrcX] << shift) - subtract), EIGHT_BIT_MAXIMUM);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 }
1034 }1074 }
1035 }1075 }
1036 }1076 }
1077 return STOP_RECURSION;
1078}
1079
1080class HeightfieldRegionVisitor : public MetavoxelVisitor {
1081public:
1037 1082
1038 if (_colorSize == 0) {1083 QVector<Box> regions;
1039 return STOP_RECURSION;1084 Box regionBounds;
1040 }1085
1041 HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();1086 HeightfieldRegionVisitor(const MetavoxelLOD& lod);
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;
1058 1087
1059 if (srcExtension == _colorExtension) {1088 virtual int visit(MetavoxelInfo& info);
1060 // easy case: same resolution1089
1061 int srcX = glm::round((intersection.minimum.x - info.minimum.x) / srcExtension);1090private:
1062 int srcY = glm::round((intersection.minimum.z - info.minimum.z) / srcExtension);1091
1092 void addRegion(const Box& unextended, const Box& extended);
1093
1094 QVector<Box> _intersections;
1095 HeightfieldFetchVisitor _fetchVisitor;
1096};
1097
1098HeightfieldRegionVisitor::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
1107int 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;
1063 1118
1064 const char* src = srcColor.constData() + (srcY * srcSize + srcX) * HeightfieldData::COLOR_BYTES; 1119 HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
1065 for (int y = 0; y < destHeight; y++, src += srcStride, dest += destStride) {1120 int colorContentsSize = 0;
1066 memcpy(dest, src, destBytes);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;
1067 }1126 }
1068 } else {1127
1069 // more difficult: different resolutions1128 const HeightfieldBuffer* existingBuffer = static_cast<const HeightfieldBuffer*>(
1070 float srcX = (intersection.minimum.x - info.minimum.x) / srcExtension;1129 info.inputValues.at(2).getInlineValue<BufferDataPointer>().data());
1071 float srcY = (intersection.minimum.z - info.minimum.z) / srcExtension;1130 Box bounds = info.getBounds();
1072 float srcIncrement = _colorExtension / srcExtension;1131 if (existingBuffer && existingBuffer->getHeight().size() == heightContentsSize &&
1073 for (int y = 0; y < destHeight; y++, dest += destStride, srcY += srcIncrement) {1132 existingBuffer->getColor().size() == colorContentsSize) {
1074 const char* src = srcColor.constData() + (int)srcY * srcStride;1133 // we already have a buffer of the correct resolution
1075 float lineSrcX = srcX;1134 addRegion(bounds, existingBuffer->getHeightBounds());
1076 for (char* lineDest = dest, *end = dest + destBytes; lineDest != end; lineDest += HeightfieldData::COLOR_BYTES,1135 return STOP_RECURSION;
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 }
1083 }1136 }
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);
1084 }1155 }
1085 1156 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
1086 return STOP_RECURSION;1157 return STOP_RECURSION;
1087}1158}
1088 1159
1089int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) {1160void HeightfieldRegionVisitor::addRegion(const Box& unextended, const Box& extended) {
1090 if (info.isLeaf) {1161 regions.append(unextended);
1091 HeightfieldBuffer* buffer = NULL;1162 regionBounds.add(extended);
1092 HeightfieldDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldDataPointer>();1163}
1093 if (height) {1164
1094 const QByteArray& heightContents = height->getContents();1165class HeightfieldUpdateVisitor : public MetavoxelVisitor {
1095 int size = glm::sqrt(heightContents.size());1166public:
1096 int extendedSize = size + HeightfieldBuffer::HEIGHT_EXTENSION;1167
1097 QByteArray extendedHeightContents(extendedSize * extendedSize, 0);1168 HeightfieldUpdateVisitor(const MetavoxelLOD& lod, const QVector<Box>& regions, const Box& regionBounds);
1098 char* dest = extendedHeightContents.data() + (extendedSize + 1) * HeightfieldBuffer::HEIGHT_BORDER;1169
1099 const char* src = heightContents.constData();1170 virtual int visit(MetavoxelInfo& info);
1100 for (int z = 0; z < size; z++, src += size, dest += extendedSize) {1171
1101 memcpy(dest, src, size);1172private:
1102 }1173
1103 QByteArray extendedColorContents;1174 const QVector<Box>& _regions;
1104 HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();1175 const Box& _regionBounds;
1105 if (color) {1176 QVector<Box> _intersections;
1106 const QByteArray& colorContents = color->getContents();1177 HeightfieldFetchVisitor _fetchVisitor;
1107 int colorSize = glm::sqrt(colorContents.size() / HeightfieldData::COLOR_BYTES);1178};
1108 int extendedColorSize = colorSize + HeightfieldBuffer::SHARED_EDGE;1179
1109 extendedColorContents = QByteArray(extendedColorSize * extendedColorSize * HeightfieldData::COLOR_BYTES, 0);1180HeightfieldUpdateVisitor::HeightfieldUpdateVisitor(const MetavoxelLOD& lod, const QVector<Box>& regions,
1110 char* dest = extendedColorContents.data();1181 const Box& regionBounds) :
1111 const char* src = colorContents.constData();1182 MetavoxelVisitor(QVector<AttributePointer>() <<
1112 int srcStride = colorSize * HeightfieldData::COLOR_BYTES;1183 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>() <<
1113 int destStride = extendedColorSize * HeightfieldData::COLOR_BYTES;1184 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod),
1114 for (int z = 0; z < colorSize; z++, src += srcStride, dest += destStride) {1185 _regions(regions),
1115 memcpy(dest, src, srcStride);1186 _regionBounds(regionBounds),
1116 }1187 _fetchVisitor(lod, _intersections) {
1117 }1188}
1118 buffer = new HeightfieldBuffer(info.minimum, info.size, extendedHeightContents, extendedColorContents);1189
1119 BorderFetchVisitor visitor(_lod, buffer);1190int HeightfieldUpdateVisitor::visit(MetavoxelInfo& info) {
1120 _data->guide(visitor);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()));
1121 }1206 }
1122 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));1207 }
1208 if (_intersections.isEmpty()) {
1123 return STOP_RECURSION;1209 return STOP_RECURSION;
1124 }1210 }
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;
1126}1217}
1127 1218
1128void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous,1219void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous,
@@ -1149,8 +1240,12 @@ void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const · 20 unmodified lines
1149 PointAugmentVisitor pointAugmentVisitor(lod);1240 PointAugmentVisitor pointAugmentVisitor(lod);
1150 data.guideToDifferent(expandedPrevious, pointAugmentVisitor);1241 data.guideToDifferent(expandedPrevious, pointAugmentVisitor);
1151 1242
1152 HeightfieldAugmentVisitor heightfieldAugmentVisitor(lod);1243 HeightfieldRegionVisitor heightfieldRegionVisitor(lod);
1153 data.guideToDifferent(expandedPrevious, heightfieldAugmentVisitor);1244 data.guideToDifferent(expandedPrevious, heightfieldRegionVisitor);
1245
1246 HeightfieldUpdateVisitor heightfieldUpdateVisitor(lod, heightfieldRegionVisitor.regions,
1247 heightfieldRegionVisitor.regionBounds);
1248 data.guide(heightfieldUpdateVisitor);
1154}1249}
1155 1250
1156class SpannerSimulateVisitor : public SpannerVisitor {1251class SpannerSimulateVisitor : public SpannerVisitor {
@@ -1222,7 +1317,7 @@ bool SpannerRenderVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, · 65 unmodified lines
1222class BufferRenderVisitor : public MetavoxelVisitor {1317class BufferRenderVisitor : public MetavoxelVisitor {
1223public:1318public:
1224 1319
1225 BufferRenderVisitor(const AttributePointer& attribute, const MetavoxelLOD& lod);1320 BufferRenderVisitor(const AttributePointer& attribute);
1226 1321
1227 virtual int visit(MetavoxelInfo& info);1322 virtual int visit(MetavoxelInfo& info);
1228 1323
@@ -1232,8 +1327,8 @@ private: · 3 unmodified lines
1232 int _containmentDepth;1327 int _containmentDepth;
1233};1328};
1234 1329
1235BufferRenderVisitor::BufferRenderVisitor(const AttributePointer& attribute, const MetavoxelLOD& lod) :1330BufferRenderVisitor::BufferRenderVisitor(const AttributePointer& attribute) :
1236 MetavoxelVisitor(QVector<AttributePointer>() << attribute, QVector<AttributePointer>(), lod),1331 MetavoxelVisitor(QVector<AttributePointer>() << attribute),
1237 _order(encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())),1332 _order(encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())),
1238 _containmentDepth(INT_MAX) {1333 _containmentDepth(INT_MAX) {
1239}1334}
@@ -1247,11 +1342,14 @@ int BufferRenderVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
1247 }1342 }
1248 _containmentDepth = (intersection == Frustum::CONTAINS_INTERSECTION) ? _depth : INT_MAX;1343 _containmentDepth = (intersection == Frustum::CONTAINS_INTERSECTION) ? _depth : INT_MAX;
1249 }1344 }
1345 if (!info.isLeaf) {
1346 return _order;
1347 }
1250 BufferDataPointer buffer = info.inputValues.at(0).getInlineValue<BufferDataPointer>();1348 BufferDataPointer buffer = info.inputValues.at(0).getInlineValue<BufferDataPointer>();
1251 if (buffer) {1349 if (buffer) {
1252 buffer->render();1350 buffer->render();
1253 }1351 }
1254 return info.isLeaf ? STOP_RECURSION : _order;1352 return STOP_RECURSION;
1255}1353}
1256 1354
1257void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod) {1355void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod) {
@@ -1280,7 +1378,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox · 22 unmodified lines
1280 1378
1281 glDisable(GL_BLEND);1379 glDisable(GL_BLEND);
1282 1380
1283 BufferRenderVisitor pointRenderVisitor(Application::getInstance()->getMetavoxels()->getPointBufferAttribute(), lod);1381 BufferRenderVisitor pointRenderVisitor(Application::getInstance()->getMetavoxels()->getPointBufferAttribute());
1284 data.guide(pointRenderVisitor);1382 data.guide(pointRenderVisitor);
1285 1383
1286 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);1384 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
@@ -1300,8 +1398,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox · 13 unmodified lines
1300 1398
1301 glEnableClientState(GL_TEXTURE_COORD_ARRAY);1399 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1302 1400
1303 BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(),1401 BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute());
1304 lod);
1305 data.guide(heightfieldRenderVisitor);1402 data.guide(heightfieldRenderVisitor);
1306 1403
1307 _heightfieldProgram.release();1404 _heightfieldProgram.release();