From 9fc0abe2b3c37925fc357a49c9e7d3929e702957 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 6 Oct 2014 17:30:28 -0700 Subject: [PATCH 1/6] Working on metavoxel averaging. Still pretty rough. --- interface/src/MetavoxelSystem.cpp | 58 +++---- interface/src/ui/MetavoxelEditor.cpp | 2 +- .../metavoxels/src/AttributeRegistry.cpp | 153 +++++++++++++++++- 3 files changed, 179 insertions(+), 34 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 7faf1a5bf4..cb2673b08d 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -1564,14 +1564,13 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue(); VoxelMaterialDataPointer material = info.inputValues.at(1).getInlineValue(); VoxelHermiteDataPointer hermite = info.inputValues.at(2).getInlineValue(); - if (color && material && hermite) { + if (color && hermite) { QVector vertices; QVector indices; // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the // dual contour algorithm for generating meshes from voxel data using Hermite-tagged edges const QVector& colorContents = color->getContents(); - const QByteArray& materialContents = material->getContents(); const QVector& hermiteContents = hermite->getContents(); int size = color->getSize(); int area = size * size; @@ -1589,7 +1588,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { int hermiteStride = hermite->getSize() * VoxelHermiteData::EDGE_COUNT; int hermiteArea = hermiteStride * hermite->getSize(); - const char* materialData = materialContents.constData(); + const char* materialData = material ? material->getContents().constData() : NULL; // as we scan down the cube generating vertices between grid points, we remember the indices of the last // (element, line, section--x, y, z) so that we can connect generated vertices as quads @@ -1667,7 +1666,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { int clampedX = qMax(x - 1, 0), clampedY = qMax(y - 1, 0), clampedZ = qMax(z - 1, 0); const QRgb* hermiteBase = hermiteData + clampedZ * hermiteArea + clampedY * hermiteStride + clampedX * VoxelHermiteData::EDGE_COUNT; - const char* materialBase = materialData + clampedZ * area + clampedY * size + clampedX; + const char* materialBase = materialData ? + (materialData + clampedZ * area + clampedY * size + clampedX) : NULL; int crossingCount = 0; if (middleX) { if (alpha0 != alpha1) { @@ -1676,10 +1676,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha0 == 0) { crossing.color = colorX[1]; - crossing.material = materialBase[1]; + crossing.material = materialBase ? materialBase[1] : 0; } else { crossing.color = colorX[0]; - crossing.material = materialBase[0]; + crossing.material = materialBase ? materialBase[0] : 0; } crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f); crossing.axis = 0; @@ -1691,10 +1691,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha1 == 0) { crossing.color = colorX[offset3]; - crossing.material = materialBase[offset3]; + crossing.material = materialBase ? materialBase[offset3] : 0; } else { crossing.color = colorX[1]; - crossing.material = materialBase[1]; + crossing.material = materialBase ? materialBase[1] : 0; } crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); crossing.axis = 1; @@ -1705,10 +1705,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha2 == 0) { crossing.color = colorX[offset3]; - crossing.material = materialBase[offset3]; + crossing.material = materialBase ? materialBase[offset3] : 0; } else { crossing.color = colorX[size]; - crossing.material = materialBase[size]; + crossing.material = materialBase ? materialBase[size] : 0; } crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f); crossing.axis = 0; @@ -1720,10 +1720,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha3 == 0) { crossing.color = colorX[offset7]; - crossing.material = materialBase[offset7]; + crossing.material = materialBase ? materialBase[offset7] : 0; } else { crossing.color = colorX[offset3]; - crossing.material = materialBase[offset3]; + crossing.material = materialBase ? materialBase[offset3] : 0; } crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); crossing.axis = 2; @@ -1734,10 +1734,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha5 == 0) { crossing.color = colorX[offset7]; - crossing.material = materialBase[offset7]; + crossing.material = materialBase ? materialBase[offset7] : 0; } else { crossing.color = colorX[offset5]; - crossing.material = materialBase[offset5]; + crossing.material = materialBase ? materialBase[offset5] : 0; } crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); crossing.axis = 1; @@ -1748,10 +1748,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha6 == 0) { crossing.color = colorX[offset7]; - crossing.material = materialBase[offset7]; + crossing.material = materialBase ? materialBase[offset7] : 0; } else { crossing.color = colorX[offset6]; - crossing.material = materialBase[offset6]; + crossing.material = materialBase ? materialBase[offset6] : 0; } crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f); crossing.axis = 0; @@ -1765,10 +1765,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha1 == 0) { crossing.color = colorX[offset5]; - crossing.material = materialBase[offset5]; + crossing.material = materialBase ? materialBase[offset5] : 0; } else { crossing.color = colorX[1]; - crossing.material = materialBase[1]; + crossing.material = materialBase ? materialBase[1] : 0; } crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); crossing.axis = 2; @@ -1779,10 +1779,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha4 == 0) { crossing.color = colorX[offset5]; - crossing.material = materialBase[offset5]; + crossing.material = materialBase ? materialBase[offset5] : 0; } else { crossing.color = colorX[area]; - crossing.material = materialBase[area]; + crossing.material = materialBase ? materialBase[area] : 0; } crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f); crossing.axis = 0; @@ -1796,10 +1796,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha0 == 0) { crossing.color = colorX[size]; - crossing.material = materialBase[size]; + crossing.material = materialBase ? materialBase[size] : 0; } else { crossing.color = colorX[0]; - crossing.material = materialBase[0]; + crossing.material = materialBase ? materialBase[0] : 0; } crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); crossing.axis = 1; @@ -1811,10 +1811,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha2 == 0) { crossing.color = colorX[offset6]; - crossing.material = materialBase[offset6]; + crossing.material = materialBase ? materialBase[offset6] : 0; } else { crossing.color = colorX[size]; - crossing.material = materialBase[size]; + crossing.material = materialBase ? materialBase[size] : 0; } crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); crossing.axis = 2; @@ -1825,10 +1825,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha4 == 0) { crossing.color = colorX[offset6]; - crossing.material = materialBase[offset6]; + crossing.material = materialBase ? materialBase[offset6] : 0; } else { crossing.color = colorX[area]; - crossing.material = materialBase[area]; + crossing.material = materialBase ? materialBase[area] : 0; } crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); crossing.axis = 1; @@ -1841,10 +1841,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha0 == 0) { crossing.color = colorX[area]; - crossing.material = materialBase[area]; + crossing.material = materialBase ? materialBase[area] : 0; } else { crossing.color = colorX[0]; - crossing.material = materialBase[0]; + crossing.material = materialBase ? materialBase[0] : 0; } crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); crossing.axis = 2; @@ -2091,7 +2091,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } } - buffer = new VoxelBuffer(vertices, indices, material->getMaterials()); + buffer = new VoxelBuffer(vertices, indices, material ? material->getMaterials() : QVector()); } BufferDataPointer pointer(buffer); info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); diff --git a/interface/src/ui/MetavoxelEditor.cpp b/interface/src/ui/MetavoxelEditor.cpp index dffc02ee07..45911d9626 100644 --- a/interface/src/ui/MetavoxelEditor.cpp +++ b/interface/src/ui/MetavoxelEditor.cpp @@ -48,7 +48,7 @@ enum GridPlane { const glm::vec2 INVALID_VECTOR(FLT_MAX, FLT_MAX); MetavoxelEditor::MetavoxelEditor() : - QWidget(Application::getInstance()->getGLWidget(), Qt::Tool | Qt::WindowStaysOnTopHint) { + QWidget(Application::getInstance()->getGLWidget(), Qt::Tool) { setWindowTitle("Metavoxel Editor"); setAttribute(Qt::WA_DeleteOnClose); diff --git a/libraries/metavoxels/src/AttributeRegistry.cpp b/libraries/metavoxels/src/AttributeRegistry.cpp index aec9a069be..3ea011c265 100644 --- a/libraries/metavoxels/src/AttributeRegistry.cpp +++ b/libraries/metavoxels/src/AttributeRegistry.cpp @@ -1616,8 +1616,74 @@ bool VoxelColorAttribute::merge(void*& parent, void* children[], bool postRead) maxSize = qMax(maxSize, pointer->getSize()); } } - *(VoxelColorDataPointer*)&parent = VoxelColorDataPointer(); - return maxSize == 0; + if (maxSize == 0) { + *(VoxelColorDataPointer*)&parent = VoxelColorDataPointer(); + return true; + } + int size = maxSize; + int area = size * size; + QVector contents(area * size); + int halfSize = size / 2; + int halfSizeComplement = size - halfSize; + for (int i = 0; i < MERGE_COUNT; i++) { + VoxelColorDataPointer child = decodeInline(children[i]); + if (!child) { + continue; + } + const QVector& childContents = child->getContents(); + int childSize = child->getSize(); + int childArea = childSize * childSize; + const int INDEX_MASK = 1; + int xIndex = i & INDEX_MASK; + const int Y_SHIFT = 1; + int yIndex = (i >> Y_SHIFT) & INDEX_MASK; + int Z_SHIFT = 2; + int zIndex = (i >> Z_SHIFT) & INDEX_MASK; + QRgb* dest = contents.data() + (zIndex * halfSize * area) + (yIndex * halfSize * size) + (xIndex * halfSize); + const QRgb* src = childContents.data(); + + const int MAX_ALPHA = 255; + if (childSize == size) { + // simple case: one destination value for four child values + for (int z = 0; z < halfSizeComplement; z++) { + int offset4 = (z == halfSize) ? 0 : childArea; + for (int y = 0; y < halfSizeComplement; y++) { + int offset2 = (y == halfSize) ? 0 : childSize; + int offset6 = offset4 + offset2; + for (QRgb* end = dest + halfSizeComplement; dest != end; ) { + int offset1 = (dest == end - 1) ? 0 : 1; + QRgb v0 = src[0], v1 = src[offset1], v2 = src[offset2], v3 = src[offset2 + offset1], v4 = src[offset4], + v5 = src[offset4 + offset1], v6 = src[offset6], v7 = src[offset6 + offset1]; + src += (1 + offset1); + int a0 = qAlpha(v0), a1 = qAlpha(v1), a2 = qAlpha(v2), a3 = qAlpha(v3), + a4 = qAlpha(v4), a5 = qAlpha(v5), a6 = qAlpha(v6), a7 = qAlpha(v7); + int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7; + if (alphaTotal == 0) { + *dest++ = qRgba(0, 0, 0, 0); + continue; + } + *dest++ = qRgba( + (qRed(v0) * a0 + qRed(v1) * a1 + qRed(v2) * a2 + qRed(v3) * a3 + + qRed(v4) * a4 + qRed(v5) * a5 + qRed(v6) * a6 + qRed(v7) * a7) / alphaTotal, + (qGreen(v0) * a0 + qGreen(v1) * a1 + qGreen(v2) * a2 + qGreen(v3) * a3 + + qGreen(v4) * a4 + qGreen(v5) * a5 + qGreen(v6) * a6 + qGreen(v7) * a7) / alphaTotal, + (qBlue(v0) * a0 + qBlue(v1) * a1 + qBlue(v2) * a2 + qBlue(v3) * a3 + + qBlue(v4) * a4 + qBlue(v5) * a5 + qBlue(v6) * a6 + qBlue(v7) * a7) / alphaTotal, + MAX_ALPHA); + } + dest += halfSize; + src += offset2; + } + dest += halfSize * size; + src += offset4; + } + } else { + // more complex: N destination values for four child values + // ... + } + } + *(VoxelColorDataPointer*)&parent = VoxelColorDataPointer(new VoxelColorData(contents, size)); + return false; } const int VOXEL_MATERIAL_HEADER_SIZE = sizeof(qint32) * 6; @@ -2020,8 +2086,87 @@ bool VoxelHermiteAttribute::merge(void*& parent, void* children[], bool postRead maxSize = qMax(maxSize, pointer->getSize()); } } - *(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer(); - return maxSize == 0; + if (maxSize == 0) { + *(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer(); + return true; + } + int size = maxSize; + int area = size * size; + QVector contents(area * size * VoxelHermiteData::EDGE_COUNT); + int halfSize = size / 2; + int halfSizeComplement = size - halfSize; + for (int i = 0; i < MERGE_COUNT; i++) { + VoxelHermiteDataPointer child = decodeInline(children[i]); + if (!child) { + continue; + } + const QVector& childContents = child->getContents(); + int childSize = child->getSize(); + int childArea = childSize * childSize; + const int INDEX_MASK = 1; + int xIndex = i & INDEX_MASK; + const int Y_SHIFT = 1; + int yIndex = (i >> Y_SHIFT) & INDEX_MASK; + int Z_SHIFT = 2; + int zIndex = (i >> Z_SHIFT) & INDEX_MASK; + QRgb* dest = contents.data() + ((zIndex * halfSize * area) + (yIndex * halfSize * size) + (xIndex * halfSize)) * + VoxelHermiteData::EDGE_COUNT; + const QRgb* src = childContents.data(); + + if (childSize == size) { + // simple case: one destination value for four child values + for (int z = 0; z < halfSizeComplement; z++) { + int offset4 = (z == halfSize) ? 0 : (childArea * VoxelHermiteData::EDGE_COUNT); + for (int y = 0; y < halfSizeComplement; y++) { + int offset2 = (y == halfSize) ? 0 : (childSize * VoxelHermiteData::EDGE_COUNT); + int offset6 = offset4 + offset2; + for (QRgb* end = dest + halfSizeComplement * VoxelHermiteData::EDGE_COUNT; dest != end; + dest += VoxelHermiteData::EDGE_COUNT) { + int offset1 = (dest == end - VoxelHermiteData::EDGE_COUNT) ? 0 : VoxelHermiteData::EDGE_COUNT; + for (int i = 0; i < VoxelHermiteData::EDGE_COUNT; i++) { + QRgb v[] = { src[i], src[offset1 + i], src[offset2 + i], src[offset2 + offset1 + i], + src[offset4 + i], src[offset4 + offset1 + i], src[offset6 + i], src[offset6 + offset1 + i] }; + glm::vec3 n[] = { unpackNormal(v[0]), unpackNormal(v[1]), unpackNormal(v[2]), unpackNormal(v[3]), + unpackNormal(v[4]), unpackNormal(v[5]), unpackNormal(v[6]), unpackNormal(v[7]) }; + float l[] = { glm::length(n[0]), glm::length(n[1]), glm::length(n[2]), glm::length(n[3]), + glm::length(n[4]), glm::length(n[5]), glm::length(n[6]), glm::length(n[7]) }; + float lengthTotal = l[0] + l[1] + l[2] + l[3] + l[4] + l[5] + l[6] + l[7]; + if (lengthTotal == 0.0f) { + dest[i] = qRgba(0, 0, 0, 0); + continue; + } + glm::vec3 combinedNormal = n[0] * l[0] + n[1] * l[1] + n[2] * l[2] + n[3] * l[3] + n[4] * l[4] + + n[5] * l[5] + n[6] * l[6] + n[7] * l[7]; + float combinedLength = glm::length(combinedNormal); + if (combinedLength > 0.0f) { + combinedNormal /= combinedLength; + } + float combinedOffset = 0.0f; + int mask = 1 << i; + for (int j = 0; j < MERGE_COUNT; j++) { + float offset = qAlpha(v[j]) * (0.5f / EIGHT_BIT_MAXIMUM); + if (j & mask) { + offset += 0.5f; + } + combinedOffset += offset * l[j]; + } + dest[i] = packNormal(combinedNormal, EIGHT_BIT_MAXIMUM * combinedOffset / lengthTotal); + } + src += (VoxelHermiteData::EDGE_COUNT + offset1); + } + dest += (halfSize * VoxelHermiteData::EDGE_COUNT); + src += offset2; + } + dest += (halfSize * size * VoxelHermiteData::EDGE_COUNT); + src += offset4; + } + } else { + // more complex: N destination values for four child values + // ... + } + } + *(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer(new VoxelHermiteData(contents, size)); + return false; } SharedObjectAttribute::SharedObjectAttribute(const QString& name, const QMetaObject* metaObject, From c9fb73ecf8f96a6e6e0ea4047ea424758b925f69 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 6 Oct 2014 18:52:10 -0700 Subject: [PATCH 2/6] Playing around with using points to represent distant voxel surfaces. --- .../resources/shaders/metavoxel_point.vert | 13 ++-- interface/src/MetavoxelSystem.cpp | 72 ++++++++++++++++++- interface/src/MetavoxelSystem.h | 12 ++++ 3 files changed, 89 insertions(+), 8 deletions(-) diff --git a/interface/resources/shaders/metavoxel_point.vert b/interface/resources/shaders/metavoxel_point.vert index 1a4a4c56ce..02de2bfa01 100644 --- a/interface/resources/shaders/metavoxel_point.vert +++ b/interface/resources/shaders/metavoxel_point.vert @@ -13,16 +13,19 @@ uniform float pointScale; -void main(void) { +// the interpolated normal +varying vec4 normal; - // standard diffuse lighting - gl_FrontColor = vec4(gl_Color.rgb * (gl_LightModel.ambient.rgb + gl_LightSource[0].ambient.rgb + - gl_LightSource[0].diffuse.rgb * max(0.0, dot(gl_NormalMatrix * gl_Normal, gl_LightSource[0].position.xyz))), - 0.0); +void main(void) { + // transform and store the normal for interpolation + normal = vec4(normalize(gl_NormalMatrix * gl_Normal), 0.0); // extract the first three components of the vertex for position gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0); // the final component is the size in world space gl_PointSize = pointScale * gl_Vertex.w / gl_Position.w; + + // copy the color for interpolation + gl_FrontColor = vec4(gl_Color.rgb, 0.0); } diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index cb2673b08d..a2dbaa301f 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -620,6 +620,22 @@ void PointBuffer::render(bool cursor) { _buffer.release(); } +VoxelPointBuffer::VoxelPointBuffer(const BufferPointVector& points) : + PointBuffer(points) { +} + +void VoxelPointBuffer::render(bool cursor) { + DefaultMetavoxelRendererImplementation::getPointProgram().bind(); + + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); + + PointBuffer::render(cursor); + + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); + + DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); +} + const int HeightfieldBuffer::HEIGHT_BORDER = 1; const int HeightfieldBuffer::SHARED_EDGE = 1; const int HeightfieldBuffer::HEIGHT_EXTENSION = 2 * HeightfieldBuffer::HEIGHT_BORDER + HeightfieldBuffer::SHARED_EDGE; @@ -1117,7 +1133,10 @@ AttributeValue BufferDataAttribute::inherit(const AttributeValue& parentValue) c void DefaultMetavoxelRendererImplementation::init() { if (!_pointProgram.isLinked()) { - _pointProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert"); + _pointProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + + "shaders/metavoxel_point.vert"); + _pointProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + + "shaders/metavoxel_voxel_base.frag"); _pointProgram.link(); _pointProgram.bind(); @@ -1560,11 +1579,11 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { if (!info.isLeaf) { return DEFAULT_ORDER; } - VoxelBuffer* buffer = NULL; + BufferData* buffer = NULL; VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue(); VoxelMaterialDataPointer material = info.inputValues.at(1).getInlineValue(); VoxelHermiteDataPointer hermite = info.inputValues.at(2).getInlineValue(); - if (color && hermite) { + if (color && hermite && material) { QVector vertices; QVector indices; @@ -2092,6 +2111,53 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } buffer = new VoxelBuffer(vertices, indices, material ? material->getMaterials() : QVector()); + + } else if (color) { + BufferPointVector points; + + const QVector& colorContents = color->getContents(); + int size = color->getSize(); + int area = size * size; + int limit = size - 1; + + const QRgb* colorZ = colorContents.constData(); + int offset3 = size + 1; + int offset5 = area + 1; + int offset6 = area + size; + int offset7 = offset6 + 1; + const int MAX_ALPHA_TOTAL = MetavoxelNode::CHILD_COUNT * EIGHT_BIT_MAXIMUM; + float step = info.size / limit; + glm::vec4 minimum(info.minimum.x + step * 0.5f, info.minimum.y + step * 0.5f, info.minimum.z + step * 0.5f, 0.0f); + + for (int z = 0; z < limit; z++) { + const QRgb* colorY = colorZ; + for (int y = 0; y < limit; y++) { + const QRgb* colorX = colorY; + for (int x = 0; x < limit; x++) { + QRgb c0 = colorX[0], c1 = colorX[1], c2 = colorX[size], c3 = colorX[offset3], c4 = colorX[area], + c5 = colorX[offset5], c6 = colorX[offset6], c7 = colorX[offset7]; + colorX++; + int a0 = qAlpha(c0), a1 = qAlpha(c1), a2 = qAlpha(c2), a3 = qAlpha(c3), + a4 = qAlpha(c4), a5 = qAlpha(c5), a6 = qAlpha(c6), a7 = qAlpha(c7); + int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7; + if (alphaTotal == 0 || alphaTotal == MAX_ALPHA_TOTAL) { + continue; + } + BufferPoint point = { minimum + glm::vec4(x, y, z, 1.0f) * step, + { (quint8)((qRed(c0) * a0 + qRed(c1) * a1 + qRed(c2) * a2 + qRed(c3) * a3 + qRed(c4) * a4 + + qRed(c5) * a5 + qRed(c6) * a6 + qRed(c7) * a7) / alphaTotal), + (quint8)((qGreen(c0) * a0 + qGreen(c1) * a1 + qGreen(c2) * a2 + qGreen(c3) * a3 + qGreen(c4) * a4 + + qGreen(c5) * a5 + qGreen(c6) * a6 + qGreen(c7) * a7) / alphaTotal), + (quint8)((qBlue(c0) * a0 + qBlue(c1) * a1 + qBlue(c2) * a2 + qBlue(c3) * a3 + qBlue(c4) * a4 + + qBlue(c5) * a5 + qBlue(c6) * a6 + qBlue(c7) * a7) / alphaTotal) }, + { 0, 127, 0 } }; + points.append(point); + } + colorY += size; + } + colorZ += area; + } + buffer = new VoxelPointBuffer(points); } BufferDataPointer pointer(buffer); info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index 10110a5c5c..af6c0ccf05 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -140,6 +140,15 @@ private: int _pointCount; }; +/// Contains the information necessary to render a group of voxels as points. +class VoxelPointBuffer : public PointBuffer { +public: + + VoxelPointBuffer(const BufferPointVector& points); + + virtual void render(bool cursor = false); +}; + /// Contains the information necessary to render a heightfield block. class HeightfieldBuffer : public BufferData { public: @@ -272,6 +281,9 @@ public: static void init(); + static ProgramObject& getPointProgram() { return _pointProgram; } + static int getPointScaleLocation() { return _pointScaleLocation; } + static ProgramObject& getBaseHeightfieldProgram() { return _baseHeightfieldProgram; } static int getBaseHeightScaleLocation() { return _baseHeightScaleLocation; } static int getBaseColorScaleLocation() { return _baseColorScaleLocation; } From 604fc84232dbf7df51155f5bd90582b2ca015860 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 7 Oct 2014 14:33:01 -0700 Subject: [PATCH 3/6] More fiddling with averages. --- interface/src/MetavoxelSystem.cpp | 90 +++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index a2dbaa301f..e702838987 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -2112,10 +2112,11 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { buffer = new VoxelBuffer(vertices, indices, material ? material->getMaterials() : QVector()); - } else if (color) { + } else if (color && hermite) { BufferPointVector points; const QVector& colorContents = color->getContents(); + const QVector& hermiteContents = hermite->getContents(); int size = color->getSize(); int area = size * size; int limit = size - 1; @@ -2129,6 +2130,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { float step = info.size / limit; glm::vec4 minimum(info.minimum.x + step * 0.5f, info.minimum.y + step * 0.5f, info.minimum.z + step * 0.5f, 0.0f); + const QRgb* hermiteData = hermiteContents.constData(); + int hermiteStride = hermite->getSize() * VoxelHermiteData::EDGE_COUNT; + int hermiteArea = hermiteStride * hermite->getSize(); + for (int z = 0; z < limit; z++) { const QRgb* colorY = colorZ; for (int y = 0; y < limit; y++) { @@ -2143,14 +2148,93 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { if (alphaTotal == 0 || alphaTotal == MAX_ALPHA_TOTAL) { continue; } - BufferPoint point = { minimum + glm::vec4(x, y, z, 1.0f) * step, + const QRgb* hermiteBase = hermiteData + z * hermiteArea + y * hermiteStride + + x * VoxelHermiteData::EDGE_COUNT; + glm::vec3 normal; + glm::vec3 position; + int crossingCount = 0; + if (a0 != a1) { + QRgb hermite = hermiteBase[0]; + position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a0 != a2) { + QRgb hermite = hermiteBase[1]; + position += glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a0 != a4) { + QRgb hermite = hermiteBase[2]; + position += glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a1 != a3) { + QRgb hermite = hermiteBase[VoxelHermiteData::EDGE_COUNT + 1]; + position += glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a1 != a5) { + QRgb hermite = hermiteBase[VoxelHermiteData::EDGE_COUNT + 2]; + position += glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a2 != a3) { + QRgb hermite = hermiteBase[hermiteStride]; + position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a2 != a6) { + QRgb hermite = hermiteBase[hermiteStride + 2]; + position += glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a3 != a7) { + QRgb hermite = hermiteBase[hermiteStride + VoxelHermiteData::EDGE_COUNT + 2]; + position += glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a4 != a5) { + QRgb hermite = hermiteBase[hermiteArea]; + position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a4 != a6) { + QRgb hermite = hermiteBase[hermiteArea + 1]; + position += glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a5 != a7) { + QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1]; + position += glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); + normal += unpackNormal(hermite); + crossingCount++; + } + if (a6 != a7) { + QRgb hermite = hermiteBase[hermiteArea + hermiteStride]; + position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f); + normal += unpackNormal(hermite); + crossingCount++; + } + normal = safeNormalize(normal); + BufferPoint point = { minimum + (glm::vec4(x, y, z, 1.0f) + + glm::vec4(position / (float)crossingCount, 0.0f)) * step, { (quint8)((qRed(c0) * a0 + qRed(c1) * a1 + qRed(c2) * a2 + qRed(c3) * a3 + qRed(c4) * a4 + qRed(c5) * a5 + qRed(c6) * a6 + qRed(c7) * a7) / alphaTotal), (quint8)((qGreen(c0) * a0 + qGreen(c1) * a1 + qGreen(c2) * a2 + qGreen(c3) * a3 + qGreen(c4) * a4 + qGreen(c5) * a5 + qGreen(c6) * a6 + qGreen(c7) * a7) / alphaTotal), (quint8)((qBlue(c0) * a0 + qBlue(c1) * a1 + qBlue(c2) * a2 + qBlue(c3) * a3 + qBlue(c4) * a4 + qBlue(c5) * a5 + qBlue(c6) * a6 + qBlue(c7) * a7) / alphaTotal) }, - { 0, 127, 0 } }; + { (quint8)(normal.x * 127.0f), (quint8)(normal.y * 127.0f), (quint8)(normal.z * 127.0f) } }; points.append(point); } colorY += size; From 04b628bede3c51f180819d2190ef773a23a94c60 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 7 Oct 2014 16:44:55 -0700 Subject: [PATCH 4/6] Added option to display Hermite data --- interface/src/Menu.cpp | 4 ++ interface/src/Menu.h | 1 + interface/src/MetavoxelSystem.cpp | 74 +++++++++++++++++++++- interface/src/MetavoxelSystem.h | 13 +++- libraries/metavoxels/src/MetavoxelData.cpp | 17 +++++ libraries/metavoxels/src/MetavoxelData.h | 5 ++ 6 files changed, 109 insertions(+), 5 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 5f2e3d767a..75eb96adc9 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -423,6 +423,10 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableAutoAdjustLOD); + QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels"); + addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false, + Application::getInstance()->getMetavoxels(), SLOT(updateHermiteDisplay())); + QMenu* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlternateIK, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index f73f4b02a2..67a4163c67 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -374,6 +374,7 @@ namespace MenuOption { const QString DisplayFrustum = "Display Frustum"; const QString DisplayHands = "Show Hand Info"; const QString DisplayHandTargets = "Show Hand Targets"; + const QString DisplayHermiteData = "Display Hermite Data"; const QString DisplayModelBounds = "Display Model Bounds"; const QString DisplayModelElementChildProxies = "Display Model Element Children"; const QString DisplayModelElementProxy = "Display Model Element Bounds"; diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index e702838987..1b8e3094be 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -137,6 +137,20 @@ void MetavoxelSystem::render() { emit rendering(); } +void MetavoxelSystem::updateHermiteDisplay() { + if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + if (node->getType() == NodeType::MetavoxelServer) { + QMutexLocker locker(&node->getMutex()); + MetavoxelSystemClient* client = static_cast(node->getLinkedData()); + if (client) { + QMetaObject::invokeMethod(client, "refreshVoxelData"); + } + } + } + } +} + class RayHeightfieldIntersectionVisitor : public RayIntersectionVisitor { public: @@ -577,6 +591,14 @@ void Augmenter::run() { QMetaObject::invokeMethod(node->getLinkedData(), "setAugmentedData", Q_ARG(const MetavoxelData&, _data)); } +void MetavoxelSystemClient::refreshVoxelData() { + // make it look as if all the colors have changed + MetavoxelData oldData = getAugmentedData(); + oldData.touch(AttributeRegistry::getInstance()->getVoxelColorAttribute()); + + QThreadPool::globalInstance()->start(new Augmenter(_node, _data, oldData, _remoteDataLOD)); +} + void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) { MetavoxelClient::dataChanged(oldData); QThreadPool::globalInstance()->start(new Augmenter(_node, _data, getAugmentedData(), _remoteDataLOD)); @@ -986,12 +1008,14 @@ void VoxelPoint::setNormal(const glm::vec3& normal) { this->normal[2] = (char)(normal.z * 127.0f); } -VoxelBuffer::VoxelBuffer(const QVector& vertices, const QVector& indices, +VoxelBuffer::VoxelBuffer(const QVector& vertices, const QVector& indices, const QVector& hermite, const QVector& materials) : _vertices(vertices), _indices(indices), + _hermite(hermite), _vertexCount(vertices.size()), _indexCount(indices.size()), + _hermiteCount(hermite.size()), _indexBuffer(QOpenGLBuffer::IndexBuffer), _materials(materials) { } @@ -1111,6 +1135,41 @@ void VoxelBuffer::render(bool cursor) { _vertexBuffer.release(); _indexBuffer.release(); + + if (_hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { + if (!_hermiteBuffer.isCreated()) { + _hermiteBuffer.create(); + _hermiteBuffer.bind(); + _hermiteBuffer.allocate(_hermite.constData(), _hermite.size() * sizeof(glm::vec3)); + _hermite.clear(); + + } else { + _hermiteBuffer.bind(); + } + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + glVertexPointer(3, GL_FLOAT, 0, 0); + + Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glNormal3f(0.0f, 1.0f, 0.0f); + + glLineWidth(2.0f); + + glDrawArrays(GL_LINES, 0, _hermiteCount); + + glLineWidth(1.0f); + + DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + _hermiteBuffer.release(); + } } BufferDataAttribute::BufferDataAttribute(const QString& name) : @@ -1586,6 +1645,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { if (color && hermite && material) { QVector vertices; QVector indices; + QVector hermiteSegments; // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the // dual contour algorithm for generating meshes from voxel data using Hermite-tagged edges @@ -1623,6 +1683,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { float highest = size - 1.0f; float scale = info.size / highest; const int ALPHA_OFFSET = 24; + bool displayHermite = Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData); for (int z = 0; z < expanded; z++) { const QRgb* colorY = colorZ; for (int y = 0; y < expanded; y++) { @@ -1885,6 +1946,13 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { green += qGreen(crossing.color); blue += qBlue(crossing.color); + if (displayHermite) { + glm::vec3 start = info.minimum + (glm::vec3(clampedX, clampedY, clampedZ) + + crossing.point) * scale; + hermiteSegments.append(start); + hermiteSegments.append(start + crossing.normal * scale); + } + // when assigning a material, search for its presence and, if not found, // place it in the first empty slot if (crossing.material != 0) { @@ -2109,8 +2177,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { colorZ += area; } } - - buffer = new VoxelBuffer(vertices, indices, material ? material->getMaterials() : QVector()); + buffer = new VoxelBuffer(vertices, indices, hermiteSegments, + material ? material->getMaterials() : QVector()); } else if (color && hermite) { BufferPointVector points; diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index af6c0ccf05..e349546bb4 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -56,6 +56,10 @@ signals: void rendering(); +public slots: + + void updateHermiteDisplay(); + protected: virtual MetavoxelClient* createClient(const SharedNodePointer& node); @@ -99,9 +103,11 @@ public: MetavoxelData getAugmentedData(); void setRenderedAugmentedData(const MetavoxelData& data) { _renderedAugmentedData = data; } - + virtual int parseData(const QByteArray& packet); + Q_INVOKABLE void refreshVoxelData(); + protected: virtual void dataChanged(const MetavoxelData& oldData); @@ -243,7 +249,7 @@ public: class VoxelBuffer : public BufferData { public: - VoxelBuffer(const QVector& vertices, const QVector& indices, + VoxelBuffer(const QVector& vertices, const QVector& indices, const QVector& hermite, const QVector& materials = QVector()); virtual void render(bool cursor = false); @@ -252,10 +258,13 @@ private: QVector _vertices; QVector _indices; + QVector _hermite; int _vertexCount; int _indexCount; + int _hermiteCount; QOpenGLBuffer _vertexBuffer; QOpenGLBuffer _indexBuffer; + QOpenGLBuffer _hermiteBuffer; QVector _materials; QVector _networkTextures; }; diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 07c55bd0ab..920482a016 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -374,6 +374,13 @@ void MetavoxelData::clear(const AttributePointer& attribute) { } } +void MetavoxelData::touch(const AttributePointer& attribute) { + MetavoxelNode* root = _roots.value(attribute); + if (root) { + setRoot(attribute, root->touch(attribute)); + } +} + class FirstRaySpannerIntersectionVisitor : public RaySpannerIntersectionVisitor { public: @@ -1249,6 +1256,16 @@ void MetavoxelNode::countNodes(const AttributePointer& attribute, const glm::vec } } +MetavoxelNode* MetavoxelNode::touch(const AttributePointer& attribute) const { + MetavoxelNode* node = new MetavoxelNode(getAttributeValue(attribute)); + for (int i = 0; i < CHILD_COUNT; i++) { + if (_children[i]) { + node->setChild(i, _children[i]->touch(attribute)); + } + } + return node; +} + MetavoxelInfo::MetavoxelInfo(MetavoxelInfo* parentInfo, int inputValuesSize, int outputValuesSize) : parentInfo(parentInfo), inputValues(inputValuesSize), diff --git a/libraries/metavoxels/src/MetavoxelData.h b/libraries/metavoxels/src/MetavoxelData.h index c693cf723c..db28ce056f 100644 --- a/libraries/metavoxels/src/MetavoxelData.h +++ b/libraries/metavoxels/src/MetavoxelData.h @@ -112,6 +112,9 @@ public: /// Clears all data in the specified attribute layer. void clear(const AttributePointer& attribute); + /// "Touches" all data in the specified attribute layer, making it look as if it has changed. + void touch(const AttributePointer& attribute); + /// Convenience function that finds the first spanner intersecting the provided ray. SharedObjectPointer findFirstRaySpannerIntersection(const glm::vec3& origin, const glm::vec3& direction, const AttributePointer& attribute, float& distance, const MetavoxelLOD& lod = MetavoxelLOD()); @@ -254,6 +257,8 @@ public: void countNodes(const AttributePointer& attribute, const glm::vec3& minimum, float size, const MetavoxelLOD& lod, int& internalNodes, int& leaves) const; + MetavoxelNode* touch(const AttributePointer& attribute) const; + private: Q_DISABLE_COPY(MetavoxelNode) From b5b82ed387c84775f985bd0fe289f1c02719c73b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 8 Oct 2014 14:05:14 -0700 Subject: [PATCH 5/6] Provide the option to display lower detail metavoxel data as points. --- interface/src/Menu.cpp | 4 +- interface/src/Menu.h | 1 + interface/src/MetavoxelSystem.cpp | 194 ++++++++++-------- interface/src/MetavoxelSystem.h | 10 +- .../metavoxels/src/AttributeRegistry.cpp | 4 +- 5 files changed, 122 insertions(+), 91 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 954f04f47d..5e375dc6be 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -425,7 +425,9 @@ Menu::Menu() : QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels"); addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false, - Application::getInstance()->getMetavoxels(), SLOT(updateHermiteDisplay())); + Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData())); + addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::LowerDetailAsPoints, 0, false, + Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData())); QMenu* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 67a4163c67..11e1131da4 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -414,6 +414,7 @@ namespace MenuOption { const QString Log = "Log"; const QString Logout = "Logout"; const QString LowVelocityFilter = "Low Velocity Filter"; + const QString LowerDetailAsPoints = "Lower Detail as Points"; const QString MetavoxelEditor = "Metavoxel Editor..."; const QString Metavoxels = "Metavoxels"; const QString Mirror = "Mirror"; diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 1b8e3094be..2d4e9e7459 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -137,15 +137,13 @@ void MetavoxelSystem::render() { emit rendering(); } -void MetavoxelSystem::updateHermiteDisplay() { - if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { - if (node->getType() == NodeType::MetavoxelServer) { - QMutexLocker locker(&node->getMutex()); - MetavoxelSystemClient* client = static_cast(node->getLinkedData()); - if (client) { - QMetaObject::invokeMethod(client, "refreshVoxelData"); - } +void MetavoxelSystem::refreshVoxelData() { + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + if (node->getType() == NodeType::MetavoxelServer) { + QMutexLocker locker(&node->getMutex()); + MetavoxelSystemClient* client = static_cast(node->getLinkedData()); + if (client) { + QMetaObject::invokeMethod(client, "refreshVoxelData"); } } } @@ -642,8 +640,47 @@ void PointBuffer::render(bool cursor) { _buffer.release(); } -VoxelPointBuffer::VoxelPointBuffer(const BufferPointVector& points) : - PointBuffer(points) { +VoxelPointBuffer::VoxelPointBuffer(const BufferPointVector& points, const QVector& hermite) : + PointBuffer(points), + _hermite(hermite), + _hermiteCount(hermite.size()) { +} + +static void renderHermiteData(QVector& hermite, int hermiteCount, QOpenGLBuffer& hermiteBuffer) { + if (hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { + if (!hermiteBuffer.isCreated()) { + hermiteBuffer.create(); + hermiteBuffer.bind(); + hermiteBuffer.allocate(hermite.constData(), hermite.size() * sizeof(glm::vec3)); + hermite.clear(); + + } else { + hermiteBuffer.bind(); + } + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + glVertexPointer(3, GL_FLOAT, 0, 0); + + Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glNormal3f(0.0f, 1.0f, 0.0f); + + glLineWidth(2.0f); + + glDrawArrays(GL_LINES, 0, hermiteCount); + + glLineWidth(1.0f); + + DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + hermiteBuffer.release(); + } } void VoxelPointBuffer::render(bool cursor) { @@ -656,6 +693,8 @@ void VoxelPointBuffer::render(bool cursor) { glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); + + renderHermiteData(_hermite, _hermiteCount, _hermiteBuffer); } const int HeightfieldBuffer::HEIGHT_BORDER = 1; @@ -1136,40 +1175,7 @@ void VoxelBuffer::render(bool cursor) { _vertexBuffer.release(); _indexBuffer.release(); - if (_hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { - if (!_hermiteBuffer.isCreated()) { - _hermiteBuffer.create(); - _hermiteBuffer.bind(); - _hermiteBuffer.allocate(_hermite.constData(), _hermite.size() * sizeof(glm::vec3)); - _hermite.clear(); - - } else { - _hermiteBuffer.bind(); - } - - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - - glVertexPointer(3, GL_FLOAT, 0, 0); - - Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glNormal3f(0.0f, 1.0f, 0.0f); - - glLineWidth(2.0f); - - glDrawArrays(GL_LINES, 0, _hermiteCount); - - glLineWidth(1.0f); - - DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); - - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - _hermiteBuffer.release(); - } + renderHermiteData(_hermite, _hermiteCount, _hermiteBuffer); } BufferDataAttribute::BufferDataAttribute(const QString& name) : @@ -1638,11 +1644,14 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { if (!info.isLeaf) { return DEFAULT_ORDER; } + const int EDGES_PER_CUBE = 12; + BufferData* buffer = NULL; VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue(); VoxelMaterialDataPointer material = info.inputValues.at(1).getInlineValue(); VoxelHermiteDataPointer hermite = info.inputValues.at(2).getInlineValue(); - if (color && hermite && material) { + + if (color && hermite && (material || !Menu::getInstance()->isOptionChecked(MenuOption::LowerDetailAsPoints))) { QVector vertices; QVector indices; QVector hermiteSegments; @@ -1677,7 +1686,6 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { QVector planeIndices(expanded * expanded); QVector lastPlaneIndices(expanded * expanded); - const int EDGES_PER_CUBE = 12; EdgeCrossing crossings[EDGES_PER_CUBE]; float highest = size - 1.0f; @@ -2182,6 +2190,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } else if (color && hermite) { BufferPointVector points; + QVector hermiteSegments; const QVector& colorContents = color->getContents(); const QVector& hermiteContents = hermite->getContents(); @@ -2201,6 +2210,9 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { const QRgb* hermiteData = hermiteContents.constData(); int hermiteStride = hermite->getSize() * VoxelHermiteData::EDGE_COUNT; int hermiteArea = hermiteStride * hermite->getSize(); + bool displayHermite = Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData); + + EdgeCrossing crossings[EDGES_PER_CUBE]; for (int z = 0; z < limit; z++) { const QRgb* colorY = colorZ; @@ -2218,80 +2230,90 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } const QRgb* hermiteBase = hermiteData + z * hermiteArea + y * hermiteStride + x * VoxelHermiteData::EDGE_COUNT; - glm::vec3 normal; - glm::vec3 position; int crossingCount = 0; if (a0 != a1) { QRgb hermite = hermiteBase[0]; - position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f); + crossing.normal = unpackNormal(hermite); } if (a0 != a2) { QRgb hermite = hermiteBase[1]; - position += glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); + crossing.normal = unpackNormal(hermite); } if (a0 != a4) { QRgb hermite = hermiteBase[2]; - position += glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + crossing.normal = unpackNormal(hermite); } if (a1 != a3) { QRgb hermite = hermiteBase[VoxelHermiteData::EDGE_COUNT + 1]; - position += glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); + crossing.normal = unpackNormal(hermite); } if (a1 != a5) { QRgb hermite = hermiteBase[VoxelHermiteData::EDGE_COUNT + 2]; - position += glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + crossing.normal = unpackNormal(hermite); } if (a2 != a3) { QRgb hermite = hermiteBase[hermiteStride]; - position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f); + crossing.normal = unpackNormal(hermite); } if (a2 != a6) { QRgb hermite = hermiteBase[hermiteStride + 2]; - position += glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + crossing.normal = unpackNormal(hermite); } if (a3 != a7) { QRgb hermite = hermiteBase[hermiteStride + VoxelHermiteData::EDGE_COUNT + 2]; - position += glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + crossing.normal = unpackNormal(hermite); } if (a4 != a5) { QRgb hermite = hermiteBase[hermiteArea]; - position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f); + crossing.normal = unpackNormal(hermite); } if (a4 != a6) { QRgb hermite = hermiteBase[hermiteArea + 1]; - position += glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); + crossing.normal = unpackNormal(hermite); } if (a5 != a7) { QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1]; - position += glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); + crossing.normal = unpackNormal(hermite); } if (a6 != a7) { QRgb hermite = hermiteBase[hermiteArea + hermiteStride]; - position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f); + crossing.normal = unpackNormal(hermite); + } + glm::vec3 normal; + glm::vec3 position; + for (int i = 0; i < crossingCount; i++) { + const EdgeCrossing& crossing = crossings[i]; + position += crossing.point; + normal += crossing.normal; + if (displayHermite) { + glm::vec3 base = glm::vec3(minimum) + (glm::vec3(x, y, z) + crossing.point) * step; + hermiteSegments.append(base); + hermiteSegments.append(base + crossing.normal * step); + } } normal = safeNormalize(normal); BufferPoint point = { minimum + (glm::vec4(x, y, z, 1.0f) + @@ -2309,7 +2331,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } colorZ += area; } - buffer = new VoxelPointBuffer(points); + buffer = new VoxelPointBuffer(points, hermiteSegments); } BufferDataPointer pointer(buffer); info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index e349546bb4..e8987a3f5e 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -58,7 +58,7 @@ signals: public slots: - void updateHermiteDisplay(); + void refreshVoxelData(); protected: @@ -150,9 +150,15 @@ private: class VoxelPointBuffer : public PointBuffer { public: - VoxelPointBuffer(const BufferPointVector& points); + VoxelPointBuffer(const BufferPointVector& points, const QVector& hermite); virtual void render(bool cursor = false); + +private: + + QVector _hermite; + int _hermiteCount; + QOpenGLBuffer _hermiteBuffer; }; /// Contains the information necessary to render a heightfield block. diff --git a/libraries/metavoxels/src/AttributeRegistry.cpp b/libraries/metavoxels/src/AttributeRegistry.cpp index 3ea011c265..44c333a03f 100644 --- a/libraries/metavoxels/src/AttributeRegistry.cpp +++ b/libraries/metavoxels/src/AttributeRegistry.cpp @@ -1657,11 +1657,11 @@ bool VoxelColorAttribute::merge(void*& parent, void* children[], bool postRead) src += (1 + offset1); int a0 = qAlpha(v0), a1 = qAlpha(v1), a2 = qAlpha(v2), a3 = qAlpha(v3), a4 = qAlpha(v4), a5 = qAlpha(v5), a6 = qAlpha(v6), a7 = qAlpha(v7); - int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7; - if (alphaTotal == 0) { + if (a0 == 0) { *dest++ = qRgba(0, 0, 0, 0); continue; } + int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7; *dest++ = qRgba( (qRed(v0) * a0 + qRed(v1) * a1 + qRed(v2) * a2 + qRed(v3) * a3 + qRed(v4) * a4 + qRed(v5) * a5 + qRed(v6) * a6 + qRed(v7) * a7) / alphaTotal, From 37eff685bcefad15239fd1b71a5d91e49b235810 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 8 Oct 2014 15:11:55 -0700 Subject: [PATCH 6/6] Remove the "render lower detail as points" option. It doesn't seem too promising. --- interface/src/Menu.cpp | 2 - interface/src/Menu.h | 1 - interface/src/MetavoxelSystem.cpp | 240 +++++------------------------- interface/src/MetavoxelSystem.h | 15 -- 4 files changed, 34 insertions(+), 224 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 5e375dc6be..77009da18b 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -426,8 +426,6 @@ Menu::Menu() : QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels"); addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false, Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData())); - addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::LowerDetailAsPoints, 0, false, - Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData())); QMenu* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 11e1131da4..67a4163c67 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -414,7 +414,6 @@ namespace MenuOption { const QString Log = "Log"; const QString Logout = "Logout"; const QString LowVelocityFilter = "Low Velocity Filter"; - const QString LowerDetailAsPoints = "Lower Detail as Points"; const QString MetavoxelEditor = "Metavoxel Editor..."; const QString Metavoxels = "Metavoxels"; const QString Mirror = "Mirror"; diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 2d4e9e7459..10a211f61b 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -640,63 +640,6 @@ void PointBuffer::render(bool cursor) { _buffer.release(); } -VoxelPointBuffer::VoxelPointBuffer(const BufferPointVector& points, const QVector& hermite) : - PointBuffer(points), - _hermite(hermite), - _hermiteCount(hermite.size()) { -} - -static void renderHermiteData(QVector& hermite, int hermiteCount, QOpenGLBuffer& hermiteBuffer) { - if (hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { - if (!hermiteBuffer.isCreated()) { - hermiteBuffer.create(); - hermiteBuffer.bind(); - hermiteBuffer.allocate(hermite.constData(), hermite.size() * sizeof(glm::vec3)); - hermite.clear(); - - } else { - hermiteBuffer.bind(); - } - - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - - glVertexPointer(3, GL_FLOAT, 0, 0); - - Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glNormal3f(0.0f, 1.0f, 0.0f); - - glLineWidth(2.0f); - - glDrawArrays(GL_LINES, 0, hermiteCount); - - glLineWidth(1.0f); - - DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); - - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - hermiteBuffer.release(); - } -} - -void VoxelPointBuffer::render(bool cursor) { - DefaultMetavoxelRendererImplementation::getPointProgram().bind(); - - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); - - PointBuffer::render(cursor); - - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); - - DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); - - renderHermiteData(_hermite, _hermiteCount, _hermiteBuffer); -} - const int HeightfieldBuffer::HEIGHT_BORDER = 1; const int HeightfieldBuffer::SHARED_EDGE = 1; const int HeightfieldBuffer::HEIGHT_EXTENSION = 2 * HeightfieldBuffer::HEIGHT_BORDER + HeightfieldBuffer::SHARED_EDGE; @@ -1175,7 +1118,38 @@ void VoxelBuffer::render(bool cursor) { _vertexBuffer.release(); _indexBuffer.release(); - renderHermiteData(_hermite, _hermiteCount, _hermiteBuffer); + if (_hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { + if (!_hermiteBuffer.isCreated()) { + _hermiteBuffer.create(); + _hermiteBuffer.bind(); + _hermiteBuffer.allocate(_hermite.constData(), _hermite.size() * sizeof(glm::vec3)); + _hermite.clear(); + + } else { + _hermiteBuffer.bind(); + } + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + glVertexPointer(3, GL_FLOAT, 0, 0); + + Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glNormal3f(0.0f, 1.0f, 0.0f); + + glLineWidth(1.0f); + + glDrawArrays(GL_LINES, 0, _hermiteCount); + + DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + _hermiteBuffer.release(); + } } BufferDataAttribute::BufferDataAttribute(const QString& name) : @@ -1644,14 +1618,12 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { if (!info.isLeaf) { return DEFAULT_ORDER; } - const int EDGES_PER_CUBE = 12; - BufferData* buffer = NULL; VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue(); VoxelMaterialDataPointer material = info.inputValues.at(1).getInlineValue(); VoxelHermiteDataPointer hermite = info.inputValues.at(2).getInlineValue(); - if (color && hermite && (material || !Menu::getInstance()->isOptionChecked(MenuOption::LowerDetailAsPoints))) { + if (color && hermite) { QVector vertices; QVector indices; QVector hermiteSegments; @@ -1686,6 +1658,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { QVector planeIndices(expanded * expanded); QVector lastPlaneIndices(expanded * expanded); + const int EDGES_PER_CUBE = 12; EdgeCrossing crossings[EDGES_PER_CUBE]; float highest = size - 1.0f; @@ -2187,151 +2160,6 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } buffer = new VoxelBuffer(vertices, indices, hermiteSegments, material ? material->getMaterials() : QVector()); - - } else if (color && hermite) { - BufferPointVector points; - QVector hermiteSegments; - - const QVector& colorContents = color->getContents(); - const QVector& hermiteContents = hermite->getContents(); - int size = color->getSize(); - int area = size * size; - int limit = size - 1; - - const QRgb* colorZ = colorContents.constData(); - int offset3 = size + 1; - int offset5 = area + 1; - int offset6 = area + size; - int offset7 = offset6 + 1; - const int MAX_ALPHA_TOTAL = MetavoxelNode::CHILD_COUNT * EIGHT_BIT_MAXIMUM; - float step = info.size / limit; - glm::vec4 minimum(info.minimum.x + step * 0.5f, info.minimum.y + step * 0.5f, info.minimum.z + step * 0.5f, 0.0f); - - const QRgb* hermiteData = hermiteContents.constData(); - int hermiteStride = hermite->getSize() * VoxelHermiteData::EDGE_COUNT; - int hermiteArea = hermiteStride * hermite->getSize(); - bool displayHermite = Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData); - - EdgeCrossing crossings[EDGES_PER_CUBE]; - - for (int z = 0; z < limit; z++) { - const QRgb* colorY = colorZ; - for (int y = 0; y < limit; y++) { - const QRgb* colorX = colorY; - for (int x = 0; x < limit; x++) { - QRgb c0 = colorX[0], c1 = colorX[1], c2 = colorX[size], c3 = colorX[offset3], c4 = colorX[area], - c5 = colorX[offset5], c6 = colorX[offset6], c7 = colorX[offset7]; - colorX++; - int a0 = qAlpha(c0), a1 = qAlpha(c1), a2 = qAlpha(c2), a3 = qAlpha(c3), - a4 = qAlpha(c4), a5 = qAlpha(c5), a6 = qAlpha(c6), a7 = qAlpha(c7); - int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7; - if (alphaTotal == 0 || alphaTotal == MAX_ALPHA_TOTAL) { - continue; - } - const QRgb* hermiteBase = hermiteData + z * hermiteArea + y * hermiteStride + - x * VoxelHermiteData::EDGE_COUNT; - int crossingCount = 0; - if (a0 != a1) { - QRgb hermite = hermiteBase[0]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f); - crossing.normal = unpackNormal(hermite); - } - if (a0 != a2) { - QRgb hermite = hermiteBase[1]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); - crossing.normal = unpackNormal(hermite); - } - if (a0 != a4) { - QRgb hermite = hermiteBase[2]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - crossing.normal = unpackNormal(hermite); - } - if (a1 != a3) { - QRgb hermite = hermiteBase[VoxelHermiteData::EDGE_COUNT + 1]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); - crossing.normal = unpackNormal(hermite); - } - if (a1 != a5) { - QRgb hermite = hermiteBase[VoxelHermiteData::EDGE_COUNT + 2]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - crossing.normal = unpackNormal(hermite); - } - if (a2 != a3) { - QRgb hermite = hermiteBase[hermiteStride]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f); - crossing.normal = unpackNormal(hermite); - } - if (a2 != a6) { - QRgb hermite = hermiteBase[hermiteStride + 2]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - crossing.normal = unpackNormal(hermite); - } - if (a3 != a7) { - QRgb hermite = hermiteBase[hermiteStride + VoxelHermiteData::EDGE_COUNT + 2]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - crossing.normal = unpackNormal(hermite); - } - if (a4 != a5) { - QRgb hermite = hermiteBase[hermiteArea]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f); - crossing.normal = unpackNormal(hermite); - } - if (a4 != a6) { - QRgb hermite = hermiteBase[hermiteArea + 1]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); - crossing.normal = unpackNormal(hermite); - } - if (a5 != a7) { - QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); - crossing.normal = unpackNormal(hermite); - } - if (a6 != a7) { - QRgb hermite = hermiteBase[hermiteArea + hermiteStride]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f); - crossing.normal = unpackNormal(hermite); - } - glm::vec3 normal; - glm::vec3 position; - for (int i = 0; i < crossingCount; i++) { - const EdgeCrossing& crossing = crossings[i]; - position += crossing.point; - normal += crossing.normal; - if (displayHermite) { - glm::vec3 base = glm::vec3(minimum) + (glm::vec3(x, y, z) + crossing.point) * step; - hermiteSegments.append(base); - hermiteSegments.append(base + crossing.normal * step); - } - } - normal = safeNormalize(normal); - BufferPoint point = { minimum + (glm::vec4(x, y, z, 1.0f) + - glm::vec4(position / (float)crossingCount, 0.0f)) * step, - { (quint8)((qRed(c0) * a0 + qRed(c1) * a1 + qRed(c2) * a2 + qRed(c3) * a3 + qRed(c4) * a4 + - qRed(c5) * a5 + qRed(c6) * a6 + qRed(c7) * a7) / alphaTotal), - (quint8)((qGreen(c0) * a0 + qGreen(c1) * a1 + qGreen(c2) * a2 + qGreen(c3) * a3 + qGreen(c4) * a4 + - qGreen(c5) * a5 + qGreen(c6) * a6 + qGreen(c7) * a7) / alphaTotal), - (quint8)((qBlue(c0) * a0 + qBlue(c1) * a1 + qBlue(c2) * a2 + qBlue(c3) * a3 + qBlue(c4) * a4 + - qBlue(c5) * a5 + qBlue(c6) * a6 + qBlue(c7) * a7) / alphaTotal) }, - { (quint8)(normal.x * 127.0f), (quint8)(normal.y * 127.0f), (quint8)(normal.z * 127.0f) } }; - points.append(point); - } - colorY += size; - } - colorZ += area; - } - buffer = new VoxelPointBuffer(points, hermiteSegments); } BufferDataPointer pointer(buffer); info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index e8987a3f5e..52706aab56 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -146,21 +146,6 @@ private: int _pointCount; }; -/// Contains the information necessary to render a group of voxels as points. -class VoxelPointBuffer : public PointBuffer { -public: - - VoxelPointBuffer(const BufferPointVector& points, const QVector& hermite); - - virtual void render(bool cursor = false); - -private: - - QVector _hermite; - int _hermiteCount; - QOpenGLBuffer _hermiteBuffer; -}; - /// Contains the information necessary to render a heightfield block. class HeightfieldBuffer : public BufferData { public: