diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index 36b06d38cf..6039a15919 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -6,6 +6,8 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // +#include + #include #include @@ -13,8 +15,13 @@ #include "MetavoxelServer.h" +const int SEND_INTERVAL = 50; + MetavoxelServer::MetavoxelServer(const unsigned char* dataBuffer, int numBytes) : ThreadedAssignment(dataBuffer, numBytes) { + + _sendTimer.setSingleShot(true); + connect(&_sendTimer, SIGNAL(timeout()), SLOT(sendDeltas())); } void MetavoxelServer::removeSession(const QUuid& sessionId) { @@ -23,8 +30,11 @@ void MetavoxelServer::removeSession(const QUuid& sessionId) { void MetavoxelServer::run() { commonInit("metavoxel-server", NODE_TYPE_METAVOXEL_SERVER); -} + _lastSend = QDateTime::currentMSecsSinceEpoch(); + _sendTimer.start(SEND_INTERVAL); +} + void MetavoxelServer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) { switch (dataByteArray.at(0)) { case PACKET_TYPE_METAVOXEL_DATA: @@ -37,6 +47,20 @@ void MetavoxelServer::processDatagram(const QByteArray& dataByteArray, const Hif } } +void MetavoxelServer::sendDeltas() { + // send deltas for all sessions + foreach (MetavoxelSession* session, _sessions) { + session->sendDelta(); + } + + // restart the send timer + qint64 now = QDateTime::currentMSecsSinceEpoch(); + int elapsed = now - _lastSend; + _lastSend = now; + + _sendTimer.start(qMax(0, 2 * SEND_INTERVAL - elapsed)); +} + void MetavoxelServer::processData(const QByteArray& data, const HifiSockAddr& sender) { // read the session id int headerPlusIDSize; @@ -66,6 +90,11 @@ MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const QUuid& session connect(&_sequencer, SIGNAL(readyToWrite(const QByteArray&)), SLOT(sendData(const QByteArray&))); connect(&_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readPacket(Bitstream&))); + connect(&_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(clearSendRecordsBefore(int))); + + // insert the baseline send record + SendRecord record = { 0 }; + _sendRecords.append(record); } void MetavoxelSession::receivedData(const QByteArray& data, const HifiSockAddr& sender) { @@ -79,6 +108,15 @@ void MetavoxelSession::receivedData(const QByteArray& data, const HifiSockAddr& _sequencer.receivedDatagram(data); } +void MetavoxelSession::sendDelta() { + Bitstream& out = _sequencer.startPacket(); + _sequencer.endPacket(); + + // record the send + SendRecord record = { _sequencer.getOutgoingPacketNumber() }; + _sendRecords.append(record); +} + void MetavoxelSession::timedOut() { qDebug() << "Session timed out [sessionId=" << _sessionId << ", sender=" << _sender << "]\n"; _server->removeSession(_sessionId); @@ -89,11 +127,31 @@ void MetavoxelSession::sendData(const QByteArray& data) { } void MetavoxelSession::readPacket(Bitstream& in) { - QVariant msg; - in >> msg; - glm::vec3 position = msg.value().position; - qDebug() << position.x << " " << position.y << " " << position.z << "\n"; - - Bitstream& out = _sequencer.startPacket(); - _sequencer.endPacket(); + QVariant message; + in >> message; + handleMessage(message); +} + +void MetavoxelSession::clearSendRecordsBefore(int packetNumber) { + if (_sendRecords.isEmpty()) { + return; + } + int index = packetNumber - _sendRecords.first().packetNumber; + if (index <= 0 || index >= _sendRecords.size()) { + return; + } + _sendRecords.erase(_sendRecords.begin(), _sendRecords.begin() + index); +} + +void MetavoxelSession::handleMessage(const QVariant& message) { + int userType = message.userType(); + if (userType == ClientStateMessage::Type) { + ClientStateMessage state = message.value(); + _position = state.position; + + } else if (userType == QMetaType::QVariantList) { + foreach (const QVariant& element, message.toList()) { + handleMessage(element); + } + } } diff --git a/assignment-client/src/metavoxels/MetavoxelServer.h b/assignment-client/src/metavoxels/MetavoxelServer.h index 33735d4a45..b5bfb63232 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.h +++ b/assignment-client/src/metavoxels/MetavoxelServer.h @@ -10,6 +10,7 @@ #define __hifi__MetavoxelServer__ #include +#include #include #include @@ -35,12 +36,19 @@ public: virtual void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); +private slots: + + void sendDeltas(); + private: void processData(const QByteArray& data, const HifiSockAddr& sender); MetavoxelData _data; + QTimer _sendTimer; + qint64 _lastSend; + QHash _sessions; }; @@ -54,6 +62,8 @@ public: void receivedData(const QByteArray& data, const HifiSockAddr& sender); + void sendDelta(); + private slots: void timedOut(); @@ -62,8 +72,17 @@ private slots: void readPacket(Bitstream& in); + void clearSendRecordsBefore(int packetNumber); + private: + void handleMessage(const QVariant& message); + + class SendRecord { + public: + int packetNumber; + }; + MetavoxelServer* _server; QUuid _sessionId; @@ -71,6 +90,10 @@ private: DatagramSequencer _sequencer; HifiSockAddr _sender; + + glm::vec3 _position; + + QList _sendRecords; }; #endif /* defined(__hifi__MetavoxelServer__) */ diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 61f4db6d95..01328df80e 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -194,7 +194,7 @@ MetavoxelClient::MetavoxelClient(const HifiSockAddr& address) : void MetavoxelClient::simulate(float deltaTime) { Bitstream& out = _sequencer.startPacket(); - ClientStateMessage state = { glm::vec3(0.5f, 0.5f, 1.0f) }; + ClientStateMessage state = { Application::getInstance()->getCamera()->getPosition() }; out << QVariant::fromValue(state); _sequencer.endPacket(); } diff --git a/libraries/metavoxels/src/DatagramSequencer.cpp b/libraries/metavoxels/src/DatagramSequencer.cpp index 0694f2b370..a97425036c 100644 --- a/libraries/metavoxels/src/DatagramSequencer.cpp +++ b/libraries/metavoxels/src/DatagramSequencer.cpp @@ -140,6 +140,9 @@ void DatagramSequencer::sendRecordAcknowledged(const SendRecord& record) { _receiveRecords.erase(_receiveRecords.begin(), it + 1); } _outputStream.persistWriteMappings(record.mappings); + + // notify any listeners + emit sendAcknowledged(record.packetNumber); } void DatagramSequencer::sendPacket(const QByteArray& packet) { diff --git a/libraries/metavoxels/src/DatagramSequencer.h b/libraries/metavoxels/src/DatagramSequencer.h index 629aeabf39..28318bd2e6 100644 --- a/libraries/metavoxels/src/DatagramSequencer.h +++ b/libraries/metavoxels/src/DatagramSequencer.h @@ -25,6 +25,9 @@ public: DatagramSequencer(const QByteArray& datagramHeader = QByteArray()); + /// Returns the packet number of the last packet sent. + int getOutgoingPacketNumber() const { return _outgoingPacketNumber; } + /// Starts a new packet for transmission. /// \return a reference to the Bitstream to use for writing to the packet Bitstream& startPacket(); @@ -44,6 +47,9 @@ signals: /// Emitted when a packet is available to read. void readyToRead(Bitstream& input); + /// Emitted when a sent packet has been acknowledged by the remote side. + void sendAcknowledged(int packetNumber); + private: class SendRecord {