mirror of
https://github.com/overte-org/overte.git
synced 2025-07-24 00:43:49 +02:00
Basic editing with delta streaming up and running.
This commit is contained in:
parent
62e8cbedbd
commit
d5695395c4
10 changed files with 118 additions and 68 deletions
|
@ -24,6 +24,10 @@ MetavoxelServer::MetavoxelServer(const unsigned char* dataBuffer, int numBytes)
|
||||||
connect(&_sendTimer, SIGNAL(timeout()), SLOT(sendDeltas()));
|
connect(&_sendTimer, SIGNAL(timeout()), SLOT(sendDeltas()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetavoxelServer::applyEdit(const MetavoxelEditMessage& edit) {
|
||||||
|
edit.apply(_data);
|
||||||
|
}
|
||||||
|
|
||||||
void MetavoxelServer::removeSession(const QUuid& sessionId) {
|
void MetavoxelServer::removeSession(const QUuid& sessionId) {
|
||||||
delete _sessions.take(sessionId);
|
delete _sessions.take(sessionId);
|
||||||
}
|
}
|
||||||
|
@ -74,16 +78,18 @@ void MetavoxelServer::processData(const QByteArray& data, const HifiSockAddr& se
|
||||||
// forward to session, creating if necessary
|
// forward to session, creating if necessary
|
||||||
MetavoxelSession*& session = _sessions[sessionID];
|
MetavoxelSession*& session = _sessions[sessionID];
|
||||||
if (!session) {
|
if (!session) {
|
||||||
session = new MetavoxelSession(this, sessionID, QByteArray::fromRawData(data.constData(), headerPlusIDSize));
|
session = new MetavoxelSession(this, sessionID, QByteArray::fromRawData(data.constData(), headerPlusIDSize), sender);
|
||||||
}
|
}
|
||||||
session->receivedData(data, sender);
|
session->receivedData(data, sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const QUuid& sessionId, const QByteArray& datagramHeader) :
|
MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const QUuid& sessionId,
|
||||||
|
const QByteArray& datagramHeader, const HifiSockAddr& sender) :
|
||||||
QObject(server),
|
QObject(server),
|
||||||
_server(server),
|
_server(server),
|
||||||
_sessionId(sessionId),
|
_sessionId(sessionId),
|
||||||
_sequencer(datagramHeader) {
|
_sequencer(datagramHeader),
|
||||||
|
_sender(sender) {
|
||||||
|
|
||||||
const int TIMEOUT_INTERVAL = 30 * 1000;
|
const int TIMEOUT_INTERVAL = 30 * 1000;
|
||||||
_timeoutTimer.setInterval(TIMEOUT_INTERVAL);
|
_timeoutTimer.setInterval(TIMEOUT_INTERVAL);
|
||||||
|
@ -98,6 +104,8 @@ MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const QUuid& session
|
||||||
// insert the baseline send record
|
// insert the baseline send record
|
||||||
SendRecord record = { 0 };
|
SendRecord record = { 0 };
|
||||||
_sendRecords.append(record);
|
_sendRecords.append(record);
|
||||||
|
|
||||||
|
qDebug() << "Opened session [sessionId=" << _sessionId << ", sender=" << _sender << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelSession::receivedData(const QByteArray& data, const HifiSockAddr& sender) {
|
void MetavoxelSession::receivedData(const QByteArray& data, const HifiSockAddr& sender) {
|
||||||
|
@ -114,7 +122,7 @@ void MetavoxelSession::receivedData(const QByteArray& data, const HifiSockAddr&
|
||||||
void MetavoxelSession::sendDelta() {
|
void MetavoxelSession::sendDelta() {
|
||||||
Bitstream& out = _sequencer.startPacket();
|
Bitstream& out = _sequencer.startPacket();
|
||||||
out << QVariant::fromValue(MetavoxelDeltaMessage());
|
out << QVariant::fromValue(MetavoxelDeltaMessage());
|
||||||
//writeDelta(_server->getData(), _sendRecords.first().data, out);
|
_server->getData().writeDelta(_sendRecords.first().data, out);
|
||||||
_sequencer.endPacket();
|
_sequencer.endPacket();
|
||||||
|
|
||||||
// record the send
|
// record the send
|
||||||
|
@ -143,13 +151,16 @@ void MetavoxelSession::clearSendRecordsBefore(int index) {
|
||||||
|
|
||||||
void MetavoxelSession::handleMessage(const QVariant& message) {
|
void MetavoxelSession::handleMessage(const QVariant& message) {
|
||||||
int userType = message.userType();
|
int userType = message.userType();
|
||||||
if (userType == ClientStateMessage::Type) {
|
if (userType == CloseSessionMessage::Type) {
|
||||||
|
qDebug() << "Session closed [sessionId=" << _sessionId << ", sender=" << _sender << "]";
|
||||||
|
_server->removeSession(_sessionId);
|
||||||
|
|
||||||
|
} else if (userType == ClientStateMessage::Type) {
|
||||||
ClientStateMessage state = message.value<ClientStateMessage>();
|
ClientStateMessage state = message.value<ClientStateMessage>();
|
||||||
_position = state.position;
|
_position = state.position;
|
||||||
|
|
||||||
} else if (userType == MetavoxelEdit::Type) {
|
} else if (userType == MetavoxelEditMessage::Type) {
|
||||||
MetavoxelEdit edit = message.value<MetavoxelEdit>();
|
_server->applyEdit(message.value<MetavoxelEditMessage>());
|
||||||
qDebug() << "got edit " << edit.granularity;
|
|
||||||
|
|
||||||
} else if (userType == QMetaType::QVariantList) {
|
} else if (userType == QMetaType::QVariantList) {
|
||||||
foreach (const QVariant& element, message.toList()) {
|
foreach (const QVariant& element, message.toList()) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <DatagramSequencer.h>
|
#include <DatagramSequencer.h>
|
||||||
#include <MetavoxelData.h>
|
#include <MetavoxelData.h>
|
||||||
|
|
||||||
|
class MetavoxelEditMessage;
|
||||||
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.
|
||||||
|
@ -30,6 +31,8 @@ public:
|
||||||
|
|
||||||
MetavoxelServer(const unsigned char* dataBuffer, int numBytes);
|
MetavoxelServer(const unsigned char* dataBuffer, int numBytes);
|
||||||
|
|
||||||
|
void applyEdit(const MetavoxelEditMessage& edit);
|
||||||
|
|
||||||
const MetavoxelData& getData() const { return _data; }
|
const MetavoxelData& getData() const { return _data; }
|
||||||
|
|
||||||
void removeSession(const QUuid& sessionId);
|
void removeSession(const QUuid& sessionId);
|
||||||
|
@ -60,7 +63,8 @@ class MetavoxelSession : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MetavoxelSession(MetavoxelServer* server, const QUuid& sessionId, const QByteArray& datagramHeader);
|
MetavoxelSession(MetavoxelServer* server, const QUuid& sessionId,
|
||||||
|
const QByteArray& datagramHeader, const HifiSockAddr& sender);
|
||||||
|
|
||||||
void receivedData(const QByteArray& data, const HifiSockAddr& sender);
|
void receivedData(const QByteArray& data, const HifiSockAddr& sender);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ void MetavoxelSystem::init() {
|
||||||
_buffer.create();
|
_buffer.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelSystem::applyEdit(const MetavoxelEdit& edit) {
|
void MetavoxelSystem::applyEdit(const MetavoxelEditMessage& edit) {
|
||||||
foreach (MetavoxelClient* client, _clients) {
|
foreach (MetavoxelClient* client, _clients) {
|
||||||
client->applyEdit(edit);
|
client->applyEdit(edit);
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,14 @@ MetavoxelClient::MetavoxelClient(const HifiSockAddr& address) :
|
||||||
_receiveRecords.append(record);
|
_receiveRecords.append(record);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelClient::applyEdit(const MetavoxelEdit& edit) {
|
MetavoxelClient::~MetavoxelClient() {
|
||||||
|
// close the session
|
||||||
|
Bitstream& out = _sequencer.startPacket();
|
||||||
|
out << QVariant::fromValue(CloseSessionMessage());
|
||||||
|
_sequencer.endPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetavoxelClient::applyEdit(const MetavoxelEditMessage& edit) {
|
||||||
// apply immediately to local tree
|
// apply immediately to local tree
|
||||||
edit.apply(_data);
|
edit.apply(_data);
|
||||||
|
|
||||||
|
@ -227,6 +234,13 @@ void MetavoxelClient::readPacket(Bitstream& in) {
|
||||||
// record the receipt
|
// record the receipt
|
||||||
ReceiveRecord record = { _sequencer.getIncomingPacketNumber(), _data };
|
ReceiveRecord record = { _sequencer.getIncomingPacketNumber(), _data };
|
||||||
_receiveRecords.append(record);
|
_receiveRecords.append(record);
|
||||||
|
|
||||||
|
// reapply local edits
|
||||||
|
foreach (const DatagramSequencer::HighPriorityMessage& message, _sequencer.getHighPriorityMessages()) {
|
||||||
|
if (message.data.userType() == MetavoxelEditMessage::Type) {
|
||||||
|
message.data.value<MetavoxelEditMessage>().apply(_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelClient::clearReceiveRecordsBefore(int index) {
|
void MetavoxelClient::clearReceiveRecordsBefore(int index) {
|
||||||
|
@ -236,7 +250,7 @@ void MetavoxelClient::clearReceiveRecordsBefore(int index) {
|
||||||
void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) {
|
void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) {
|
||||||
int userType = message.userType();
|
int userType = message.userType();
|
||||||
if (userType == MetavoxelDeltaMessage::Type) {
|
if (userType == MetavoxelDeltaMessage::Type) {
|
||||||
// readDelta(_data, _receiveRecords.first().data, in);
|
_data.readDelta(_receiveRecords.first().data, in);
|
||||||
|
|
||||||
} else if (userType == QMetaType::QVariantList) {
|
} else if (userType == QMetaType::QVariantList) {
|
||||||
foreach (const QVariant& element, message.toList()) {
|
foreach (const QVariant& element, message.toList()) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void applyEdit(const MetavoxelEdit& edit);
|
void applyEdit(const MetavoxelEditMessage& edit);
|
||||||
|
|
||||||
void processData(const QByteArray& data, const HifiSockAddr& sender);
|
void processData(const QByteArray& data, const HifiSockAddr& sender);
|
||||||
|
|
||||||
|
@ -87,10 +87,11 @@ class MetavoxelClient : public QObject {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MetavoxelClient(const HifiSockAddr& address);
|
MetavoxelClient(const HifiSockAddr& address);
|
||||||
|
virtual ~MetavoxelClient();
|
||||||
|
|
||||||
const QUuid& getSessionID() const { return _sessionID; }
|
const QUuid& getSessionID() const { return _sessionID; }
|
||||||
|
|
||||||
void applyEdit(const MetavoxelEdit& edit);
|
void applyEdit(const MetavoxelEditMessage& edit);
|
||||||
|
|
||||||
void simulate(float deltaTime, MetavoxelVisitor& visitor);
|
void simulate(float deltaTime, MetavoxelVisitor& visitor);
|
||||||
|
|
||||||
|
|
|
@ -348,7 +348,7 @@ void MetavoxelEditor::applyValue(const glm::vec3& minimum, const glm::vec3& maxi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
OwnedAttributeValue value(attribute, attribute->createFromVariant(getValue()));
|
OwnedAttributeValue value(attribute, attribute->createFromVariant(getValue()));
|
||||||
MetavoxelEdit edit = { minimum, maximum, getGridSpacing(), value };
|
MetavoxelEditMessage edit = { minimum, maximum, getGridSpacing(), value };
|
||||||
Application::getInstance()->getMetavoxels()->applyEdit(edit);
|
Application::getInstance()->getMetavoxels()->applyEdit(edit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,12 @@ class DatagramSequencer : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
class HighPriorityMessage {
|
||||||
|
public:
|
||||||
|
QVariant data;
|
||||||
|
int firstPacketNumber;
|
||||||
|
};
|
||||||
|
|
||||||
DatagramSequencer(const QByteArray& datagramHeader = QByteArray());
|
DatagramSequencer(const QByteArray& datagramHeader = QByteArray());
|
||||||
|
|
||||||
/// Returns the packet number of the last packet sent.
|
/// Returns the packet number of the last packet sent.
|
||||||
|
@ -37,6 +43,9 @@ public:
|
||||||
/// Adds a message to the high priority queue. Will be sent with every outgoing packet until received.
|
/// Adds a message to the high priority queue. Will be sent with every outgoing packet until received.
|
||||||
void sendHighPriorityMessage(const QVariant& data);
|
void sendHighPriorityMessage(const QVariant& data);
|
||||||
|
|
||||||
|
/// Returns a reference to the list of high priority messages not yet acknowledged.
|
||||||
|
const QList<HighPriorityMessage>& getHighPriorityMessages() const { return _highPriorityMessages; }
|
||||||
|
|
||||||
/// Starts a new packet for transmission.
|
/// Starts a new packet for transmission.
|
||||||
/// \return a reference to the Bitstream to use for writing to the packet
|
/// \return a reference to the Bitstream to use for writing to the packet
|
||||||
Bitstream& startPacket();
|
Bitstream& startPacket();
|
||||||
|
@ -85,12 +94,6 @@ private:
|
||||||
bool operator<(const ReceiveRecord& other) const { return packetNumber < other.packetNumber; }
|
bool operator<(const ReceiveRecord& other) const { return packetNumber < other.packetNumber; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class HighPriorityMessage {
|
|
||||||
public:
|
|
||||||
QVariant data;
|
|
||||||
int firstPacketNumber;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Notes that the described send was acknowledged by the other party.
|
/// Notes that the described send was acknowledged by the other party.
|
||||||
void sendRecordAcknowledged(const SendRecord& record);
|
void sendRecordAcknowledged(const SendRecord& record);
|
||||||
|
|
||||||
|
|
|
@ -72,28 +72,20 @@ void MetavoxelData::guide(MetavoxelVisitor& visitor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelData::read(Bitstream& in) {
|
void MetavoxelData::read(Bitstream& in) {
|
||||||
// save the old roots and clear
|
// clear out any existing roots
|
||||||
QHash<AttributePointer, MetavoxelNode*> oldRoots = _roots;
|
decrementRootReferenceCounts();
|
||||||
_roots.clear();
|
_roots.clear();
|
||||||
|
|
||||||
// read in the new roots, reusing old ones where appropriate
|
// read in the new roots
|
||||||
int rootCount;
|
int rootCount;
|
||||||
in >> rootCount;
|
in >> rootCount;
|
||||||
for (int i = 0; i < rootCount; i++) {
|
for (int i = 0; i < rootCount; i++) {
|
||||||
AttributePointer attribute;
|
AttributePointer attribute;
|
||||||
in.getAttributeStreamer() >> attribute;
|
in.getAttributeStreamer() >> attribute;
|
||||||
MetavoxelNode* root = oldRoots.take(attribute);
|
MetavoxelNode*& root = _roots[attribute];
|
||||||
if (!root) {
|
|
||||||
root = new MetavoxelNode(attribute);
|
root = new MetavoxelNode(attribute);
|
||||||
}
|
|
||||||
_roots.insert(attribute, root);
|
|
||||||
root->read(attribute, in);
|
root->read(attribute, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear out the remaining old roots
|
|
||||||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = oldRoots.constBegin(); it != oldRoots.constEnd(); it++) {
|
|
||||||
it.value()->decrementReferenceCount(it.key());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelData::write(Bitstream& out) const {
|
void MetavoxelData::write(Bitstream& out) const {
|
||||||
|
@ -105,20 +97,23 @@ void MetavoxelData::write(Bitstream& out) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelData::readDelta(const MetavoxelData& reference, Bitstream& in) {
|
void MetavoxelData::readDelta(const MetavoxelData& reference, Bitstream& in) {
|
||||||
|
// shallow copy the reference
|
||||||
|
*this = reference;
|
||||||
|
|
||||||
int changedCount;
|
int changedCount;
|
||||||
in >> changedCount;
|
in >> changedCount;
|
||||||
for (int i = 0; i < changedCount; i++) {
|
for (int i = 0; i < changedCount; i++) {
|
||||||
AttributePointer attribute;
|
AttributePointer attribute;
|
||||||
in.getAttributeStreamer() >> attribute;
|
in.getAttributeStreamer() >> attribute;
|
||||||
MetavoxelNode*& root = _roots[attribute];
|
MetavoxelNode*& root = _roots[attribute];
|
||||||
if (!root) {
|
if (root) {
|
||||||
|
MetavoxelNode* oldRoot = root;
|
||||||
root = new MetavoxelNode(attribute);
|
root = new MetavoxelNode(attribute);
|
||||||
}
|
root->readDelta(attribute, *oldRoot, in);
|
||||||
MetavoxelNode* referenceRoot = reference._roots.value(attribute);
|
oldRoot->decrementReferenceCount(attribute);
|
||||||
if (referenceRoot) {
|
|
||||||
root->readDelta(attribute, *referenceRoot, in);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
root = new MetavoxelNode(attribute);
|
||||||
root->read(attribute, in);
|
root->read(attribute, in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +123,7 @@ void MetavoxelData::readDelta(const MetavoxelData& reference, Bitstream& in) {
|
||||||
for (int i = 0; i < removedCount; i++) {
|
for (int i = 0; i < removedCount; i++) {
|
||||||
AttributePointer attribute;
|
AttributePointer attribute;
|
||||||
in.getAttributeStreamer() >> attribute;
|
in.getAttributeStreamer() >> attribute;
|
||||||
|
_roots.take(attribute)->decrementReferenceCount(attribute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,22 +226,16 @@ bool MetavoxelNode::isLeaf() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelNode::read(const AttributePointer& attribute, Bitstream& in) {
|
void MetavoxelNode::read(const AttributePointer& attribute, Bitstream& in) {
|
||||||
|
clearChildren(attribute);
|
||||||
|
|
||||||
bool leaf;
|
bool leaf;
|
||||||
in >> leaf;
|
in >> leaf;
|
||||||
attribute->read(in, _attributeValue, leaf);
|
attribute->read(in, _attributeValue, leaf);
|
||||||
if (leaf) {
|
if (!leaf) {
|
||||||
clearChildren(attribute);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
void* childValues[CHILD_COUNT];
|
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
if (!_children[i]) {
|
|
||||||
_children[i] = new MetavoxelNode(attribute);
|
_children[i] = new MetavoxelNode(attribute);
|
||||||
}
|
|
||||||
_children[i]->read(attribute, in);
|
_children[i]->read(attribute, in);
|
||||||
childValues[i] = _children[i]->_attributeValue;
|
|
||||||
}
|
}
|
||||||
attribute->merge(_attributeValue, childValues);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,20 +251,28 @@ void MetavoxelNode::write(const AttributePointer& attribute, Bitstream& out) con
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelNode::readDelta(const AttributePointer& attribute, const MetavoxelNode& reference, Bitstream& in) {
|
void MetavoxelNode::readDelta(const AttributePointer& attribute, const MetavoxelNode& reference, Bitstream& in) {
|
||||||
|
clearChildren(attribute);
|
||||||
|
|
||||||
bool leaf;
|
bool leaf;
|
||||||
in >> leaf;
|
in >> leaf;
|
||||||
attribute->readDelta(in, _attributeValue, reference._attributeValue, leaf);
|
attribute->readDelta(in, _attributeValue, reference._attributeValue, leaf);
|
||||||
if (leaf) {
|
if (!leaf) {
|
||||||
clearChildren(attribute);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (reference.isLeaf()) {
|
if (reference.isLeaf()) {
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
_children[i] = new MetavoxelNode(attribute);
|
||||||
_children[i]->read(attribute, in);
|
_children[i]->read(attribute, in);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
bool changed;
|
||||||
|
in >> changed;
|
||||||
|
if (changed) {
|
||||||
|
_children[i] = new MetavoxelNode(attribute);
|
||||||
_children[i]->readDelta(attribute, *reference._children[i], in);
|
_children[i]->readDelta(attribute, *reference._children[i], in);
|
||||||
|
} else {
|
||||||
|
_children[i] = reference._children[i];
|
||||||
|
_children[i]->incrementReferenceCount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,11 +289,16 @@ void MetavoxelNode::writeDelta(const AttributePointer& attribute, const Metavoxe
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
if (_children[i] == reference._children[i]) {
|
||||||
|
out << false;
|
||||||
|
} else {
|
||||||
|
out << true;
|
||||||
_children[i]->writeDelta(attribute, *reference._children[i], out);
|
_children[i]->writeDelta(attribute, *reference._children[i], out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MetavoxelNode::decrementReferenceCount(const AttributePointer& attribute) {
|
void MetavoxelNode::decrementReferenceCount(const AttributePointer& attribute) {
|
||||||
if (--_referenceCount == 0) {
|
if (--_referenceCount == 0) {
|
||||||
|
@ -343,9 +345,16 @@ void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
||||||
visitation.info.isLeaf = visitation.allInputNodesLeaves();
|
visitation.info.isLeaf = visitation.allInputNodesLeaves();
|
||||||
bool keepGoing = visitation.visitor.visit(visitation.info);
|
bool keepGoing = visitation.visitor.visit(visitation.info);
|
||||||
for (int i = 0; i < visitation.outputNodes.size(); i++) {
|
for (int i = 0; i < visitation.outputNodes.size(); i++) {
|
||||||
const AttributeValue& value = visitation.info.outputValues[i];
|
AttributeValue& value = visitation.info.outputValues[i];
|
||||||
if (value.getAttribute()) {
|
if (!value.getAttribute()) {
|
||||||
visitation.outputNodes[i] = new MetavoxelNode(value);
|
continue;
|
||||||
|
}
|
||||||
|
MetavoxelNode*& node = visitation.outputNodes[i];
|
||||||
|
if (node && node->isLeaf() && value.getAttribute()->equal(value.getValue(), node->getAttributeValue())) {
|
||||||
|
// "set" to same value; disregard
|
||||||
|
value = AttributeValue();
|
||||||
|
} else {
|
||||||
|
node = new MetavoxelNode(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!keepGoing) {
|
if (!keepGoing) {
|
||||||
|
|
|
@ -67,6 +67,7 @@ public:
|
||||||
void setAttributeValue(const AttributeValue& attributeValue);
|
void setAttributeValue(const AttributeValue& attributeValue);
|
||||||
|
|
||||||
AttributeValue getAttributeValue(const AttributePointer& attribute) const;
|
AttributeValue getAttributeValue(const AttributePointer& attribute) const;
|
||||||
|
void* getAttributeValue() const { return _attributeValue; }
|
||||||
|
|
||||||
void mergeChildren(const AttributePointer& attribute);
|
void mergeChildren(const AttributePointer& attribute);
|
||||||
|
|
||||||
|
|
|
@ -12,16 +12,16 @@
|
||||||
class EditVisitor : public MetavoxelVisitor {
|
class EditVisitor : public MetavoxelVisitor {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EditVisitor(const MetavoxelEdit& edit);
|
EditVisitor(const MetavoxelEditMessage& edit);
|
||||||
|
|
||||||
virtual bool visit(MetavoxelInfo& info);
|
virtual bool visit(MetavoxelInfo& info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const MetavoxelEdit& _edit;
|
const MetavoxelEditMessage& _edit;
|
||||||
};
|
};
|
||||||
|
|
||||||
EditVisitor::EditVisitor(const MetavoxelEdit& edit) :
|
EditVisitor::EditVisitor(const MetavoxelEditMessage& edit) :
|
||||||
MetavoxelVisitor(QVector<AttributePointer>(), QVector<AttributePointer>() << edit.value.getAttribute()),
|
MetavoxelVisitor(QVector<AttributePointer>(), QVector<AttributePointer>() << edit.value.getAttribute()),
|
||||||
_edit(edit) {
|
_edit(edit) {
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ bool EditVisitor::visit(MetavoxelInfo& info) {
|
||||||
return true; // subdivide
|
return true; // subdivide
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelEdit::apply(MetavoxelData& data) const {
|
void MetavoxelEditMessage::apply(MetavoxelData& data) const {
|
||||||
EditVisitor visitor(*this);
|
EditVisitor visitor(*this);
|
||||||
data.guide(visitor);
|
data.guide(visitor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,13 @@
|
||||||
|
|
||||||
class MetavoxelData;
|
class MetavoxelData;
|
||||||
|
|
||||||
|
/// Requests to close the session.
|
||||||
|
class CloseSessionMessage {
|
||||||
|
STREAMABLE
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_STREAMABLE_METATYPE(CloseSessionMessage)
|
||||||
|
|
||||||
/// A message containing the state of a client.
|
/// A message containing the state of a client.
|
||||||
class ClientStateMessage {
|
class ClientStateMessage {
|
||||||
STREAMABLE
|
STREAMABLE
|
||||||
|
@ -33,7 +40,7 @@ class MetavoxelDeltaMessage {
|
||||||
DECLARE_STREAMABLE_METATYPE(MetavoxelDeltaMessage)
|
DECLARE_STREAMABLE_METATYPE(MetavoxelDeltaMessage)
|
||||||
|
|
||||||
/// A simple streamable edit.
|
/// A simple streamable edit.
|
||||||
class MetavoxelEdit {
|
class MetavoxelEditMessage {
|
||||||
STREAMABLE
|
STREAMABLE
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -46,6 +53,6 @@ public:
|
||||||
void apply(MetavoxelData& data) const;
|
void apply(MetavoxelData& data) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_STREAMABLE_METATYPE(MetavoxelEdit)
|
DECLARE_STREAMABLE_METATYPE(MetavoxelEditMessage)
|
||||||
|
|
||||||
#endif /* defined(__interface__MetavoxelMessages__) */
|
#endif /* defined(__interface__MetavoxelMessages__) */
|
||||||
|
|
Loading…
Reference in a new issue