From 04b628bede3c51f180819d2190ef773a23a94c60 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 7 Oct 2014 16:44:55 -0700 Subject: [PATCH] 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)