From 0ddd3e650cf6b792d4281d7332bb203fa9498457 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 21 Jul 2014 19:00:13 -0700 Subject: [PATCH] More point bits (trying a different tack). --- .../src/metavoxels/MetavoxelServer.cpp | 12 ++ .../src/metavoxels/MetavoxelServer.h | 2 + .../resources/shaders/metavoxel_point.vert | 2 +- interface/src/MetavoxelSystem.cpp | 120 +++++++++++++++++- interface/src/MetavoxelSystem.h | 43 ++++--- libraries/metavoxels/src/Endpoint.cpp | 2 +- .../metavoxels/src/MetavoxelClientManager.cpp | 23 +++- .../metavoxels/src/MetavoxelClientManager.h | 3 +- 8 files changed, 179 insertions(+), 28 deletions(-) diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index 598d8ea722..eed0f3a226 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -44,6 +44,7 @@ void MetavoxelServer::run() { nodeList->addNodeTypeToInterestSet(NodeType::Agent); connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), SLOT(maybeAttachSession(const SharedNodePointer&))); + connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(maybeDeleteSession(const SharedNodePointer&))); _lastSend = QDateTime::currentMSecsSinceEpoch(); _sendTimer.start(SEND_INTERVAL); @@ -96,6 +97,17 @@ void MetavoxelServer::maybeAttachSession(const SharedNodePointer& node) { } } +void MetavoxelServer::maybeDeleteSession(const SharedNodePointer& node) { + if (node->getType() == NodeType::Agent) { + QMutexLocker locker(&node->getMutex()); + MetavoxelSession* session = static_cast(node->getLinkedData()); + if (session) { + node->setLinkedData(NULL); + session->deleteLater(); + } + } +} + void MetavoxelServer::sendDeltas() { // send deltas for all sessions foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { diff --git a/assignment-client/src/metavoxels/MetavoxelServer.h b/assignment-client/src/metavoxels/MetavoxelServer.h index 9ed765f65f..42694b03bf 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.h +++ b/assignment-client/src/metavoxels/MetavoxelServer.h @@ -21,6 +21,7 @@ class MetavoxelEditMessage; class MetavoxelPersister; +class MetavoxelSender; class MetavoxelSession; /// Maintains a shared metavoxel system, accepting change requests and broadcasting updates. @@ -46,6 +47,7 @@ public: private slots: void maybeAttachSession(const SharedNodePointer& node); + void maybeDeleteSession(const SharedNodePointer& node); void sendDeltas(); private: diff --git a/interface/resources/shaders/metavoxel_point.vert b/interface/resources/shaders/metavoxel_point.vert index fa585be099..1a4a4c56ce 100644 --- a/interface/resources/shaders/metavoxel_point.vert +++ b/interface/resources/shaders/metavoxel_point.vert @@ -18,7 +18,7 @@ void main(void) { // 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))), - gl_Color.a); + 0.0); // extract the first three components of the vertex for position gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0); diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index c30976d83e..2b3528b1b3 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -26,6 +26,8 @@ REGISTER_META_OBJECT(SphereRenderer) REGISTER_META_OBJECT(StaticModelRenderer) +static int bufferPointVectorMetaTypeId = qRegisterMetaType(); + ProgramObject MetavoxelSystem::_program; int MetavoxelSystem::_pointScaleLocation; @@ -152,8 +154,22 @@ void MetavoxelSystem::render() { glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); - PointBufferRenderVisitor pointBufferRenderVisitor; - guide(pointBufferRenderVisitor); + glDisable(GL_BLEND); + + //PointBufferRenderVisitor pointBufferRenderVisitor; + //guide(pointBufferRenderVisitor); + + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + if (node->getType() == NodeType::MetavoxelServer) { + QMutexLocker locker(&node->getMutex()); + MetavoxelSystemClient* client = static_cast(node->getLinkedData()); + if (client) { + client->render(); + } + } + } + + glEnable(GL_BLEND); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); @@ -176,7 +192,35 @@ void MetavoxelSystem::updateClient(MetavoxelClient* client) { } MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelSystem* system) : - MetavoxelClient(node, system) { + MetavoxelClient(node, system), + _pointCount(0) { + + _buffer.setUsagePattern(QOpenGLBuffer::StaticDraw); + _buffer.create(); +} + +void MetavoxelSystemClient::render() { + _buffer.bind(); + + BufferPoint* point = 0; + glVertexPointer(4, GL_FLOAT, sizeof(BufferPoint), &point->vertex); + glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(BufferPoint), &point->color); + glNormalPointer(GL_BYTE, sizeof(BufferPoint), &point->normal); + + glDrawArrays(GL_POINTS, 0, _pointCount); + + _buffer.release(); +} + +void MetavoxelSystemClient::setPoints(const BufferPointVector& points) { + qint64 now = QDateTime::currentMSecsSinceEpoch(); + _buffer.bind(); + _buffer.allocate(points.constData(), points.size() * sizeof(BufferPoint)); + _buffer.release(); + _pointCount = points.size(); + qDebug() << "upload" << (QDateTime::currentMSecsSinceEpoch() - now); + qDebug() << _pointCount; + } int MetavoxelSystemClient::parseData(const QByteArray& packet) { @@ -280,8 +324,73 @@ bool BufferBuilder::postVisit(MetavoxelInfo& info) { return true; } +class PointCollector : public MetavoxelVisitor { +public: + + QVector points; + + PointCollector(const MetavoxelLOD& lod); + + virtual int visit(MetavoxelInfo& info); +}; + +PointCollector::PointCollector(const MetavoxelLOD& lod) : + MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getColorAttribute() << + AttributeRegistry::getInstance()->getNormalAttribute(), QVector(), lod) { +} + +int PointCollector::visit(MetavoxelInfo& info) { + if (!info.isLeaf) { + return DEFAULT_ORDER; + } + QRgb color = info.inputValues.at(0).getInlineValue(); + quint8 alpha = qAlpha(color); + if (alpha <= ALPHA_RENDER_THRESHOLD) { + return STOP_RECURSION; + } + QRgb normal = info.inputValues.at(1).getInlineValue(); + BufferPoint point = { glm::vec4(info.minimum + glm::vec3(info.size, info.size, info.size) * 0.5f, info.size), + { quint8(qRed(color)), quint8(qGreen(color)), quint8(qBlue(color)) }, + { quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } }; + points.append(point); + return STOP_RECURSION; +} + +/// Builds a point buffer. +class PointBufferBuilder : public QRunnable { +public: + + PointBufferBuilder(const SharedNodePointer& node, const MetavoxelData& data, const MetavoxelLOD& lod); + + virtual void run(); + +private: + + QWeakPointer _node; + MetavoxelData _data; + MetavoxelLOD _lod; +}; + +PointBufferBuilder::PointBufferBuilder(const SharedNodePointer& node, const MetavoxelData& data, const MetavoxelLOD& lod) : + _node(node), + _data(data), + _lod(lod) { +} + +void PointBufferBuilder::run() { + SharedNodePointer node = _node; + if (!node) { + return; + } + qint64 now = QDateTime::currentMSecsSinceEpoch(); + PointCollector collector(_lod); + _data.guide(collector); + QMetaObject::invokeMethod(node->getLinkedData(), "setPoints", Q_ARG(const BufferPointVector&, collector.points)); + qDebug() << "collect" << (QDateTime::currentMSecsSinceEpoch() - now); +} + void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) { - BufferBuilder builder(_remoteDataLOD); + /* BufferBuilder builder(_remoteDataLOD); const AttributePointer& pointBufferAttribute = Application::getInstance()->getMetavoxels()->getPointBufferAttribute(); MetavoxelNode* oldRoot = oldData.getRoot(pointBufferAttribute); if (oldRoot && oldData.getSize() == _data.getSize()) { @@ -292,7 +401,8 @@ void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) { } else { _data.clear(pointBufferAttribute); _data.guide(builder); - } + } */ + QThreadPool::globalInstance()->start(new PointBufferBuilder(_node, _data, _remoteDataLOD)); } void MetavoxelSystemClient::sendDatagram(const QByteArray& data) { diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index 6557dc5018..afbfd9444f 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -52,22 +52,6 @@ private: AttributePointer _pointBufferAttribute; }; -/// A client session associated with a single server. -class MetavoxelSystemClient : public MetavoxelClient { - Q_OBJECT - -public: - - MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelSystem* system); - - virtual int parseData(const QByteArray& packet); - -protected: - - virtual void dataChanged(const MetavoxelData& oldData); - virtual void sendDatagram(const QByteArray& data); -}; - /// Describes contents of a point in a point buffer. class BufferPoint { public: @@ -79,6 +63,33 @@ public: typedef QVector BufferPointVector; typedef QPair BufferPointVectorPair; +Q_DECLARE_METATYPE(BufferPointVector) + +/// A client session associated with a single server. +class MetavoxelSystemClient : public MetavoxelClient { + Q_OBJECT + +public: + + MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelSystem* system); + + void render(); + + Q_INVOKABLE void setPoints(const BufferPointVector& points); + + virtual int parseData(const QByteArray& packet); + +protected: + + virtual void dataChanged(const MetavoxelData& oldData); + virtual void sendDatagram(const QByteArray& data); + +private: + + QOpenGLBuffer _buffer; + int _pointCount; +}; + /// Contains the information necessary to render a group of points at variable detail levels. class PointBuffer : public QSharedData { public: diff --git a/libraries/metavoxels/src/Endpoint.cpp b/libraries/metavoxels/src/Endpoint.cpp index 420a52ef95..9672b245cc 100644 --- a/libraries/metavoxels/src/Endpoint.cpp +++ b/libraries/metavoxels/src/Endpoint.cpp @@ -49,7 +49,7 @@ void Endpoint::update() { int Endpoint::parseData(const QByteArray& packet) { // process through sequencer - _sequencer.receivedDatagram(packet); + QMetaObject::invokeMethod(&_sequencer, "receivedDatagram", Q_ARG(const QByteArray&, packet)); return packet.size(); } diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index d1ea3021a6..af97551ade 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -16,6 +16,7 @@ void MetavoxelClientManager::init() { connect(NodeList::getInstance(), SIGNAL(nodeAdded(SharedNodePointer)), SLOT(maybeAttachClient(const SharedNodePointer&))); + connect(NodeList::getInstance(), SIGNAL(nodeKilled(SharedNodePointer)), SLOT(maybeDeleteClient(const SharedNodePointer&))); } void MetavoxelClientManager::update() { @@ -95,6 +96,17 @@ void MetavoxelClientManager::maybeAttachClient(const SharedNodePointer& node) { } } +void MetavoxelClientManager::maybeDeleteClient(const SharedNodePointer& node) { + if (node->getType() == NodeType::MetavoxelServer) { + QMutexLocker locker(&node->getMutex()); + MetavoxelClient* client = static_cast(node->getLinkedData()); + if (client) { + node->setLinkedData(NULL); + client->deleteLater(); + } + } +} + MetavoxelClient* MetavoxelClientManager::createClient(const SharedNodePointer& node) { return new MetavoxelClient(node, this); } @@ -138,8 +150,10 @@ void MetavoxelClient::applyEdit(const MetavoxelEditMessage& edit, bool reliable) // apply immediately to local tree MetavoxelData oldData = _data; edit.apply(_data, _sequencer.getWeakSharedObjectHash()); - dataChanged(oldData); - + if (_data != oldData) { + dataChanged(oldData); + } + // start sending it out _sequencer.sendHighPriorityMessage(QVariant::fromValue(edit)); } @@ -177,8 +191,9 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { message.data.value().apply(_data, _sequencer.getWeakSharedObjectHash()); } } - dataChanged(oldData); - + if (_data != oldData) { + dataChanged(oldData); + } } else if (userType == MetavoxelDeltaPendingMessage::Type) { // check the id to make sure this is not a delta we've already processed int id = message.value().id; diff --git a/libraries/metavoxels/src/MetavoxelClientManager.h b/libraries/metavoxels/src/MetavoxelClientManager.h index fcc8b31a1f..a915ba9c3c 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.h +++ b/libraries/metavoxels/src/MetavoxelClientManager.h @@ -40,7 +40,8 @@ public: private slots: void maybeAttachClient(const SharedNodePointer& node); - + void maybeDeleteClient(const SharedNodePointer& node); + protected: virtual MetavoxelClient* createClient(const SharedNodePointer& node);