More point bits (trying a different tack).

This commit is contained in:
Andrzej Kapolka 2014-07-21 19:00:13 -07:00
parent dd7f3703e1
commit 0ddd3e650c
8 changed files with 179 additions and 28 deletions

View file

@ -44,6 +44,7 @@ void MetavoxelServer::run() {
nodeList->addNodeTypeToInterestSet(NodeType::Agent); nodeList->addNodeTypeToInterestSet(NodeType::Agent);
connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), SLOT(maybeAttachSession(const SharedNodePointer&))); connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), SLOT(maybeAttachSession(const SharedNodePointer&)));
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(maybeDeleteSession(const SharedNodePointer&)));
_lastSend = QDateTime::currentMSecsSinceEpoch(); _lastSend = QDateTime::currentMSecsSinceEpoch();
_sendTimer.start(SEND_INTERVAL); _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<MetavoxelSession*>(node->getLinkedData());
if (session) {
node->setLinkedData(NULL);
session->deleteLater();
}
}
}
void MetavoxelServer::sendDeltas() { void MetavoxelServer::sendDeltas() {
// send deltas for all sessions // send deltas for all sessions
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {

View file

@ -21,6 +21,7 @@
class MetavoxelEditMessage; class MetavoxelEditMessage;
class MetavoxelPersister; class MetavoxelPersister;
class MetavoxelSender;
class MetavoxelSession; class MetavoxelSession;
/// Maintains a shared metavoxel system, accepting change requests and broadcasting updates. /// Maintains a shared metavoxel system, accepting change requests and broadcasting updates.
@ -46,6 +47,7 @@ public:
private slots: private slots:
void maybeAttachSession(const SharedNodePointer& node); void maybeAttachSession(const SharedNodePointer& node);
void maybeDeleteSession(const SharedNodePointer& node);
void sendDeltas(); void sendDeltas();
private: private:

View file

@ -18,7 +18,7 @@ void main(void) {
// standard diffuse lighting // standard diffuse lighting
gl_FrontColor = vec4(gl_Color.rgb * (gl_LightModel.ambient.rgb + gl_LightSource[0].ambient.rgb + 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_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 // extract the first three components of the vertex for position
gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0); gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0);

View file

@ -26,6 +26,8 @@
REGISTER_META_OBJECT(SphereRenderer) REGISTER_META_OBJECT(SphereRenderer)
REGISTER_META_OBJECT(StaticModelRenderer) REGISTER_META_OBJECT(StaticModelRenderer)
static int bufferPointVectorMetaTypeId = qRegisterMetaType<BufferPointVector>();
ProgramObject MetavoxelSystem::_program; ProgramObject MetavoxelSystem::_program;
int MetavoxelSystem::_pointScaleLocation; int MetavoxelSystem::_pointScaleLocation;
@ -152,8 +154,22 @@ void MetavoxelSystem::render() {
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
PointBufferRenderVisitor pointBufferRenderVisitor; glDisable(GL_BLEND);
guide(pointBufferRenderVisitor);
//PointBufferRenderVisitor pointBufferRenderVisitor;
//guide(pointBufferRenderVisitor);
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex());
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
if (client) {
client->render();
}
}
}
glEnable(GL_BLEND);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
@ -176,7 +192,35 @@ void MetavoxelSystem::updateClient(MetavoxelClient* client) {
} }
MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelSystem* system) : 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) { int MetavoxelSystemClient::parseData(const QByteArray& packet) {
@ -280,8 +324,73 @@ bool BufferBuilder::postVisit(MetavoxelInfo& info) {
return true; return true;
} }
class PointCollector : public MetavoxelVisitor {
public:
QVector<BufferPoint> points;
PointCollector(const MetavoxelLOD& lod);
virtual int visit(MetavoxelInfo& info);
};
PointCollector::PointCollector(const MetavoxelLOD& lod) :
MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getColorAttribute() <<
AttributeRegistry::getInstance()->getNormalAttribute(), QVector<AttributePointer>(), lod) {
}
int PointCollector::visit(MetavoxelInfo& info) {
if (!info.isLeaf) {
return DEFAULT_ORDER;
}
QRgb color = info.inputValues.at(0).getInlineValue<QRgb>();
quint8 alpha = qAlpha(color);
if (alpha <= ALPHA_RENDER_THRESHOLD) {
return STOP_RECURSION;
}
QRgb normal = info.inputValues.at(1).getInlineValue<QRgb>();
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> _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) { void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) {
BufferBuilder builder(_remoteDataLOD); /* BufferBuilder builder(_remoteDataLOD);
const AttributePointer& pointBufferAttribute = Application::getInstance()->getMetavoxels()->getPointBufferAttribute(); const AttributePointer& pointBufferAttribute = Application::getInstance()->getMetavoxels()->getPointBufferAttribute();
MetavoxelNode* oldRoot = oldData.getRoot(pointBufferAttribute); MetavoxelNode* oldRoot = oldData.getRoot(pointBufferAttribute);
if (oldRoot && oldData.getSize() == _data.getSize()) { if (oldRoot && oldData.getSize() == _data.getSize()) {
@ -292,7 +401,8 @@ void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) {
} else { } else {
_data.clear(pointBufferAttribute); _data.clear(pointBufferAttribute);
_data.guide(builder); _data.guide(builder);
} } */
QThreadPool::globalInstance()->start(new PointBufferBuilder(_node, _data, _remoteDataLOD));
} }
void MetavoxelSystemClient::sendDatagram(const QByteArray& data) { void MetavoxelSystemClient::sendDatagram(const QByteArray& data) {

View file

@ -52,22 +52,6 @@ private:
AttributePointer _pointBufferAttribute; 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. /// Describes contents of a point in a point buffer.
class BufferPoint { class BufferPoint {
public: public:
@ -79,6 +63,33 @@ public:
typedef QVector<BufferPoint> BufferPointVector; typedef QVector<BufferPoint> BufferPointVector;
typedef QPair<BufferPointVector, BufferPointVector> BufferPointVectorPair; typedef QPair<BufferPointVector, BufferPointVector> 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. /// Contains the information necessary to render a group of points at variable detail levels.
class PointBuffer : public QSharedData { class PointBuffer : public QSharedData {
public: public:

View file

@ -49,7 +49,7 @@ void Endpoint::update() {
int Endpoint::parseData(const QByteArray& packet) { int Endpoint::parseData(const QByteArray& packet) {
// process through sequencer // process through sequencer
_sequencer.receivedDatagram(packet); QMetaObject::invokeMethod(&_sequencer, "receivedDatagram", Q_ARG(const QByteArray&, packet));
return packet.size(); return packet.size();
} }

View file

@ -16,6 +16,7 @@
void MetavoxelClientManager::init() { void MetavoxelClientManager::init() {
connect(NodeList::getInstance(), SIGNAL(nodeAdded(SharedNodePointer)), SLOT(maybeAttachClient(const SharedNodePointer&))); connect(NodeList::getInstance(), SIGNAL(nodeAdded(SharedNodePointer)), SLOT(maybeAttachClient(const SharedNodePointer&)));
connect(NodeList::getInstance(), SIGNAL(nodeKilled(SharedNodePointer)), SLOT(maybeDeleteClient(const SharedNodePointer&)));
} }
void MetavoxelClientManager::update() { 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<MetavoxelClient*>(node->getLinkedData());
if (client) {
node->setLinkedData(NULL);
client->deleteLater();
}
}
}
MetavoxelClient* MetavoxelClientManager::createClient(const SharedNodePointer& node) { MetavoxelClient* MetavoxelClientManager::createClient(const SharedNodePointer& node) {
return new MetavoxelClient(node, this); return new MetavoxelClient(node, this);
} }
@ -138,8 +150,10 @@ void MetavoxelClient::applyEdit(const MetavoxelEditMessage& edit, bool reliable)
// apply immediately to local tree // apply immediately to local tree
MetavoxelData oldData = _data; MetavoxelData oldData = _data;
edit.apply(_data, _sequencer.getWeakSharedObjectHash()); edit.apply(_data, _sequencer.getWeakSharedObjectHash());
dataChanged(oldData); if (_data != oldData) {
dataChanged(oldData);
}
// start sending it out // start sending it out
_sequencer.sendHighPriorityMessage(QVariant::fromValue(edit)); _sequencer.sendHighPriorityMessage(QVariant::fromValue(edit));
} }
@ -177,8 +191,9 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) {
message.data.value<MetavoxelEditMessage>().apply(_data, _sequencer.getWeakSharedObjectHash()); message.data.value<MetavoxelEditMessage>().apply(_data, _sequencer.getWeakSharedObjectHash());
} }
} }
dataChanged(oldData); if (_data != oldData) {
dataChanged(oldData);
}
} else if (userType == MetavoxelDeltaPendingMessage::Type) { } else if (userType == MetavoxelDeltaPendingMessage::Type) {
// check the id to make sure this is not a delta we've already processed // check the id to make sure this is not a delta we've already processed
int id = message.value<MetavoxelDeltaPendingMessage>().id; int id = message.value<MetavoxelDeltaPendingMessage>().id;

View file

@ -40,7 +40,8 @@ public:
private slots: private slots:
void maybeAttachClient(const SharedNodePointer& node); void maybeAttachClient(const SharedNodePointer& node);
void maybeDeleteClient(const SharedNodePointer& node);
protected: protected:
virtual MetavoxelClient* createClient(const SharedNodePointer& node); virtual MetavoxelClient* createClient(const SharedNodePointer& node);