From 631419d23c62739f7927593fe7e67b32e1de0723 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 22 Oct 2014 18:22:21 -0700 Subject: [PATCH] Tweaks to heightfield conversion. --- .../shaders/metavoxel_heightfield_base.vert | 13 +++--- .../metavoxels/src/MetavoxelMessages.cpp | 43 ++++++++++++------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/interface/resources/shaders/metavoxel_heightfield_base.vert b/interface/resources/shaders/metavoxel_heightfield_base.vert index f097426e13..5486f5fa67 100644 --- a/interface/resources/shaders/metavoxel_heightfield_base.vert +++ b/interface/resources/shaders/metavoxel_heightfield_base.vert @@ -26,11 +26,14 @@ varying vec4 normal; void main(void) { // transform and store the normal for interpolation vec2 heightCoord = gl_MultiTexCoord0.st; - float deltaX = texture2D(heightMap, heightCoord - vec2(heightScale, 0.0)).r - - texture2D(heightMap, heightCoord + vec2(heightScale, 0.0)).r; - float deltaZ = texture2D(heightMap, heightCoord - vec2(0.0, heightScale)).r - - texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r; - normal = normalize(gl_ModelViewMatrix * vec4(deltaX, heightScale, deltaZ, 0.0)); + vec4 neighborHeights = vec4(texture2D(heightMap, heightCoord - vec2(heightScale, 0.0)).r, + texture2D(heightMap, heightCoord + vec2(heightScale, 0.0)).r, + texture2D(heightMap, heightCoord - vec2(0.0, heightScale)).r, + texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r); + vec4 neighborsZero = step(1.0 / 255.0, neighborHeights); + normal = normalize(gl_ModelViewMatrix * vec4( + (neighborHeights.x - neighborHeights.y) * neighborsZero.x * neighborsZero.y, heightScale, + (neighborHeights.z - neighborHeights.w) * neighborsZero.z * neighborsZero.w, 0.0)); // add the height to the position float height = texture2D(heightMap, heightCoord).r; diff --git a/libraries/metavoxels/src/MetavoxelMessages.cpp b/libraries/metavoxels/src/MetavoxelMessages.cpp index d9c60f3f12..2d1e03fc69 100644 --- a/libraries/metavoxels/src/MetavoxelMessages.cpp +++ b/libraries/metavoxels/src/MetavoxelMessages.cpp @@ -1062,6 +1062,13 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) { HeightfieldHeightDataPointer newHeightPointer(new HeightfieldHeightData(contents)); info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(newHeightPointer)); + // allow a border for what we clear in terms of color/material + innerBounds.minimum.x += increment; + innerBounds.minimum.z += increment; + innerBounds.maximum.x -= increment; + innerBounds.maximum.z -= increment; + innerOverlap = bounds.getIntersection(innerBounds); + HeightfieldColorDataPointer colorPointer = info.inputValues.at(1).getInlineValue(); if (colorPointer) { contents = colorPointer->getContents(); @@ -1087,14 +1094,16 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) { destY = (innerOverlap.minimum.z - info.minimum.z) * heightScale; destWidth = glm::ceil((innerOverlap.maximum.x - innerOverlap.minimum.x) * heightScale); destHeight = glm::ceil((innerOverlap.maximum.z - innerOverlap.minimum.z) * heightScale); - dest = contents.data() + (destY * size + destX) * DataBlock::COLOR_BYTES; - - for (int y = 0; y < destHeight; y++, dest += size * DataBlock::COLOR_BYTES) { - memset(dest, 0, destWidth * DataBlock::COLOR_BYTES); + if (destWidth > 0 && destHeight > 0) { + dest = contents.data() + (destY * size + destX) * DataBlock::COLOR_BYTES; + + for (int y = 0; y < destHeight; y++, dest += size * DataBlock::COLOR_BYTES) { + memset(dest, 0, destWidth * DataBlock::COLOR_BYTES); + } + + HeightfieldColorDataPointer newColorPointer(new HeightfieldColorData(contents)); + info.outputValues[1] = AttributeValue(_outputs.at(1), encodeInline(newColorPointer)); } - - HeightfieldColorDataPointer newColorPointer(new HeightfieldColorData(contents)); - info.outputValues[1] = AttributeValue(_outputs.at(1), encodeInline(newColorPointer)); } HeightfieldMaterialDataPointer materialPointer = info.inputValues.at(2).getInlineValue(); @@ -1134,16 +1143,18 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) { destY = (innerOverlap.minimum.z - info.minimum.z) * heightScale; destWidth = glm::ceil((innerOverlap.maximum.x - innerOverlap.minimum.x) * heightScale); destHeight = glm::ceil((innerOverlap.maximum.z - innerOverlap.minimum.z) * heightScale); - dest = (uchar*)contents.data() + destY * size + destX; - - for (int y = 0; y < destHeight; y++, dest += size) { - memset(dest, 0, destWidth); + if (destWidth > 0 && destHeight > 0) { + dest = (uchar*)contents.data() + destY * size + destX; + + for (int y = 0; y < destHeight; y++, dest += size) { + memset(dest, 0, destWidth); + } + + clearUnusedMaterials(materials, contents); + HeightfieldMaterialDataPointer newMaterialPointer(new HeightfieldMaterialData(contents, materials)); + info.outputValues[2] = AttributeValue(_outputs.at(2), + encodeInline(newMaterialPointer)); } - - clearUnusedMaterials(materials, contents); - HeightfieldMaterialDataPointer newMaterialPointer(new HeightfieldMaterialData(contents, materials)); - info.outputValues[2] = AttributeValue(_outputs.at(2), - encodeInline(newMaterialPointer)); } return STOP_RECURSION;