Basic network simulation for metavoxels.

This commit is contained in:
Andrzej Kapolka 2014-10-20 18:43:41 -07:00
parent b796e1bedd
commit 45fb31cd08
5 changed files with 132 additions and 5 deletions

View file

@ -45,6 +45,7 @@
#include "ui/AttachmentsDialog.h"
#include "ui/InfoView.h"
#include "ui/MetavoxelEditor.h"
#include "ui/MetavoxelNetworkSimulator.h"
#include "ui/ModelsBrowser.h"
#include "ui/LoginDialog.h"
#include "ui/NodeBounds.h"
@ -431,6 +432,8 @@ Menu::Menu() :
QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels");
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false,
Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData()));
addActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::NetworkSimulator, 0, this,
SLOT(showMetavoxelNetworkSimulator()));
QMenu* handOptionsMenu = developerMenu->addMenu("Hands");
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false);
@ -1378,6 +1381,13 @@ void Menu::showMetavoxelEditor() {
_MetavoxelEditor->raise();
}
void Menu::showMetavoxelNetworkSimulator() {
if (!_metavoxelNetworkSimulator) {
_metavoxelNetworkSimulator = new MetavoxelNetworkSimulator();
}
_metavoxelNetworkSimulator->raise();
}
void Menu::showScriptEditor() {
if(!_ScriptEditor || !_ScriptEditor->isVisible()) {
_ScriptEditor = new ScriptEditorWindow();

View file

@ -78,6 +78,7 @@ class AttachmentsDialog;
class BandwidthDialog;
class LodToolsDialog;
class MetavoxelEditor;
class MetavoxelNetworkSimulator;
class ChatWindow;
class OctreeStatsDialog;
class MenuItemProperties;
@ -218,6 +219,7 @@ private slots:
void cycleFrustumRenderMode();
void runTests();
void showMetavoxelEditor();
void showMetavoxelNetworkSimulator();
void showScriptEditor();
void showChat();
void toggleConsole();
@ -274,6 +276,7 @@ private:
FrustumDrawMode _frustumDrawMode;
ViewFrustumOffset _viewFrustumOffset;
QPointer<MetavoxelEditor> _MetavoxelEditor;
QPointer<MetavoxelNetworkSimulator> _metavoxelNetworkSimulator;
QPointer<ScriptEditorWindow> _ScriptEditor;
QPointer<ChatWindow> _chatWindow;
QDialog* _jsConsole;
@ -430,6 +433,7 @@ namespace MenuOption {
const QString MuteEnvironment = "Mute Environment";
const QString MyLocations = "My Locations...";
const QString NameLocation = "Name this location";
const QString NetworkSimulator = "Network Simulator...";
const QString NewVoxelCullingMode = "New Voxel Culling Mode";
const QString ObeyEnvironmentalGravity = "Obey Environmental Gravity";
const QString OctreeStats = "Voxel and Entity Statistics";

View file

@ -39,6 +39,13 @@ REGISTER_META_OBJECT(StaticModelRenderer)
static int bufferPointVectorMetaTypeId = qRegisterMetaType<BufferPointVector>();
MetavoxelSystem::NetworkSimulation::NetworkSimulation(float dropRate, float repeatRate, int minimumDelay, int maximumDelay) :
dropRate(dropRate),
repeatRate(repeatRate),
minimumDelay(minimumDelay),
maximumDelay(maximumDelay) {
}
void MetavoxelSystem::init() {
MetavoxelClientManager::init();
DefaultMetavoxelRendererImplementation::init();
@ -61,6 +68,16 @@ MetavoxelLOD MetavoxelSystem::getLOD() {
return _lod;
}
void MetavoxelSystem::setNetworkSimulation(const NetworkSimulation& simulation) {
QWriteLocker locker(&_networkSimulationLock);
_networkSimulation = simulation;
}
MetavoxelSystem::NetworkSimulation MetavoxelSystem::getNetworkSimulation() {
QReadLocker locker(&_networkSimulationLock);
return _networkSimulation;
}
class SimulateVisitor : public MetavoxelVisitor {
public:
@ -692,10 +709,53 @@ MetavoxelData MetavoxelSystemClient::getAugmentedData() {
return _augmentedData;
}
class ReceiveDelayer : public QObject {
public:
ReceiveDelayer(const SharedNodePointer& node, const QByteArray& packet);
protected:
virtual void timerEvent(QTimerEvent* event);
private:
SharedNodePointer _node;
QByteArray _packet;
};
ReceiveDelayer::ReceiveDelayer(const SharedNodePointer& node, const QByteArray& packet) :
_node(node),
_packet(packet) {
}
void ReceiveDelayer::timerEvent(QTimerEvent* event) {
QMutexLocker locker(&_node->getMutex());
MetavoxelClient* client = static_cast<MetavoxelClient*>(_node->getLinkedData());
if (client) {
QMetaObject::invokeMethod(&client->getSequencer(), "receivedDatagram", Q_ARG(const QByteArray&, _packet));
}
deleteLater();
}
int MetavoxelSystemClient::parseData(const QByteArray& packet) {
// process through sequencer
QMetaObject::invokeMethod(&_sequencer, "receivedDatagram", Q_ARG(const QByteArray&, packet));
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::METAVOXELS).updateValue(packet.size());
MetavoxelSystem::NetworkSimulation simulation = Application::getInstance()->getMetavoxels()->getNetworkSimulation();
if (randFloat() < simulation.dropRate) {
return packet.size();
}
int count = (randFloat() < simulation.repeatRate) ? 2 : 1;
for (int i = 0; i < count; i++) {
int delay = randIntInRange(simulation.minimumDelay, simulation.maximumDelay);
if (delay > 0) {
ReceiveDelayer* delayer = new ReceiveDelayer(_node, packet);
delayer->startTimer(delay);
} else {
QMetaObject::invokeMethod(&_sequencer, "receivedDatagram", Q_ARG(const QByteArray&, packet));
}
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::METAVOXELS).updateValue(packet.size());
}
return packet.size();
}
@ -774,9 +834,46 @@ void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) {
QThreadPool::globalInstance()->start(new Augmenter(_node, _data, getAugmentedData(), _remoteDataLOD));
}
class SendDelayer : public QObject {
public:
SendDelayer(const SharedNodePointer& node, const QByteArray& data);
virtual void timerEvent(QTimerEvent* event);
private:
SharedNodePointer _node;
QByteArray _data;
};
SendDelayer::SendDelayer(const SharedNodePointer& node, const QByteArray& data) :
_node(node),
_data(data) {
}
void SendDelayer::timerEvent(QTimerEvent* event) {
NodeList::getInstance()->writeDatagram(_data, _node);
deleteLater();
}
void MetavoxelSystemClient::sendDatagram(const QByteArray& data) {
NodeList::getInstance()->writeDatagram(data, _node);
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size());
MetavoxelSystem::NetworkSimulation simulation = Application::getInstance()->getMetavoxels()->getNetworkSimulation();
if (randFloat() < simulation.dropRate) {
return;
}
int count = (randFloat() < simulation.repeatRate) ? 2 : 1;
for (int i = 0; i < count; i++) {
int delay = randIntInRange(simulation.minimumDelay, simulation.maximumDelay);
if (delay > 0) {
SendDelayer* delayer = new SendDelayer(_node, data);
delayer->startTimer(delay);
} else {
NodeList::getInstance()->writeDatagram(data, _node);
}
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size());
}
}
BufferData::~BufferData() {

View file

@ -31,12 +31,25 @@ class MetavoxelSystem : public MetavoxelClientManager {
public:
class NetworkSimulation {
public:
float dropRate;
float repeatRate;
int minimumDelay;
int maximumDelay;
NetworkSimulation(float dropRate = 0.0f, float repeatRate = 0.0f, int minimumDelay = 0, int maximumDelay = 0);
};
virtual void init();
virtual MetavoxelLOD getLOD();
const Frustum& getFrustum() const { return _frustum; }
void setNetworkSimulation(const NetworkSimulation& simulation);
NetworkSimulation getNetworkSimulation();
const AttributePointer& getPointBufferAttribute() { return _pointBufferAttribute; }
const AttributePointer& getHeightfieldBufferAttribute() { return _heightfieldBufferAttribute; }
const AttributePointer& getVoxelBufferAttribute() { return _voxelBufferAttribute; }
@ -93,6 +106,9 @@ private:
MetavoxelLOD _lod;
QReadWriteLock _lodLock;
Frustum _frustum;
NetworkSimulation _networkSimulation;
QReadWriteLock _networkSimulationLock;
};
/// Generic abstract base class for objects that handle a signal.

View file

@ -32,7 +32,7 @@ public:
PacketRecord* baselineReceiveRecord = NULL);
virtual ~Endpoint();
const DatagramSequencer& getSequencer() const { return _sequencer; }
DatagramSequencer& getSequencer() { return _sequencer; }
virtual void update();