From 9fc0abe2b3c37925fc357a49c9e7d3929e702957 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 6 Oct 2014 17:30:28 -0700 Subject: [PATCH 01/56] 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 02/56] 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 03/56] 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 fa58f53bff991135441ff61e6f7819b6ce3ef491 Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 8 Oct 2014 01:28:24 +0200 Subject: [PATCH 04/56] remove font settings for chat entry --- interface/ui/chatWindow.ui | 9 --------- 1 file changed, 9 deletions(-) diff --git a/interface/ui/chatWindow.ui b/interface/ui/chatWindow.ui index 4120515b3d..2670d05d5e 100644 --- a/interface/ui/chatWindow.ui +++ b/interface/ui/chatWindow.ui @@ -225,15 +225,6 @@ border-color: palette(dark); border-style: solid; border-left-width: 1px; borde 60 - - - Helvetica,Arial,sans-serif - 14 - - - - - QFrame::NoFrame From 04b628bede3c51f180819d2190ef773a23a94c60 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 7 Oct 2014 16:44:55 -0700 Subject: [PATCH 05/56] 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 54ad9477e7cd524a6215b4f29bc42ae8081e081f Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 8 Oct 2014 03:12:53 +0200 Subject: [PATCH 06/56] Add style to chat entry --- interface/ui/chatWindow.ui | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/ui/chatWindow.ui b/interface/ui/chatWindow.ui index 2670d05d5e..fa75ea9be8 100644 --- a/interface/ui/chatWindow.ui +++ b/interface/ui/chatWindow.ui @@ -225,6 +225,10 @@ border-color: palette(dark); border-style: solid; border-left-width: 1px; borde 60 + + font-family: Arial; +font-size: 14px; + QFrame::NoFrame From f4b9ccbceb5cc1d590134d247fa71647a38c5a94 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 7 Oct 2014 21:51:46 -0700 Subject: [PATCH 07/56] remove unused camera functions --- interface/src/Application.cpp | 2 +- interface/src/Camera.cpp | 46 +++-------------------------------- interface/src/Camera.h | 27 -------------------- 3 files changed, 5 insertions(+), 70 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 215848b355..6d36d06ee3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2962,7 +2962,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { } } - bool mirrorMode = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR); + bool mirrorMode = (whichCamera.getMode() == CAMERA_MODE_MIRROR); { PerformanceTimer perfTimer("avatars"); _avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE, diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 4a924b4ec3..762fb1a3f6 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -29,8 +29,8 @@ const float CAMERA_INDEPENDENT_MODE_DISTANCE = 0.0f; const float CAMERA_INDEPENDENT_MODE_TIGHTNESS = 100.0f; const float CAMERA_THIRD_PERSON_MODE_UP_SHIFT = -0.2f; -const float CAMERA_THIRD_PERSON_MODE_DISTANCE = 1.5f; -const float CAMERA_THIRD_PERSON_MODE_TIGHTNESS = 8.0f; +const float CAMERA_THIRD_PERSON_MODE_DISTANCE = 10.5f; +const float CAMERA_THIRD_PERSON_MODE_TIGHTNESS = 100.0f; const float CAMERA_MIRROR_MODE_UP_SHIFT = 0.0f; const float CAMERA_MIRROR_MODE_DISTANCE = 0.17f; @@ -61,9 +61,7 @@ Camera::Camera() : _modeShift(1.0f), _linearModeShift(0.0f), _modeShiftPeriod(1.0f), - _scale(1.0f), - _lookingAt(0.0f, 0.0f, 0.0f), - _isKeepLookingAt(false) + _scale(1.0f) { } @@ -99,11 +97,6 @@ void Camera::updateFollowMode(float deltaTime) { t = 1.0f; } - // handle keepLookingAt - if (_isKeepLookingAt) { - lookAt(_lookingAt); - } - // Update position and rotation, setting directly if tightness is 0.0 if (_needsToInitialize || (_tightness == 0.0f)) { _rotation = _targetRotation; @@ -167,13 +160,7 @@ void Camera::setMode(CameraMode m) { } void Camera::setTargetPosition(const glm::vec3& t) { - _targetPosition = t; - - // handle keepLookingAt - if (_isKeepLookingAt) { - lookAt(_lookingAt); - } - + _targetPosition = t; } void Camera::setTargetRotation( const glm::quat& targetRotation ) { @@ -226,36 +213,11 @@ bool Camera::getFrustumNeedsReshape() const { return _frustumNeedsReshape; } -// call this when deciding whether to render the head or not -CameraMode Camera::getInterpolatedMode() const { - const float SHIFT_THRESHOLD_INTO_FIRST_PERSON = 0.7f; - const float SHIFT_THRESHOLD_OUT_OF_FIRST_PERSON = 0.6f; - if ((_mode == CAMERA_MODE_FIRST_PERSON && _linearModeShift < SHIFT_THRESHOLD_INTO_FIRST_PERSON) || - (_prevMode == CAMERA_MODE_FIRST_PERSON && _linearModeShift < SHIFT_THRESHOLD_OUT_OF_FIRST_PERSON)) { - return _prevMode; - } - return _mode; -} - // call this after reshaping the view frustum void Camera::setFrustumWasReshaped() { _frustumNeedsReshape = false; } -void Camera::lookAt(const glm::vec3& lookAt) { - glm::vec3 up = IDENTITY_UP; - glm::mat4 lookAtMatrix = glm::lookAt(_targetPosition, lookAt, up); - glm::quat rotation = glm::quat_cast(lookAtMatrix); - rotation.w = -rotation.w; // Rosedale approved - setTargetRotation(rotation); -} - -void Camera::keepLookingAt(const glm::vec3& point) { - lookAt(point); - _isKeepLookingAt = true; - _lookingAt = point; -} - CameraScriptableObject::CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum) : _camera(camera), _viewFrustum(viewFrustum) { diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 2bbbf0e751..ab229b7ef5 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -67,21 +67,8 @@ public: const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; } float getScale() const { return _scale; } - CameraMode getInterpolatedMode() const; - bool getFrustumNeedsReshape() const; // call to find out if the view frustum needs to be reshaped void setFrustumWasReshaped(); // call this after reshaping the view frustum. - - // These only work on independent cameras - /// one time change to what the camera is looking at - void lookAt(const glm::vec3& value); - - /// fix what the camera is looking at, and keep the camera looking at this even if position changes - void keepLookingAt(const glm::vec3& value); - - /// stops the keep looking at feature, doesn't change what's being looked at, but will stop camera from - /// continuing to update it's orientation to keep looking at the item - void stopLooking() { _isKeepLookingAt = false; } private: @@ -113,9 +100,6 @@ private: float _linearModeShift; float _modeShiftPeriod; float _scale; - - glm::vec3 _lookingAt; - bool _isKeepLookingAt; void updateFollowMode(float deltaTime); }; @@ -137,17 +121,6 @@ public slots: void setOrientation(const glm::quat& value) { _camera->setTargetRotation(value); } glm::quat getOrientation() const { return _camera->getRotation(); } - // These only work on independent cameras - /// one time change to what the camera is looking at - void lookAt(const glm::vec3& value) { _camera->lookAt(value);} - - /// fix what the camera is looking at, and keep the camera looking at this even if position changes - void keepLookingAt(const glm::vec3& value) { _camera->keepLookingAt(value);} - - /// stops the keep looking at feature, doesn't change what's being looked at, but will stop camera from - /// continuing to update it's orientation to keep looking at the item - void stopLooking() { _camera->stopLooking();} - PickRay computePickRay(float x, float y); private: From c4c9f4820d6529a1f3420cde487b92f576b051de Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 8 Oct 2014 10:00:47 -0700 Subject: [PATCH 08/56] First pass at simplifying camera, removes interpolation to target and setbacks --- interface/src/Application.cpp | 62 +++++----- interface/src/Camera.cpp | 150 ++---------------------- interface/src/Camera.h | 41 +------ interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/devices/OculusManager.cpp | 12 +- 5 files changed, 48 insertions(+), 219 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6d36d06ee3..3fbf489738 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -605,37 +605,37 @@ void Application::paintGL() { glEnable(GL_LINE_SMOOTH); if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - _myCamera.setTightness(0.0f); // In first person, camera follows (untweaked) head exactly without delay if (!OculusManager::isConnected()) { - _myCamera.setTargetPosition(_myAvatar->getHead()->getEyePosition()); - _myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation()); + _myCamera.setPosition(_myAvatar->getHead()->getEyePosition()); + _myCamera.setRotation(_myAvatar->getHead()->getCameraOrientation()); } // OculusManager::display() updates camera position and rotation a bit further on. } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { //Note, the camera distance is set in Camera::setMode() so we dont have to do it here. - _myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing - _myCamera.setTargetPosition(_myAvatar->getUprightHeadPosition()); + float thirdPersonCameraDistance = MIRROR_FULLSCREEN_DISTANCE * _scaleMirror * 10.0f; + _myCamera.setPosition(_myAvatar->getUprightHeadPosition() + + _myAvatar->getOrientation() * glm::vec3(0,0,1) * thirdPersonCameraDistance); if (OculusManager::isConnected()) { - _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation()); + _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation()); } else { - _myCamera.setTargetRotation(_myAvatar->getHead()->getOrientation()); + _myCamera.setRotation(_myAvatar->getHead()->getOrientation()); } } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - _myCamera.setTightness(0.0f); //Only behave like a true mirror when in the OR if (OculusManager::isConnected()) { - _myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setTargetPosition(_myAvatar->getHead()->getEyePosition() + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0)); + _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(_myAvatar->getHead()->getEyePosition() + + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + + _myAvatar->getOrientation() * glm::vec3(0,0,-1) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } else { - _myCamera.setTightness(0.0f); glm::vec3 eyePosition = _myAvatar->getHead()->getEyePosition(); float headHeight = eyePosition.y - _myAvatar->getPosition().y; - _myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - _myCamera.setTargetPosition(_myAvatar->getPosition() + glm::vec3(0, headHeight + (_raiseMirror * _myAvatar->getScale()), 0)); - _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(_myAvatar->getPosition() + + glm::vec3(0, headHeight + (_raiseMirror * _myAvatar->getScale()), 0) + + _myAvatar->getOrientation() * glm::vec3(0,0,-1) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); } } @@ -659,11 +659,14 @@ void Application::paintGL() { ViewFrustumOffset viewFrustumOffset = Menu::getInstance()->getViewFrustumOffset(); // set the camera to third-person view but offset so we can see the frustum - _viewFrustumOffsetCamera.setTargetPosition(_myCamera.getTargetPosition()); - _viewFrustumOffsetCamera.setTargetRotation(_myCamera.getTargetRotation() * glm::quat(glm::radians(glm::vec3( + _viewFrustumOffsetCamera.setPosition(_myCamera.getPosition()); + _viewFrustumOffsetCamera.setRotation(_myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( viewFrustumOffset.pitch, viewFrustumOffset.yaw, viewFrustumOffset.roll)))); - _viewFrustumOffsetCamera.setUpShift(viewFrustumOffset.up); - _viewFrustumOffsetCamera.setDistance(viewFrustumOffset.distance); + // TODO: PHILIP + // Fix Frustum offset and up + //_viewFrustumOffsetCamera.setUpShift(viewFrustumOffset.up); + //_viewFrustumOffsetCamera.setDistance(viewFrustumOffset.distance); + _viewFrustumOffsetCamera.initialize(); // force immediate snap to ideal position and orientation _viewFrustumOffsetCamera.update(1.f/_fps); whichCamera = &_viewFrustumOffsetCamera; @@ -1779,10 +1782,8 @@ void Application::init() { // TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager _avatarManager.init(); _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); - _myCamera.setModeShiftPeriod(1.0f); _mirrorCamera.setMode(CAMERA_MODE_MIRROR); - _mirrorCamera.setModeShiftPeriod(0.0f); OculusManager::connect(); if (OculusManager::isConnected()) { @@ -2122,17 +2123,14 @@ void Application::cameraMenuChanged() { if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { _myCamera.setMode(CAMERA_MODE_MIRROR); - _myCamera.setModeShiftPeriod(0.0f); } } else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); - _myCamera.setModeShiftPeriod(modeShiftPeriod); } } else { if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); - _myCamera.setModeShiftPeriod(modeShiftPeriod); } } } @@ -3101,30 +3099,30 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { bool eyeRelativeCamera = false; if (billboard) { _mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees - _mirrorCamera.setDistance(BILLBOARD_DISTANCE * _myAvatar->getScale()); - _mirrorCamera.setTargetPosition(_myAvatar->getPosition()); + _mirrorCamera.setPosition(_myAvatar->getPosition() + + _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, 1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale()); } else if (_rearMirrorTools->getZoomLevel() == BODY) { _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees - _mirrorCamera.setDistance(MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); - _mirrorCamera.setTargetPosition(_myAvatar->getChestPosition()); + _mirrorCamera.setPosition(_myAvatar->getChestPosition() + + _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, 1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); } else { // HEAD zoom level _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees - _mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); if (_myAvatar->getSkeletonModel().isActive() && _myAvatar->getHead()->getFaceModel().isActive()) { // as a hack until we have a better way of dealing with coordinate precision issues, reposition the // face/body so that the average eye position lies at the origin eyeRelativeCamera = true; - _mirrorCamera.setTargetPosition(glm::vec3()); + _mirrorCamera.setPosition(glm::vec3()); } else { - _mirrorCamera.setTargetPosition(_myAvatar->getHead()->getEyePosition()); + _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + + _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, 1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); } } _mirrorCamera.setAspectRatio((float)region.width() / region.height()); - _mirrorCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + _mirrorCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); _mirrorCamera.update(1.0f/_fps); // set the bounds of rear mirror view diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 762fb1a3f6..79d66568bf 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -20,95 +20,21 @@ #include "Util.h" #include "devices/OculusManager.h" -const float CAMERA_FIRST_PERSON_MODE_UP_SHIFT = 0.0f; -const float CAMERA_FIRST_PERSON_MODE_DISTANCE = 0.0f; -const float CAMERA_FIRST_PERSON_MODE_TIGHTNESS = 100.0f; - -const float CAMERA_INDEPENDENT_MODE_UP_SHIFT = 0.0f; -const float CAMERA_INDEPENDENT_MODE_DISTANCE = 0.0f; -const float CAMERA_INDEPENDENT_MODE_TIGHTNESS = 100.0f; - -const float CAMERA_THIRD_PERSON_MODE_UP_SHIFT = -0.2f; -const float CAMERA_THIRD_PERSON_MODE_DISTANCE = 10.5f; -const float CAMERA_THIRD_PERSON_MODE_TIGHTNESS = 100.0f; - -const float CAMERA_MIRROR_MODE_UP_SHIFT = 0.0f; -const float CAMERA_MIRROR_MODE_DISTANCE = 0.17f; -const float CAMERA_MIRROR_MODE_TIGHTNESS = 100.0f; - Camera::Camera() : _needsToInitialize(true), _mode(CAMERA_MODE_THIRD_PERSON), - _prevMode(CAMERA_MODE_THIRD_PERSON), - _frustumNeedsReshape(true), _position(0.0f, 0.0f, 0.0f), - _idealPosition(0.0f, 0.0f, 0.0f), - _targetPosition(0.0f, 0.0f, 0.0f), _fieldOfView(DEFAULT_FIELD_OF_VIEW_DEGREES), _aspectRatio(16.0f/9.0f), _nearClip(DEFAULT_NEAR_CLIP), // default _farClip(DEFAULT_FAR_CLIP), // default - _upShift(0.0f), - _distance(0.0f), - _tightness(10.0f), // default - _previousUpShift(0.0f), - _previousDistance(0.0f), - _previousTightness(0.0f), - _newUpShift(0.0f), - _newDistance(0.0f), - _newTightness(0.0f), - _modeShift(1.0f), - _linearModeShift(0.0f), - _modeShiftPeriod(1.0f), _scale(1.0f) { } -void Camera::update(float deltaTime) { - - if (_mode != CAMERA_MODE_NULL) { - // use iterative forces to push the camera towards the target position and angle - updateFollowMode(deltaTime); - } -} - -// use iterative forces to keep the camera at the desired position and angle -void Camera::updateFollowMode(float deltaTime) { - if (_linearModeShift < 1.0f) { - _linearModeShift += deltaTime / _modeShiftPeriod; - if (_needsToInitialize || _linearModeShift > 1.0f) { - _linearModeShift = 1.0f; - _modeShift = 1.0f; - _upShift = _newUpShift; - _distance = _newDistance; - _tightness = _newTightness; - } else { - _modeShift = ONE_HALF - ONE_HALF * cosf(_linearModeShift * PI ); - _upShift = _previousUpShift * (1.0f - _modeShift) + _newUpShift * _modeShift; - _distance = _previousDistance * (1.0f - _modeShift) + _newDistance * _modeShift; - _tightness = _previousTightness * (1.0f - _modeShift) + _newTightness * _modeShift; - } - } - - // derive t from tightness - float t = _tightness * _modeShift * deltaTime; - if (t > 1.0f) { - t = 1.0f; - } - - // Update position and rotation, setting directly if tightness is 0.0 - if (_needsToInitialize || (_tightness == 0.0f)) { - _rotation = _targetRotation; - _idealPosition = _targetPosition + _scale * (_rotation * glm::vec3(0.0f, _upShift, _distance)); - _position = _idealPosition; - _needsToInitialize = false; - } else { - // pull rotation towards ideal - _rotation = safeMix(_rotation, _targetRotation, t); - _idealPosition = _targetPosition + _scale * (_rotation * glm::vec3(0.0f, _upShift, _distance)); - _position += (_idealPosition - _position) * t; - } +void Camera::update(float deltaTime) { + return; } float Camera::getFarClip() const { @@ -117,106 +43,46 @@ float Camera::getFarClip() const { : std::numeric_limits::max() - 1; } -void Camera::setModeShiftPeriod (float period) { - const float MIN_PERIOD = 0.001f; - const float MAX_PERIOD = 3.0f; - _modeShiftPeriod = glm::clamp(period, MIN_PERIOD, MAX_PERIOD); - - // if a zero period was requested, we clearly want to snap immediately to the target - if (period == 0.0f) { - update(MAX_PERIOD); - } -} - -void Camera::setMode(CameraMode m) { - - _prevMode = _mode; +void Camera::setMode(CameraMode m) { _mode = m; - _modeShift = 0.0; - _linearModeShift = 0.0; - - _previousUpShift = _upShift; - _previousDistance = _distance; - _previousTightness = _tightness; - - if (_mode == CAMERA_MODE_THIRD_PERSON) { - _newUpShift = CAMERA_THIRD_PERSON_MODE_UP_SHIFT; - _newDistance = CAMERA_THIRD_PERSON_MODE_DISTANCE; - _newTightness = CAMERA_THIRD_PERSON_MODE_TIGHTNESS; - } else if (_mode == CAMERA_MODE_FIRST_PERSON) { - _newUpShift = CAMERA_FIRST_PERSON_MODE_UP_SHIFT; - _newDistance = CAMERA_FIRST_PERSON_MODE_DISTANCE; - _newTightness = CAMERA_FIRST_PERSON_MODE_TIGHTNESS; - } else if (_mode == CAMERA_MODE_MIRROR) { - _newUpShift = CAMERA_MIRROR_MODE_UP_SHIFT; - _newDistance = CAMERA_MIRROR_MODE_DISTANCE; - _newTightness = CAMERA_MIRROR_MODE_TIGHTNESS; - } else if (_mode == CAMERA_MODE_INDEPENDENT) { - _newUpShift = CAMERA_INDEPENDENT_MODE_UP_SHIFT; - _newDistance = CAMERA_INDEPENDENT_MODE_DISTANCE; - _newTightness = CAMERA_INDEPENDENT_MODE_TIGHTNESS; - - } } -void Camera::setTargetPosition(const glm::vec3& t) { - _targetPosition = t; -} - -void Camera::setTargetRotation( const glm::quat& targetRotation ) { - _targetRotation = targetRotation; -} void Camera::setFieldOfView(float f) { _fieldOfView = f; - _frustumNeedsReshape = true; } void Camera::setAspectRatio(float a) { - _aspectRatio = a; - _frustumNeedsReshape = true; + _aspectRatio = a; } void Camera::setNearClip(float n) { - _nearClip = n; - _frustumNeedsReshape = true; + _nearClip = n; } void Camera::setFarClip(float f) { - _farClip = f; - _frustumNeedsReshape = true; + _farClip = f; } void Camera::setEyeOffsetPosition(const glm::vec3& p) { _eyeOffsetPosition = p; - _frustumNeedsReshape = true; } void Camera::setEyeOffsetOrientation(const glm::quat& o) { _eyeOffsetOrientation = o; - _frustumNeedsReshape = true; + } void Camera::setScale(float s) { _scale = s; _needsToInitialize = true; - _frustumNeedsReshape = true; + } void Camera::initialize() { _needsToInitialize = true; - _modeShift = 0.0; } -// call to find out if the view frustum needs to be reshaped -bool Camera::getFrustumNeedsReshape() const { - return _frustumNeedsReshape; -} - -// call this after reshaping the view frustum -void Camera::setFrustumWasReshaped() { - _frustumNeedsReshape = false; -} CameraScriptableObject::CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum) : _camera(camera), _viewFrustum(viewFrustum) diff --git a/interface/src/Camera.h b/interface/src/Camera.h index ab229b7ef5..ee4930272d 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -35,14 +35,9 @@ public: void initialize(); // instantly put the camera at the ideal position and rotation. void update( float deltaTime ); - - void setUpShift(float u) { _upShift = u; } - void setDistance(float d) { _distance = d; } + void setPosition(const glm::vec3& p) { _position = p; } - void setTargetPosition(const glm::vec3& t); - void setTightness(float t) { _tightness = t; } - void setTargetRotation(const glm::quat& rotation); - void setModeShiftPeriod(float r); + void setRotation(const glm::quat& rotation) { _rotation = rotation; }; void setMode(CameraMode m); void setFieldOfView(float f); void setAspectRatio(float a); @@ -55,10 +50,6 @@ public: const glm::vec3& getPosition() const { return _position; } const glm::quat& getRotation() const { return _rotation; } CameraMode getMode() const { return _mode; } - float getModeShiftPeriod() const { return _modeShiftPeriod; } - float getDistance() const { return _distance; } - const glm::vec3& getTargetPosition() const { return _targetPosition; } - const glm::quat& getTargetRotation() const { return _targetRotation; } float getFieldOfView() const { return _fieldOfView; } float getAspectRatio() const { return _aspectRatio; } float getNearClip() const { return _scale * _nearClip; } @@ -67,18 +58,11 @@ public: const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; } float getScale() const { return _scale; } - bool getFrustumNeedsReshape() const; // call to find out if the view frustum needs to be reshaped - void setFrustumWasReshaped(); // call this after reshaping the view frustum. - private: bool _needsToInitialize; CameraMode _mode; - CameraMode _prevMode; - bool _frustumNeedsReshape; glm::vec3 _position; - glm::vec3 _idealPosition; - glm::vec3 _targetPosition; float _fieldOfView; // degrees float _aspectRatio; float _nearClip; @@ -86,22 +70,8 @@ private: glm::vec3 _eyeOffsetPosition; glm::quat _eyeOffsetOrientation; glm::quat _rotation; - glm::quat _targetRotation; - float _upShift; - float _distance; - float _tightness; - float _previousUpShift; - float _previousDistance; - float _previousTightness; - float _newUpShift; - float _newDistance; - float _newTightness; - float _modeShift; - float _linearModeShift; - float _modeShiftPeriod; + float _scale; - - void updateFollowMode(float deltaTime); }; @@ -113,12 +83,11 @@ public: public slots: QString getMode() const; void setMode(const QString& mode); - void setModeShiftPeriod(float r) {_camera->setModeShiftPeriod(r); } - void setPosition(const glm::vec3& value) { _camera->setTargetPosition(value);} + void setPosition(const glm::vec3& value) { _camera->setPosition(value);} glm::vec3 getPosition() const { return _camera->getPosition(); } - void setOrientation(const glm::quat& value) { _camera->setTargetRotation(value); } + void setOrientation(const glm::quat& value) { _camera->setRotation(value); } glm::quat getOrientation() const { return _camera->getRotation(); } PickRay computePickRay(float x, float y); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 087d670760..c0ce474d16 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1126,7 +1126,7 @@ void MyAvatar::renderBody(RenderMode renderMode, bool postLighting, float glowLe // Render head so long as the camera isn't inside it const Camera *camera = Application::getInstance()->getCamera(); - const glm::vec3 cameraPos = camera->getPosition() + (camera->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) * camera->getDistance(); + const glm::vec3 cameraPos = camera->getPosition(); if (shouldRenderHead(cameraPos, renderMode)) { getHead()->render(1.0f, modelRenderMode, postLighting); diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 65518b839c..eb48e3d463 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -311,10 +311,6 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p ovrPosef eyeRenderPose[ovrEye_Count]; - _camera->setTightness(0.0f); // In first person, camera follows (untweaked) head exactly without delay - _camera->setDistance(0.0f); - _camera->setUpShift(0.0f); - glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -348,8 +344,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p orientation.z = eyeRenderPose[eye].Orientation.z; orientation.w = eyeRenderPose[eye].Orientation.w; - _camera->setTargetRotation(bodyOrientation * orientation); - _camera->setTargetPosition(position + trackerPosition); + _camera->setRotation(bodyOrientation * orientation); + _camera->setPosition(position + trackerPosition); // Store the latest left and right eye render locations for things that need to know glm::vec3 thisEyePosition = position + trackerPosition + @@ -413,8 +409,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p glBindTexture(GL_TEXTURE_2D, 0); // Update camera for use by rest of Interface. - whichCamera.setTargetPosition((_leftEyePosition + _rightEyePosition) / 2.f); - whichCamera.setTargetRotation(_camera->getTargetRotation()); + whichCamera.setPosition((_leftEyePosition + _rightEyePosition) / 2.f); + whichCamera.setRotation(_camera->getRotation()); #endif } From 2636fdd3cb1675a1a080f345849c56948f1c8765 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 8 Oct 2014 10:23:45 -0700 Subject: [PATCH 09/56] Fix third person camera distance --- interface/src/Application.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3fbf489738..1c06ad17d2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -612,10 +612,9 @@ void Application::paintGL() { // OculusManager::display() updates camera position and rotation a bit further on. } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - //Note, the camera distance is set in Camera::setMode() so we dont have to do it here. - float thirdPersonCameraDistance = MIRROR_FULLSCREEN_DISTANCE * _scaleMirror * 10.0f; + static const float THIRD_PERSON_CAMERA_DISTANCE = 1.5f; _myCamera.setPosition(_myAvatar->getUprightHeadPosition() + - _myAvatar->getOrientation() * glm::vec3(0,0,1) * thirdPersonCameraDistance); + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, 1.0f) * THIRD_PERSON_CAMERA_DISTANCE * _myAvatar->getScale()); if (OculusManager::isConnected()) { _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation()); } else { From 00c182ad7b8223d70721e3cf8d55f01966d6d60d Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 8 Oct 2014 10:51:06 -0700 Subject: [PATCH 10/56] Fix full screen mirror keyboard controls --- interface/src/Application.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1c06ad17d2..31a4ae28fd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -627,14 +627,14 @@ void Application::paintGL() { _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); _myCamera.setPosition(_myAvatar->getHead()->getEyePosition() + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + - _myAvatar->getOrientation() * glm::vec3(0,0,-1) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } else { - glm::vec3 eyePosition = _myAvatar->getHead()->getEyePosition(); - float headHeight = eyePosition.y - _myAvatar->getPosition().y; - _myCamera.setPosition(_myAvatar->getPosition() + - glm::vec3(0, headHeight + (_raiseMirror * _myAvatar->getScale()), 0) + - _myAvatar->getOrientation() * glm::vec3(0,0,-1) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(_myAvatar->getHead()->getEyePosition() + + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } } From 12349a885400c229800f25cda3e3c5e893fe076f Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 8 Oct 2014 10:59:46 -0700 Subject: [PATCH 11/56] Fix rearview mirror camera --- interface/src/Application.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 31a4ae28fd..16537ee6dc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3099,12 +3099,12 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { if (billboard) { _mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees _mirrorCamera.setPosition(_myAvatar->getPosition() + - _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, 1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale()); + _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, -1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale()); } else if (_rearMirrorTools->getZoomLevel() == BODY) { _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees _mirrorCamera.setPosition(_myAvatar->getChestPosition() + - _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, 1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); + _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); } else { // HEAD zoom level _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees @@ -3112,11 +3112,11 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { // as a hack until we have a better way of dealing with coordinate precision issues, reposition the // face/body so that the average eye position lies at the origin eyeRelativeCamera = true; - _mirrorCamera.setPosition(glm::vec3()); + _mirrorCamera.setPosition(_myAvatar->getOrientation() * glm::vec3(0.f, 0.f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); } else { _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + - _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, 1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); + _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); } } _mirrorCamera.setAspectRatio((float)region.width() / region.height()); From 17b9f4a37d23797990dc6f8e1e7421da22ee1dab Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 11:34:45 -0700 Subject: [PATCH 12/56] allow a call to Joysticks.reset to reset SDL while interface is running --- interface/src/devices/Joystick.cpp | 4 + interface/src/devices/Joystick.h | 3 + .../scripting/JoystickScriptingInterface.cpp | 91 ++++++++++++++----- .../scripting/JoystickScriptingInterface.h | 6 ++ 4 files changed, 79 insertions(+), 25 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index d220a827f1..f636e47a42 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -29,6 +29,10 @@ Joystick::Joystick(const QString& name, SDL_Joystick* sdlJoystick) : #endif Joystick::~Joystick() { + closeJoystick(); +} + +void Joystick::closeJoystick() { #ifdef HAVE_SDL SDL_JoystickClose(_sdlJoystick); #endif diff --git a/interface/src/devices/Joystick.h b/interface/src/devices/Joystick.h index 228e993204..0335bf6af3 100644 --- a/interface/src/devices/Joystick.h +++ b/interface/src/devices/Joystick.h @@ -37,6 +37,9 @@ public: void update(); + void closeJoystick(); + void setSDLJoystick(SDL_Joystick* sdlJoystick) { _sdlJoystick = sdlJoystick; } + const QString& getName() const { return _name; } const QVector& getAxes() const { return _axes; } diff --git a/interface/src/scripting/JoystickScriptingInterface.cpp b/interface/src/scripting/JoystickScriptingInterface.cpp index 1e35c11f61..87f841c494 100644 --- a/interface/src/scripting/JoystickScriptingInterface.cpp +++ b/interface/src/scripting/JoystickScriptingInterface.cpp @@ -27,17 +27,10 @@ JoystickScriptingInterface& JoystickScriptingInterface::getInstance() { JoystickScriptingInterface::JoystickScriptingInterface() : _openJoysticks(), - _availableDeviceNames() + _availableDeviceNames(), + _isInitialized(false) { -#ifdef HAVE_SDL - SDL_Init(SDL_INIT_JOYSTICK); - - int joystickCount = SDL_NumJoysticks(); - - for (int i = 0; i < joystickCount; i++) { - _availableDeviceNames << SDL_JoystickName(i); - } -#endif + reset(); } JoystickScriptingInterface::~JoystickScriptingInterface() { @@ -45,18 +38,53 @@ JoystickScriptingInterface::~JoystickScriptingInterface() { #ifdef HAVE_SDL SDL_Quit(); + _isInitialized = false; +#endif +} + +void JoystickScriptingInterface::reset() { +#ifdef HAVE_SDL + + if (_isInitialized) { + _isInitialized = false; + + // close all the open joysticks before we quit + foreach(Joystick* openJoystick, _openJoysticks) { + openJoystick->closeJoystick(); + } + + SDL_Quit(); + } + + bool initSuccess = (SDL_Init(SDL_INIT_JOYSTICK) == 0); + + if (initSuccess) { + + int joystickCount = SDL_NumJoysticks(); + + for (int i = 0; i < joystickCount; i++) { + _availableDeviceNames << SDL_JoystickName(i); + } + + foreach(const QString& joystickName, _openJoysticks.keys()) { + _openJoysticks[joystickName]->setSDLJoystick(openSDLJoystickWithName(joystickName)); + } + + _isInitialized = true; + } #endif } void JoystickScriptingInterface::update() { #ifdef HAVE_SDL - PerformanceTimer perfTimer("JoystickScriptingInterface::update"); - SDL_JoystickUpdate(); - - foreach(Joystick* joystick, _openJoysticks) { - joystick->update(); + if (_isInitialized) { + PerformanceTimer perfTimer("JoystickScriptingInterface::update"); + SDL_JoystickUpdate(); + + foreach(Joystick* joystick, _openJoysticks) { + joystick->update(); + } } - #endif } @@ -64,17 +92,13 @@ Joystick* JoystickScriptingInterface::joystickWithName(const QString& name) { Joystick* matchingJoystick = _openJoysticks.value(name); #ifdef HAVE_SDL if (!matchingJoystick) { - // we haven't opened a joystick with this name yet - enumerate our SDL devices and see if it exists - int joystickCount = SDL_NumJoysticks(); + SDL_Joystick* openSDLJoystick = openSDLJoystickWithName(name); - for (int i = 0; i < joystickCount; i++) { - if (SDL_JoystickName(i) == name) { - matchingJoystick = _openJoysticks.insert(name, new Joystick(name, SDL_JoystickOpen(i))).value(); - break; - } + if (openSDLJoystick) { + matchingJoystick = _openJoysticks.insert(name, new Joystick(name, openSDLJoystick)).value(); + } else { + qDebug() << "No matching joystick found with name" << name << "- returning NULL pointer."; } - - qDebug() << "No matching joystick found with name" << name << "- returning NULL pointer."; } #endif @@ -82,3 +106,20 @@ Joystick* JoystickScriptingInterface::joystickWithName(const QString& name) { } +#ifdef HAVE_SDL + +SDL_Joystick* JoystickScriptingInterface::openSDLJoystickWithName(const QString &name) { + // we haven't opened a joystick with this name yet - enumerate our SDL devices and see if it exists + int joystickCount = SDL_NumJoysticks(); + + for (int i = 0; i < joystickCount; i++) { + if (SDL_JoystickName(i) == name) { + return SDL_JoystickOpen(i); + break; + } + } + + return NULL; +} + +#endif diff --git a/interface/src/scripting/JoystickScriptingInterface.h b/interface/src/scripting/JoystickScriptingInterface.h index 98e38f5698..02624c70d5 100644 --- a/interface/src/scripting/JoystickScriptingInterface.h +++ b/interface/src/scripting/JoystickScriptingInterface.h @@ -31,13 +31,19 @@ public: public slots: Joystick* joystickWithName(const QString& name); + void reset(); private: +#ifdef HAVE_SDL + SDL_Joystick* openSDLJoystickWithName(const QString& name); +#endif + JoystickScriptingInterface(); ~JoystickScriptingInterface(); QMap _openJoysticks; QStringList _availableDeviceNames; + bool _isInitialized; }; #endif // hifi_JoystickScriptingInterface_h From 8e2d41f37fe79a02382ee858a3979090f8a28349 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 11:41:07 -0700 Subject: [PATCH 13/56] remove deadzone handling from Joystick class --- interface/src/devices/Joystick.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index f636e47a42..fe67eaceaa 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -42,14 +42,12 @@ void Joystick::update() { #ifdef HAVE_SDL // update our current values, emit a signal when there is a change for (int j = 0; j < getNumAxes(); j++) { - float value = glm::round(SDL_JoystickGetAxis(_sdlJoystick, j) + 0.5f) / std::numeric_limits::max(); - const float DEAD_ZONE = 0.1f; - float cleanValue = glm::abs(value) < DEAD_ZONE ? 0.0f : value; - - if (_axes[j] != cleanValue) { + float newValue = glm::round(SDL_JoystickGetAxis(_sdlJoystick, j) + 0.5f) / std::numeric_limits::max(); + + if (_axes[j] != newValue) { float oldValue = _axes[j]; - _axes[j] = cleanValue; - emit axisValueChanged(j, cleanValue, oldValue); + _axes[j] = newValue; + emit axisValueChanged(j, newValue, oldValue); } } for (int j = 0; j < getNumButtons(); j++) { From 48071bbdb39c834d42b2ae5ccc11bec6587b5606 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 8 Oct 2014 11:48:30 -0700 Subject: [PATCH 14/56] don't collide with entities with unknown IDs --- libraries/entities/src/EntityCollisionSystem.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libraries/entities/src/EntityCollisionSystem.cpp b/libraries/entities/src/EntityCollisionSystem.cpp index 4ec9912b01..7f987db9ed 100644 --- a/libraries/entities/src/EntityCollisionSystem.cpp +++ b/libraries/entities/src/EntityCollisionSystem.cpp @@ -115,6 +115,11 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { return; // bail early if this entity is to be ignored... } + // don't collide entities with unknown IDs, + if (!entityA->isKnownID()) { + return; + } + glm::vec3 penetration; EntityItem* entityB = NULL; @@ -133,6 +138,11 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { penetration = collision->_penetration; entityB = static_cast(collision->_extraData); + // don't collide entities with unknown IDs, + if (!entityB->isKnownID()) { + continue; // skip this loop pass if the entity has an unknown ID + } + // NOTE: 'penetration' is the depth that 'entityA' overlaps 'entityB'. It points from A into B. glm::vec3 penetrationInTreeUnits = penetration / (float)(TREE_SCALE); @@ -267,6 +277,12 @@ void EntityCollisionSystem::updateCollisionWithAvatars(EntityItem* entity) { } void EntityCollisionSystem::applyHardCollision(EntityItem* entity, const CollisionInfo& collisionInfo) { + + // don't collide entities with unknown IDs, + if (!entity->isKnownID()) { + return; + } + // HALTING_* params are determined using expected acceleration of gravity over some timescale. // This is a HACK for entities that bounce in a 1.0 gravitational field and should eventually be made more universal. const float HALTING_ENTITY_PERIOD = 0.0167f; // ~1/60th of a second From ce505c1b0cae9c75c76d39c34169987f100f6b48 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 12:09:40 -0700 Subject: [PATCH 15/56] add a missing HAVE_SDL wrap on setter in Joystick --- interface/src/devices/Joystick.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/devices/Joystick.h b/interface/src/devices/Joystick.h index 0335bf6af3..8343c20a04 100644 --- a/interface/src/devices/Joystick.h +++ b/interface/src/devices/Joystick.h @@ -38,7 +38,10 @@ public: void update(); void closeJoystick(); + +#ifdef HAVE_SDL void setSDLJoystick(SDL_Joystick* sdlJoystick) { _sdlJoystick = sdlJoystick; } +#endif const QString& getName() const { return _name; } From b5b82ed387c84775f985bd0fe289f1c02719c73b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 8 Oct 2014 14:05:14 -0700 Subject: [PATCH 16/56] 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 fb8c5c3bf0f6072db711e844121faedb89fe5da8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 14:52:53 -0700 Subject: [PATCH 17/56] initial styling changes to domain table --- domain-server/resources/describe-settings.json | 13 +++++++++++++ domain-server/resources/web/css/style.css | 4 ++++ domain-server/resources/web/js/settings.js | 16 ++++++---------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 8b33fede2e..04c8c5bf1f 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -59,6 +59,19 @@ "type": "password", "help": "Password used for basic HTTP authentication. Leave this blank if you do not want to change it.", "value-hidden": true + }, + { + "name": "allowed_users", + "type": "table", + "label": "Allowed Users", + "help": "A list of usernames for the High Fidelity users you want to allow into your domain. Users not found in this list will not be allowed to connect.", + "number": false, + "can_add": true, + "can_delete": true, + "key": { + "name": "username", + "label": "Username" + } } ] }, diff --git a/domain-server/resources/web/css/style.css b/domain-server/resources/web/css/style.css index 60f493593a..46e8b94a3a 100644 --- a/domain-server/resources/web/css/style.css +++ b/domain-server/resources/web/css/style.css @@ -74,3 +74,7 @@ span.port { width: 100%; margin-bottom: 15px; } + +td.buttons { + width: 14px; +} diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index d6646a87da..246a9a1705 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -280,12 +280,9 @@ $('body').on('click', '.save-button', function(e){ }); function makeTable(setting, setting_name, setting_value) { - var html = "
" - html += "
" + setting.label + "
" - html += "
" - html += "

" + setting.help + "

" - html += "
" - html += "" + var html = "" + html += "" + setting.help + "" + html += "
" // Column names html += "" @@ -297,7 +294,7 @@ function makeTable(setting, setting_name, setting_value) { html += "" // Data }) if (setting.can_delete === true || setting.can_add === true) { - html += "" // Buttons + html += "" // Buttons } html += "" @@ -329,9 +326,8 @@ function makeTable(setting, setting_name, setting_value) { if (setting.can_add === true) { html += makeTableInputs(setting) } - + html += "
" + col.label + "+/-
" - html += "
" return html; } @@ -342,7 +338,7 @@ function makeTableInputs(setting) { html += "" } html += "\ - \ + \ " _.each(setting.columns, function(col) { html += "\ From f4eddbc93b5031958d48807be1ec7fa73fac318b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 14:54:41 -0700 Subject: [PATCH 18/56] change number to numbered for domain-server settings --- domain-server/resources/describe-settings.json | 4 ++-- domain-server/resources/web/js/settings.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 04c8c5bf1f..30d843c7eb 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -65,7 +65,7 @@ "type": "table", "label": "Allowed Users", "help": "A list of usernames for the High Fidelity users you want to allow into your domain. Users not found in this list will not be allowed to connect.", - "number": false, + "numbered": false, "can_add": true, "can_delete": true, "key": { @@ -85,7 +85,7 @@ "type": "table", "label": "Zones", "help": "In this table you can define a set of zones in which you can specify various audio properties.", - "number": false, + "numbered": false, "can_add": true, "can_delete": true, "key": { diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index 246a9a1705..311a25dacd 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -302,8 +302,8 @@ function makeTable(setting, setting_name, setting_value) { var row_num = 1 _.each(setting_value, function(row, name) { html += "" - if (setting.number === true) { - html += "" + row_num + "" + if (setting.numbered === true) { + html += "" + row_num + "" } html += "" + name + "" _.each(setting.columns, function(col) { @@ -334,8 +334,8 @@ function makeTable(setting, setting_name, setting_value) { function makeTableInputs(setting) { var html = "" - if (setting.number === true) { - html += "" + if (setting.numbered === true) { + html += "" } html += "\ \ From 51afd52ffb4af3a899048994718cf580ae1a1830 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 14:56:09 -0700 Subject: [PATCH 19/56] vertically center the glyphicon for table button --- domain-server/resources/web/css/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/domain-server/resources/web/css/style.css b/domain-server/resources/web/css/style.css index 46e8b94a3a..4c365ed110 100644 --- a/domain-server/resources/web/css/style.css +++ b/domain-server/resources/web/css/style.css @@ -78,3 +78,8 @@ span.port { td.buttons { width: 14px; } + +td.buttons .glyphicon { + display: block; + text-align: center; +} From 37eff685bcefad15239fd1b71a5d91e49b235810 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 8 Oct 2014 15:11:55 -0700 Subject: [PATCH 20/56] 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: From 01bef6be6dd30ab7c31bde26eced40c9b3af54f4 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 8 Oct 2014 15:28:29 -0700 Subject: [PATCH 21/56] remove unused cameraPushback variable --- interface/src/Application.cpp | 14 ++++++-------- interface/src/Application.h | 1 - 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 16537ee6dc..c90a5ade9f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -153,7 +153,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _lastQueriedViewFrustum(), _lastQueriedTime(usecTimestampNow()), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), - _cameraPushback(0.0f), _scaleMirror(1.0f), _rotateMirror(0.0f), _raiseMirror(0.0f), @@ -658,13 +657,12 @@ void Application::paintGL() { ViewFrustumOffset viewFrustumOffset = Menu::getInstance()->getViewFrustumOffset(); // set the camera to third-person view but offset so we can see the frustum - _viewFrustumOffsetCamera.setPosition(_myCamera.getPosition()); - _viewFrustumOffsetCamera.setRotation(_myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( - viewFrustumOffset.pitch, viewFrustumOffset.yaw, viewFrustumOffset.roll)))); - // TODO: PHILIP - // Fix Frustum offset and up - //_viewFrustumOffsetCamera.setUpShift(viewFrustumOffset.up); - //_viewFrustumOffsetCamera.setDistance(viewFrustumOffset.distance); + glm::quat frustumRotation = glm::quat(glm::radians(glm::vec3(viewFrustumOffset.pitch, viewFrustumOffset.yaw, viewFrustumOffset.roll))); + + _viewFrustumOffsetCamera.setPosition(_myCamera.getPosition() + + frustumRotation * glm::vec3(0.0f, viewFrustumOffset.up, -viewFrustumOffset.distance)); + + _viewFrustumOffsetCamera.setRotation(_myCamera.getRotation() * frustumRotation); _viewFrustumOffsetCamera.initialize(); // force immediate snap to ideal position and orientation _viewFrustumOffsetCamera.update(1.f/_fps); diff --git a/interface/src/Application.h b/interface/src/Application.h index ca26cffab8..248c4325bf 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -519,7 +519,6 @@ private: QRect _mirrorViewRect; RearMirrorTools* _rearMirrorTools; - float _cameraPushback; glm::mat4 _untranslatedViewMatrix; glm::vec3 _viewMatrixTranslation; glm::mat4 _projectionMatrix; From 4daa379b033f6eb841f42d1006aa013dee6712a6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 15:32:56 -0700 Subject: [PATCH 22/56] use sweet alert for nice error messages in domain-settings --- .../resources/web/css/sweet-alert.css | 602 ++++++++++++++++++ domain-server/resources/web/header.html | 1 + domain-server/resources/web/js/settings.js | 19 +- .../resources/web/js/sweet-alert.min.js | 1 + .../resources/web/settings/index.shtml | 2 + 5 files changed, 613 insertions(+), 12 deletions(-) create mode 100755 domain-server/resources/web/css/sweet-alert.css create mode 100755 domain-server/resources/web/js/sweet-alert.min.js diff --git a/domain-server/resources/web/css/sweet-alert.css b/domain-server/resources/web/css/sweet-alert.css new file mode 100755 index 0000000000..eba0fa065d --- /dev/null +++ b/domain-server/resources/web/css/sweet-alert.css @@ -0,0 +1,602 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:400,600,700,300); +.sweet-overlay { + background-color: rgba(0, 0, 0, 0.4); + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + display: none; + z-index: 1000; } + +.sweet-alert { + background-color: white; + font-family: 'Open Sans', sans-serif; + width: 478px; + padding: 17px; + border-radius: 5px; + text-align: center; + position: fixed; + left: 50%; + top: 50%; + margin-left: -256px; + margin-top: -200px; + overflow: hidden; + display: none; + z-index: 2000; } + @media all and (max-width: 540px) { + .sweet-alert { + width: auto; + margin-left: 0; + margin-right: 0; + left: 15px; + right: 15px; } } + .sweet-alert h2 { + color: #575757; + font-size: 30px; + text-align: center; + font-weight: 600; + text-transform: none; + position: relative; } + .sweet-alert p { + color: #797979; + font-size: 16px; + text-align: center; + font-weight: 300; + position: relative; + margin: 0; + line-height: normal; } + .sweet-alert button { + background-color: #AEDEF4; + color: white; + border: none; + box-shadow: none; + font-size: 17px; + font-weight: 500; + border-radius: 5px; + padding: 10px 32px; + margin: 26px 5px 0 5px; + cursor: pointer; } + .sweet-alert button:focus { + outline: none; + box-shadow: 0 0 2px rgba(128, 179, 235, 0.5), inset 0 0 0 1px rgba(0, 0, 0, 0.05); } + .sweet-alert button:hover { + background-color: #a1d9f2; } + .sweet-alert button:active { + background-color: #81ccee; } + .sweet-alert button.cancel { + background-color: #D0D0D0; } + .sweet-alert button.cancel:hover { + background-color: #c8c8c8; } + .sweet-alert button.cancel:active { + background-color: #b6b6b6; } + .sweet-alert button.cancel:focus { + box-shadow: rgba(197, 205, 211, 0.8) 0px 0px 2px, rgba(0, 0, 0, 0.0470588) 0px 0px 0px 1px inset !important; } + .sweet-alert[data-has-cancel-button=false] button { + box-shadow: none !important; } + .sweet-alert .icon { + width: 80px; + height: 80px; + border: 4px solid gray; + border-radius: 50%; + margin: 20px auto; + position: relative; + box-sizing: content-box; } + .sweet-alert .icon.error { + border-color: #F27474; } + .sweet-alert .icon.error .x-mark { + position: relative; + display: block; } + .sweet-alert .icon.error .line { + position: absolute; + height: 5px; + width: 47px; + background-color: #F27474; + display: block; + top: 37px; + border-radius: 2px; } + .sweet-alert .icon.error .line.left { + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + left: 17px; } + .sweet-alert .icon.error .line.right { + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + right: 16px; } + .sweet-alert .icon.warning { + border-color: #F8BB86; } + .sweet-alert .icon.warning .body { + position: absolute; + width: 5px; + height: 47px; + left: 50%; + top: 10px; + border-radius: 2px; + margin-left: -2px; + background-color: #F8BB86; } + .sweet-alert .icon.warning .dot { + position: absolute; + width: 7px; + height: 7px; + border-radius: 50%; + margin-left: -3px; + left: 50%; + bottom: 10px; + background-color: #F8BB86; } + .sweet-alert .icon.info { + border-color: #C9DAE1; } + .sweet-alert .icon.info::before { + content: ""; + position: absolute; + width: 5px; + height: 29px; + left: 50%; + bottom: 17px; + border-radius: 2px; + margin-left: -2px; + background-color: #C9DAE1; } + .sweet-alert .icon.info::after { + content: ""; + position: absolute; + width: 7px; + height: 7px; + border-radius: 50%; + margin-left: -3px; + top: 19px; + background-color: #C9DAE1; } + .sweet-alert .icon.success { + border-color: #A5DC86; } + .sweet-alert .icon.success::before, .sweet-alert .icon.success::after { + content: ''; + border-radius: 50%; + position: absolute; + width: 60px; + height: 120px; + background: white; + transform: rotate(45deg); } + .sweet-alert .icon.success::before { + border-radius: 120px 0 0 120px; + top: -7px; + left: -33px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + -webkit-transform-origin: 60px 60px; + transform-origin: 60px 60px; } + .sweet-alert .icon.success::after { + border-radius: 0 120px 120px 0; + top: -11px; + left: 30px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + -webkit-transform-origin: 0px 60px; + transform-origin: 0px 60px; } + .sweet-alert .icon.success .placeholder { + width: 80px; + height: 80px; + border: 4px solid rgba(165, 220, 134, 0.2); + border-radius: 50%; + box-sizing: content-box; + position: absolute; + left: -4px; + top: -4px; + z-index: 2; } + .sweet-alert .icon.success .fix { + width: 5px; + height: 90px; + background-color: white; + position: absolute; + left: 28px; + top: 8px; + z-index: 1; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); } + .sweet-alert .icon.success .line { + height: 5px; + background-color: #A5DC86; + display: block; + border-radius: 2px; + position: absolute; + z-index: 2; } + .sweet-alert .icon.success .line.tip { + width: 25px; + left: 14px; + top: 46px; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); } + .sweet-alert .icon.success .line.long { + width: 47px; + right: 8px; + top: 38px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); } + .sweet-alert .icon.custom { + background-size: contain; + border-radius: 0; + border: none; + background-position: center center; + background-repeat: no-repeat; } + +/* + * Animations + */ +@-webkit-keyframes showSweetAlert { + 0% { + transform: scale(0.7); + -webkit-transform: scale(0.7); } + 45% { + transform: scale(1.05); + -webkit-transform: scale(1.05); } + 80% { + transform: scale(0.95); + -webkit-tranform: scale(0.95); } + 100% { + transform: scale(1); + -webkit-transform: scale(1); } } +@-moz-keyframes showSweetAlert { + 0% { + transform: scale(0.7); + -webkit-transform: scale(0.7); } + 45% { + transform: scale(1.05); + -webkit-transform: scale(1.05); } + 80% { + transform: scale(0.95); + -webkit-tranform: scale(0.95); } + 100% { + transform: scale(1); + -webkit-transform: scale(1); } } +@keyframes showSweetAlert { + 0% { + transform: scale(0.7); + -webkit-transform: scale(0.7); } + 45% { + transform: scale(1.05); + -webkit-transform: scale(1.05); } + 80% { + transform: scale(0.95); + -webkit-tranform: scale(0.95); } + 100% { + transform: scale(1); + -webkit-transform: scale(1); } } +@-webkit-keyframes hideSweetAlert { + 0% { + transform: scale(1); + -webkit-transform: scale(1); } + 100% { + transform: scale(0.5); + -webkit-transform: scale(0.5); } } +@-moz-keyframes hideSweetAlert { + 0% { + transform: scale(1); + -webkit-transform: scale(1); } + 100% { + transform: scale(0.5); + -webkit-transform: scale(0.5); } } +@keyframes hideSweetAlert { + 0% { + transform: scale(1); + -webkit-transform: scale(1); } + 100% { + transform: scale(0.5); + -webkit-transform: scale(0.5); } } +.showSweetAlert { + -webkit-animation: showSweetAlert 0.3s; + -moz-animation: showSweetAlert 0.3s; + animation: showSweetAlert 0.3s; } + +.hideSweetAlert { + -webkit-animation: hideSweetAlert 0.2s; + -moz-animation: hideSweetAlert 0.2s; + animation: hideSweetAlert 0.2s; } + +@-webkit-keyframes animateSuccessTip { + 0% { + width: 0; + left: 1px; + top: 19px; } + 54% { + width: 0; + left: 1px; + top: 19px; } + 70% { + width: 50px; + left: -8px; + top: 37px; } + 84% { + width: 17px; + left: 21px; + top: 48px; } + 100% { + width: 25px; + left: 14px; + top: 45px; } } +@-moz-keyframes animateSuccessTip { + 0% { + width: 0; + left: 1px; + top: 19px; } + 54% { + width: 0; + left: 1px; + top: 19px; } + 70% { + width: 50px; + left: -8px; + top: 37px; } + 84% { + width: 17px; + left: 21px; + top: 48px; } + 100% { + width: 25px; + left: 14px; + top: 45px; } } +@keyframes animateSuccessTip { + 0% { + width: 0; + left: 1px; + top: 19px; } + 54% { + width: 0; + left: 1px; + top: 19px; } + 70% { + width: 50px; + left: -8px; + top: 37px; } + 84% { + width: 17px; + left: 21px; + top: 48px; } + 100% { + width: 25px; + left: 14px; + top: 45px; } } +@-webkit-keyframes animateSuccessLong { + 0% { + width: 0; + right: 46px; + top: 54px; } + 65% { + width: 0; + right: 46px; + top: 54px; } + 84% { + width: 55px; + right: 0px; + top: 35px; } + 100% { + width: 47px; + right: 8px; + top: 38px; } } +@-moz-keyframes animateSuccessLong { + 0% { + width: 0; + right: 46px; + top: 54px; } + 65% { + width: 0; + right: 46px; + top: 54px; } + 84% { + width: 55px; + right: 0px; + top: 35px; } + 100% { + width: 47px; + right: 8px; + top: 38px; } } +@keyframes animateSuccessLong { + 0% { + width: 0; + right: 46px; + top: 54px; } + 65% { + width: 0; + right: 46px; + top: 54px; } + 84% { + width: 55px; + right: 0px; + top: 35px; } + 100% { + width: 47px; + right: 8px; + top: 38px; } } +@-webkit-keyframes rotatePlaceholder { + 0% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 5% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 12% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } + 100% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } } +@-moz-keyframes rotatePlaceholder { + 0% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 5% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 12% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } + 100% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } } +@keyframes rotatePlaceholder { + 0% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 5% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 12% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } + 100% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } } +.animateSuccessTip { + -webkit-animation: animateSuccessTip 0.75s; + -moz-animation: animateSuccessTip 0.75s; + animation: animateSuccessTip 0.75s; } + +.animateSuccessLong { + -webkit-animation: animateSuccessLong 0.75s; + -moz-animation: animateSuccessLong 0.75s; + animation: animateSuccessLong 0.75s; } + +.icon.success.animate::after { + -webkit-animation: rotatePlaceholder 4.25s ease-in; + -moz-animation: rotatePlaceholder 4.25s ease-in; + animation: rotatePlaceholder 4.25s ease-in; } + +@-webkit-keyframes animateErrorIcon { + 0% { + transform: rotateX(100deg); + -webkit-transform: rotateX(100deg); + opacity: 0; } + 100% { + transform: rotateX(0deg); + -webkit-transform: rotateX(0deg); + opacity: 1; } } +@-moz-keyframes animateErrorIcon { + 0% { + transform: rotateX(100deg); + -webkit-transform: rotateX(100deg); + opacity: 0; } + 100% { + transform: rotateX(0deg); + -webkit-transform: rotateX(0deg); + opacity: 1; } } +@keyframes animateErrorIcon { + 0% { + transform: rotateX(100deg); + -webkit-transform: rotateX(100deg); + opacity: 0; } + 100% { + transform: rotateX(0deg); + -webkit-transform: rotateX(0deg); + opacity: 1; } } +.animateErrorIcon { + -webkit-animation: animateErrorIcon 0.5s; + -moz-animation: animateErrorIcon 0.5s; + animation: animateErrorIcon 0.5s; } + +@-webkit-keyframes animateXMark { + 0% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 50% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 80% { + transform: scale(1.15); + -webkit-transform: scale(1.15); + margin-top: -6px; } + 100% { + transform: scale(1); + -webkit-transform: scale(1); + margin-top: 0; + opacity: 1; } } +@-moz-keyframes animateXMark { + 0% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 50% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 80% { + transform: scale(1.15); + -webkit-transform: scale(1.15); + margin-top: -6px; } + 100% { + transform: scale(1); + -webkit-transform: scale(1); + margin-top: 0; + opacity: 1; } } +@keyframes animateXMark { + 0% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 50% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 80% { + transform: scale(1.15); + -webkit-transform: scale(1.15); + margin-top: -6px; } + 100% { + transform: scale(1); + -webkit-transform: scale(1); + margin-top: 0; + opacity: 1; } } +.animateXMark { + -webkit-animation: animateXMark 0.5s; + -moz-animation: animateXMark 0.5s; + animation: animateXMark 0.5s; } + +/*@include keyframes(simpleRotate) { + 0% { transform: rotateY(0deg); } + 100% { transform: rotateY(-360deg); } +} +.simpleRotate { + @include animation('simpleRotate 0.75s'); +}*/ +@-webkit-keyframes pulseWarning { + 0% { + border-color: #F8D486; } + 100% { + border-color: #F8BB86; } } +@-moz-keyframes pulseWarning { + 0% { + border-color: #F8D486; } + 100% { + border-color: #F8BB86; } } +@keyframes pulseWarning { + 0% { + border-color: #F8D486; } + 100% { + border-color: #F8BB86; } } +.pulseWarning { + -webkit-animation: pulseWarning 0.75s infinite alternate; + -moz-animation: pulseWarning 0.75s infinite alternate; + animation: pulseWarning 0.75s infinite alternate; } + +@-webkit-keyframes pulseWarningIns { + 0% { + background-color: #F8D486; } + 100% { + background-color: #F8BB86; } } +@-moz-keyframes pulseWarningIns { + 0% { + background-color: #F8D486; } + 100% { + background-color: #F8BB86; } } +@keyframes pulseWarningIns { + 0% { + background-color: #F8D486; } + 100% { + background-color: #F8BB86; } } +.pulseWarningIns { + -webkit-animation: pulseWarningIns 0.75s infinite alternate; + -moz-animation: pulseWarningIns 0.75s infinite alternate; + animation: pulseWarningIns 0.75s infinite alternate; } diff --git a/domain-server/resources/web/header.html b/domain-server/resources/web/header.html index 5abf8fa028..66f48637c5 100644 --- a/domain-server/resources/web/header.html +++ b/domain-server/resources/web/header.html @@ -6,6 +6,7 @@ +