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

View file

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

View file

@ -39,6 +39,13 @@ REGISTER_META_OBJECT(StaticModelRenderer)
static int bufferPointVectorMetaTypeId = qRegisterMetaType<BufferPointVector>(); 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() { void MetavoxelSystem::init() {
MetavoxelClientManager::init(); MetavoxelClientManager::init();
DefaultMetavoxelRendererImplementation::init(); DefaultMetavoxelRendererImplementation::init();
@ -61,6 +68,16 @@ MetavoxelLOD MetavoxelSystem::getLOD() {
return _lod; 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 { class SimulateVisitor : public MetavoxelVisitor {
public: public:
@ -692,10 +709,53 @@ MetavoxelData MetavoxelSystemClient::getAugmentedData() {
return _augmentedData; 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) { int MetavoxelSystemClient::parseData(const QByteArray& packet) {
// process through sequencer // process through sequencer
QMetaObject::invokeMethod(&_sequencer, "receivedDatagram", Q_ARG(const QByteArray&, packet)); MetavoxelSystem::NetworkSimulation simulation = Application::getInstance()->getMetavoxels()->getNetworkSimulation();
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::METAVOXELS).updateValue(packet.size()); 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(); return packet.size();
} }
@ -774,9 +834,46 @@ void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) {
QThreadPool::globalInstance()->start(new Augmenter(_node, _data, getAugmentedData(), _remoteDataLOD)); 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) { void MetavoxelSystemClient::sendDatagram(const QByteArray& data) {
NodeList::getInstance()->writeDatagram(data, _node); MetavoxelSystem::NetworkSimulation simulation = Application::getInstance()->getMetavoxels()->getNetworkSimulation();
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size()); 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() { BufferData::~BufferData() {

View file

@ -31,12 +31,25 @@ class MetavoxelSystem : public MetavoxelClientManager {
public: 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 void init();
virtual MetavoxelLOD getLOD(); virtual MetavoxelLOD getLOD();
const Frustum& getFrustum() const { return _frustum; } const Frustum& getFrustum() const { return _frustum; }
void setNetworkSimulation(const NetworkSimulation& simulation);
NetworkSimulation getNetworkSimulation();
const AttributePointer& getPointBufferAttribute() { return _pointBufferAttribute; } const AttributePointer& getPointBufferAttribute() { return _pointBufferAttribute; }
const AttributePointer& getHeightfieldBufferAttribute() { return _heightfieldBufferAttribute; } const AttributePointer& getHeightfieldBufferAttribute() { return _heightfieldBufferAttribute; }
const AttributePointer& getVoxelBufferAttribute() { return _voxelBufferAttribute; } const AttributePointer& getVoxelBufferAttribute() { return _voxelBufferAttribute; }
@ -93,6 +106,9 @@ private:
MetavoxelLOD _lod; MetavoxelLOD _lod;
QReadWriteLock _lodLock; QReadWriteLock _lodLock;
Frustum _frustum; Frustum _frustum;
NetworkSimulation _networkSimulation;
QReadWriteLock _networkSimulationLock;
}; };
/// Generic abstract base class for objects that handle a signal. /// Generic abstract base class for objects that handle a signal.

View file

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