diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index a8a7ace06f..bbd1fe4c07 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -75,7 +75,7 @@ InboundAudioStream::Settings AudioMixer::_streamSettings; bool AudioMixer::_printStreamStats = false; -bool AudioMixer::_enableFilter = false; +bool AudioMixer::_enableFilter = true; AudioMixer::AudioMixer(const QByteArray& packet) : ThreadedAssignment(packet), @@ -710,7 +710,9 @@ void AudioMixer::run() { } const QString FILTER_KEY = "J-enable-filter"; - _enableFilter = audioGroupObject[FILTER_KEY].toBool(); + if (audioGroupObject[FILTER_KEY].isBool()) { + _enableFilter = audioGroupObject[FILTER_KEY].toBool(); + } if (_enableFilter) { qDebug() << "Filter enabled"; } diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index a2f9deccf6..1726c3f60a 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -42,7 +42,7 @@ "type": "checkbox", "label": "Enable Positional Filter", "help": "If enabled, positional audio stream uses lowpass filter", - "default": false + "default": true }, { "name": "unattenuated-zone", diff --git a/interface/resources/shaders/metavoxel_voxel_splat.frag b/interface/resources/shaders/metavoxel_voxel_splat.frag index 66ce2721ac..c6c9860c1a 100644 --- a/interface/resources/shaders/metavoxel_voxel_splat.frag +++ b/interface/resources/shaders/metavoxel_voxel_splat.frag @@ -17,13 +17,20 @@ const int SPLAT_COUNT = 4; // the splat textures uniform sampler2D diffuseMaps[SPLAT_COUNT]; +// the model space normal +varying vec3 normal; + // alpha values for the four splat textures varying vec4 alphaValues; void main(void) { + // determine the cube face to use for texture coordinate generation + vec3 absNormal = abs(normal); + vec2 parameters = step(absNormal.yy, absNormal.xz) * step(absNormal.zx, absNormal.xz); + // blend the splat textures - gl_FragColor = (texture2D(diffuseMaps[0], gl_TexCoord[0].st) * alphaValues.x + - texture2D(diffuseMaps[1], gl_TexCoord[1].st) * alphaValues.y + - texture2D(diffuseMaps[2], gl_TexCoord[2].st) * alphaValues.z + - texture2D(diffuseMaps[3], gl_TexCoord[3].st) * alphaValues.w); + gl_FragColor = (texture2D(diffuseMaps[0], mix(gl_TexCoord[0].xw, gl_TexCoord[0].zy, parameters)) * alphaValues.x + + texture2D(diffuseMaps[1], mix(gl_TexCoord[1].xw, gl_TexCoord[1].zy, parameters)) * alphaValues.y + + texture2D(diffuseMaps[2], mix(gl_TexCoord[2].xw, gl_TexCoord[2].zy, parameters)) * alphaValues.z + + texture2D(diffuseMaps[3], mix(gl_TexCoord[3].xw, gl_TexCoord[3].zy, parameters)) * alphaValues.w); } diff --git a/interface/resources/shaders/metavoxel_voxel_splat.vert b/interface/resources/shaders/metavoxel_voxel_splat.vert index 150a9e7d2e..31ddbef395 100644 --- a/interface/resources/shaders/metavoxel_voxel_splat.vert +++ b/interface/resources/shaders/metavoxel_voxel_splat.vert @@ -29,6 +29,9 @@ attribute vec4 materials; // the weights of each material attribute vec4 materialWeights; +// the model space normal +varying vec3 normal; + // alpha values for the four splat textures varying vec4 alphaValues; @@ -36,12 +39,19 @@ void main(void) { // use the fixed-function position gl_Position = ftransform(); + // pass along the normal + normal = gl_Normal; + // pass along the scaled/offset texture coordinates - vec4 textureSpacePosition = vec4(gl_Vertex.xz, 0.0, 1.0); - gl_TexCoord[0] = textureSpacePosition * vec4(splatTextureScalesS[0], splatTextureScalesT[0], 0.0, 1.0); - gl_TexCoord[1] = textureSpacePosition * vec4(splatTextureScalesS[1], splatTextureScalesT[1], 0.0, 1.0); - gl_TexCoord[2] = textureSpacePosition * vec4(splatTextureScalesS[2], splatTextureScalesT[2], 0.0, 1.0); - gl_TexCoord[3] = textureSpacePosition * vec4(splatTextureScalesS[3], splatTextureScalesT[3], 0.0, 1.0); + vec4 textureSpacePosition = gl_Vertex.xyyz; + gl_TexCoord[0] = textureSpacePosition * vec4(splatTextureScalesS[0], splatTextureScalesT[0], + splatTextureScalesS[0], splatTextureScalesT[0]); + gl_TexCoord[1] = textureSpacePosition * vec4(splatTextureScalesS[1], splatTextureScalesT[1], + splatTextureScalesS[1], splatTextureScalesT[1]); + gl_TexCoord[2] = textureSpacePosition * vec4(splatTextureScalesS[2], splatTextureScalesT[2], + splatTextureScalesS[2], splatTextureScalesT[2]); + gl_TexCoord[3] = textureSpacePosition * vec4(splatTextureScalesS[3], splatTextureScalesT[3], + splatTextureScalesS[3], splatTextureScalesT[3]); // compute the alpha values for each texture float value = materials[0]; diff --git a/libraries/metavoxels/src/MetavoxelMessages.cpp b/libraries/metavoxels/src/MetavoxelMessages.cpp index 79ac74a1f6..791604f63f 100644 --- a/libraries/metavoxels/src/MetavoxelMessages.cpp +++ b/libraries/metavoxels/src/MetavoxelMessages.cpp @@ -667,8 +667,9 @@ int VoxelMaterialBoxEditVisitor::visit(MetavoxelInfo& info) { return DEFAULT_ORDER; } VoxelColorDataPointer colorPointer = info.inputValues.at(0).getInlineValue(); - QVector colorContents = (colorPointer && colorPointer->getSize() == VOXEL_BLOCK_SAMPLES) ? + QVector oldColorContents = (colorPointer && colorPointer->getSize() == VOXEL_BLOCK_SAMPLES) ? colorPointer->getContents() : QVector(VOXEL_BLOCK_VOLUME); + QVector colorContents = oldColorContents; Box overlap = info.getBounds().getIntersection(_region); float scale = VOXEL_BLOCK_SIZE / info.size; @@ -725,32 +726,92 @@ int VoxelMaterialBoxEditVisitor::visit(MetavoxelInfo& info) { for (int x = hermiteMinX, hermiteMaxX = x + hermiteSizeX - 1; x <= hermiteMaxX; x++, hermiteDestX += VoxelHermiteData::EDGE_COUNT) { // internal edges are set to zero; border edges (when non-terminal) are set to the intersection values - hermiteDestX[0] = 0x0; if ((x == hermiteMinX || x == hermiteMaxX) && x != VOXEL_BLOCK_SIZE) { - const QRgb* color = colorContents.constData() + z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + int offset = z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + const QRgb* color = colorContents.constData() + offset; int alpha0 = qAlpha(color[0]); - if (alpha0 != qAlpha(color[1])) { - hermiteDestX[0] = qRgba(alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, 0, 0, - ((x == hermiteMinX ? overlap.minimum.x : overlap.maximum.x) - x) * EIGHT_BIT_MAXIMUM); + int alpha1 = qAlpha(color[1]); + if (alpha0 != alpha1) { + const QRgb* oldColor = oldColorContents.constData() + offset; + if (qAlpha(oldColor[0]) == alpha0 && qAlpha(oldColor[1]) == alpha1) { + if (x == hermiteMinX) { + int alpha = (overlap.minimum.x - x) * EIGHT_BIT_MAXIMUM; + if (alpha <= qAlpha(hermiteDestX[0])) { + hermiteDestX[0] = qRgba(alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, 0, 0, alpha); + } + } else { + int alpha = (overlap.maximum.x - x) * EIGHT_BIT_MAXIMUM; + if (alpha >= qAlpha(hermiteDestX[0])) { + hermiteDestX[0] = qRgba(alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, 0, 0, alpha); + } + } + } else { + hermiteDestX[0] = qRgba(alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, 0, 0, + ((x == hermiteMinX ? overlap.minimum.x : overlap.maximum.x) - x) * EIGHT_BIT_MAXIMUM); + } + } else { + hermiteDestX[0] = 0x0; } + } else { + hermiteDestX[0] = 0x0; } - hermiteDestX[1] = 0x0; if ((y == hermiteMinY || y == hermiteMaxY) && y != VOXEL_BLOCK_SIZE) { - const QRgb* color = colorContents.constData() + z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + int offset = z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + const QRgb* color = colorContents.constData() + offset; int alpha0 = qAlpha(color[0]); - if (alpha0 != qAlpha(color[VOXEL_BLOCK_SAMPLES])) { - hermiteDestX[1] = qRgba(0, alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, 0, - ((y == hermiteMinY ? overlap.minimum.y : overlap.maximum.y) - y) * EIGHT_BIT_MAXIMUM); + int alpha2 = qAlpha(color[VOXEL_BLOCK_SAMPLES]); + if (alpha0 != alpha2) { + const QRgb* oldColor = oldColorContents.constData() + offset; + if (qAlpha(oldColor[0]) == alpha0 && qAlpha(oldColor[VOXEL_BLOCK_SAMPLES]) == alpha2) { + if (y == hermiteMinY) { + int alpha = (overlap.minimum.y - y) * EIGHT_BIT_MAXIMUM; + if (alpha <= qAlpha(hermiteDestX[1])) { + hermiteDestX[1] = qRgba(0, alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, 0, alpha); + } + } else { + int alpha = (overlap.maximum.y - y) * EIGHT_BIT_MAXIMUM; + if (alpha >= qAlpha(hermiteDestX[1])) { + hermiteDestX[1] = qRgba(0, alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, 0, alpha); + } + } + } else { + hermiteDestX[1] = qRgba(0, alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, 0, + ((y == hermiteMinY ? overlap.minimum.y : overlap.maximum.y) - y) * EIGHT_BIT_MAXIMUM); + } + } else { + hermiteDestX[1] = 0x0; } + } else { + hermiteDestX[1] = 0x0; } - hermiteDestX[2] = 0x0; if ((z == hermiteMinZ || z == hermiteMaxZ) && z != VOXEL_BLOCK_SIZE) { - const QRgb* color = colorContents.constData() + z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + int offset = z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + const QRgb* color = colorContents.constData() + offset; int alpha0 = qAlpha(color[0]); - if (alpha0 != qAlpha(color[VOXEL_BLOCK_AREA])) { - hermiteDestX[2] = qRgba(0, 0, alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, - ((z == hermiteMinZ ? overlap.minimum.z : overlap.maximum.z) - z) * EIGHT_BIT_MAXIMUM); + int alpha4 = qAlpha(color[VOXEL_BLOCK_AREA]); + if (alpha0 != alpha4) { + const QRgb* oldColor = oldColorContents.constData() + offset; + if (qAlpha(oldColor[0]) == alpha0 && qAlpha(oldColor[VOXEL_BLOCK_AREA]) == alpha4) { + if (z == hermiteMinZ) { + int alpha = (overlap.minimum.z - z) * EIGHT_BIT_MAXIMUM; + if (alpha <= qAlpha(hermiteDestX[2])) { + hermiteDestX[2] = qRgba(0, 0, alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, alpha); + } + } else { + int alpha = (overlap.maximum.z - z) * EIGHT_BIT_MAXIMUM; + if (alpha >= qAlpha(hermiteDestX[2])) { + hermiteDestX[2] = qRgba(0, 0, alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, alpha); + } + } + } else { + hermiteDestX[2] = qRgba(0, 0, alpha0 == 0 ? -NORMAL_MAX : NORMAL_MAX, + ((z == hermiteMinZ ? overlap.minimum.z : overlap.maximum.z) - z) * EIGHT_BIT_MAXIMUM); + } + } else { + hermiteDestX[2] = 0x0; } + } else { + hermiteDestX[2] = 0x0; } } } @@ -864,8 +925,9 @@ int VoxelMaterialSphereEditVisitor::visit(MetavoxelInfo& info) { return DEFAULT_ORDER; } VoxelColorDataPointer colorPointer = info.inputValues.at(0).getInlineValue(); - QVector colorContents = (colorPointer && colorPointer->getSize() == VOXEL_BLOCK_SAMPLES) ? + QVector oldColorContents = (colorPointer && colorPointer->getSize() == VOXEL_BLOCK_SAMPLES) ? colorPointer->getContents() : QVector(VOXEL_BLOCK_VOLUME); + QVector colorContents = oldColorContents; Box overlap = info.getBounds().getIntersection(_bounds); float scale = VOXEL_BLOCK_SIZE / info.size; @@ -883,6 +945,7 @@ int VoxelMaterialSphereEditVisitor::visit(MetavoxelInfo& info) { float relativeRadiusSquared = relativeRadius * relativeRadius; QRgb rgb = _color.rgba(); + bool flipped = (qAlpha(rgb) == 0); glm::vec3 position(0.0f, 0.0f, minZ); for (QRgb* destZ = colorContents.data() + minZ * VOXEL_BLOCK_AREA + minY * VOXEL_BLOCK_SAMPLES + minX, *endZ = destZ + sizeZ * VOXEL_BLOCK_AREA; destZ != endZ; destZ += VOXEL_BLOCK_AREA, position.z++) { @@ -932,78 +995,117 @@ int VoxelMaterialSphereEditVisitor::visit(MetavoxelInfo& info) { hermiteDestX += VoxelHermiteData::EDGE_COUNT) { // at each intersected non-terminal edge, we check for a transition and, if one is detected, we assign the // crossing and normal values based on intersection with the sphere - hermiteDestX[0] = 0x0; - glm::vec3 offset(x - relativeCenter.x, y - relativeCenter.y, z - relativeCenter.z); + glm::vec3 vector(x - relativeCenter.x, y - relativeCenter.y, z - relativeCenter.z); if (x != VOXEL_BLOCK_SIZE) { - const QRgb* color = colorContents.constData() + z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + int offset = z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + const QRgb* color = colorContents.constData() + offset; int alpha0 = qAlpha(color[0]); - if (alpha0 != qAlpha(color[1])) { - float radicand = relativeRadiusSquared - offset.y * offset.y - offset.z * offset.z; + int alpha1 = qAlpha(color[1]); + if (alpha0 != alpha1) { + float radicand = relativeRadiusSquared - vector.y * vector.y - vector.z * vector.z; float parameter = 0.5f; if (radicand >= 0.0f) { float root = glm::sqrt(radicand); - parameter = -offset.x - root; + parameter = -vector.x - root; if (parameter < 0.0f || parameter > 1.0f) { - parameter = glm::clamp(-offset.x + root, 0.0f, 1.0f); + parameter = glm::clamp(-vector.x + root, 0.0f, 1.0f); } } - glm::vec3 normal = offset + glm::vec3(parameter, 0.0f, 0.0f); + glm::vec3 normal = vector + glm::vec3(parameter, 0.0f, 0.0f); float length = glm::length(normal); if (length > EPSILON) { normal /= length; } else { normal = glm::vec3(0.0f, 1.0f, 0.0f); } - hermiteDestX[0] = packNormal(normal, parameter * EIGHT_BIT_MAXIMUM); + const QRgb* oldColor = oldColorContents.constData() + offset; + if (qAlpha(oldColor[0]) == alpha0 && qAlpha(oldColor[1]) == alpha1) { + int alpha = parameter * EIGHT_BIT_MAXIMUM; + if (normal.x < 0.0f ? alpha <= qAlpha(hermiteDestX[0]) : alpha >= qAlpha(hermiteDestX[0])) { + hermiteDestX[0] = packNormal(flipped ? -normal : normal, alpha); + } + } else { + hermiteDestX[0] = packNormal(flipped ? -normal : normal, parameter * EIGHT_BIT_MAXIMUM); + } + } else { + hermiteDestX[0] = 0x0; } + } else { + hermiteDestX[0] = 0x0; } - hermiteDestX[1] = 0x0; if (y != VOXEL_BLOCK_SIZE) { - const QRgb* color = colorContents.constData() + z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + int offset = z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + const QRgb* color = colorContents.constData() + offset; int alpha0 = qAlpha(color[0]); - if (alpha0 != qAlpha(color[VOXEL_BLOCK_SAMPLES])) { - float radicand = relativeRadiusSquared - offset.x * offset.x - offset.z * offset.z; + int alpha2 = qAlpha(color[VOXEL_BLOCK_SAMPLES]); + if (alpha0 != alpha2) { + float radicand = relativeRadiusSquared - vector.x * vector.x - vector.z * vector.z; float parameter = 0.5f; if (radicand >= 0.0f) { float root = glm::sqrt(radicand); - parameter = -offset.y - root; + parameter = -vector.y - root; if (parameter < 0.0f || parameter > 1.0f) { - parameter = glm::clamp(-offset.y + root, 0.0f, 1.0f); + parameter = glm::clamp(-vector.y + root, 0.0f, 1.0f); } } - glm::vec3 normal = offset + glm::vec3(parameter, 0.0f, 0.0f); + glm::vec3 normal = vector + glm::vec3(parameter, 0.0f, 0.0f); float length = glm::length(normal); if (length > EPSILON) { normal /= length; } else { normal = glm::vec3(1.0f, 0.0f, 0.0f); } - hermiteDestX[1] = packNormal(normal, parameter * EIGHT_BIT_MAXIMUM); + const QRgb* oldColor = oldColorContents.constData() + offset; + if (qAlpha(oldColor[0]) == alpha0 && qAlpha(oldColor[VOXEL_BLOCK_SAMPLES]) == alpha2) { + int alpha = parameter * EIGHT_BIT_MAXIMUM; + if (normal.y < 0.0f ? alpha <= qAlpha(hermiteDestX[1]) : alpha >= qAlpha(hermiteDestX[1])) { + hermiteDestX[1] = packNormal(flipped ? -normal : normal, alpha); + } + } else { + hermiteDestX[1] = packNormal(flipped ? -normal : normal, parameter * EIGHT_BIT_MAXIMUM); + } + } else { + hermiteDestX[1] = 0x0; } + } else { + hermiteDestX[1] = 0x0; } - hermiteDestX[2] = 0x0; if (z != VOXEL_BLOCK_SIZE) { - const QRgb* color = colorContents.constData() + z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + int offset = z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x; + const QRgb* color = colorContents.constData() + offset; int alpha0 = qAlpha(color[0]); - if (alpha0 != qAlpha(color[VOXEL_BLOCK_AREA])) { - float radicand = relativeRadiusSquared - offset.x * offset.x - offset.y * offset.y; + int alpha4 = qAlpha(color[VOXEL_BLOCK_AREA]); + if (alpha0 != alpha4) { + float radicand = relativeRadiusSquared - vector.x * vector.x - vector.y * vector.y; float parameter = 0.5f; if (radicand >= 0.0f) { float root = glm::sqrt(radicand); - parameter = -offset.z - root; + parameter = -vector.z - root; if (parameter < 0.0f || parameter > 1.0f) { - parameter = glm::clamp(-offset.z + root, 0.0f, 1.0f); + parameter = glm::clamp(-vector.z + root, 0.0f, 1.0f); } } - glm::vec3 normal = offset + glm::vec3(parameter, 0.0f, 0.0f); + glm::vec3 normal = vector + glm::vec3(parameter, 0.0f, 0.0f); float length = glm::length(normal); if (length > EPSILON) { normal /= length; } else { normal = glm::vec3(1.0f, 0.0f, 0.0f); } - hermiteDestX[2] = packNormal(normal, parameter * EIGHT_BIT_MAXIMUM); + const QRgb* oldColor = oldColorContents.constData() + offset; + if (qAlpha(oldColor[0]) == alpha0 && qAlpha(oldColor[VOXEL_BLOCK_AREA]) == alpha4) { + int alpha = parameter * EIGHT_BIT_MAXIMUM; + if (normal.z < 0.0f ? alpha <= qAlpha(hermiteDestX[2]) : alpha >= qAlpha(hermiteDestX[2])) { + hermiteDestX[2] = packNormal(flipped ? -normal : normal, alpha); + } + } else { + hermiteDestX[2] = packNormal(flipped ? -normal : normal, parameter * EIGHT_BIT_MAXIMUM); + } + } else { + hermiteDestX[2] = 0x0; } + } else { + hermiteDestX[2] = 0x0; } } }