3
0
Fork 0
mirror of https://github.com/lubosz/overte.git synced 2025-04-26 14:15:39 +02:00

Working on metavoxel streaming tests.

This commit is contained in:
Andrzej Kapolka 2014-06-19 18:15:17 -07:00
parent 7a9c0f0e6a
commit 24f535e02d
3 changed files with 196 additions and 54 deletions
libraries/metavoxels/src
tests/metavoxels/src

View file

@ -687,6 +687,23 @@ MetavoxelNode* MetavoxelData::createRoot(const AttributePointer& attribute) {
return root = new MetavoxelNode(attribute);
}
bool MetavoxelData::deepEquals(const MetavoxelData& other, const MetavoxelLOD& lod) const {
if (_size != other._size) {
return false;
}
if (_roots.size() != other._roots.size()) {
return false;
}
glm::vec3 minimum = getMinimum();
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) {
MetavoxelNode* otherNode = other._roots.value(it.key());
if (!(otherNode && it.value()->deepEquals(it.key(), *otherNode, minimum, _size, lod))) {
return false;
}
}
return true;
}
bool MetavoxelData::operator==(const MetavoxelData& other) const {
return _size == other._size && _roots == other._roots;
}
@ -1083,6 +1100,31 @@ void MetavoxelNode::clearChildren(const AttributePointer& attribute) {
}
}
bool MetavoxelNode::deepEquals(const AttributePointer& attribute, const MetavoxelNode& other,
const glm::vec3& minimum, float size, const MetavoxelLOD& lod) const {
if (!attribute->equal(_attributeValue, other._attributeValue)) {
return false;
}
if (!lod.shouldSubdivide(minimum, size, attribute->getLODThresholdMultiplier())) {
return true;
}
bool leaf = isLeaf(), otherLeaf = other.isLeaf();
if (leaf && otherLeaf) {
return true;
}
if (leaf || otherLeaf) {
return false;
}
float nextSize = size * 0.5f;
for (int i = 0; i < CHILD_COUNT; i++) {
glm::vec3 nextMinimum = getNextMinimum(minimum, nextSize, i);
if (!_children[i]->deepEquals(attribute, *(other._children[i]), nextMinimum, nextSize, lod)) {
return false;
}
}
return true;
}
int MetavoxelVisitor::encodeOrder(int first, int second, int third, int fourth,
int fifth, int sixth, int seventh, int eighth) {
return first | (second << 3) | (third << 6) | (fourth << 9) |
@ -1111,6 +1153,10 @@ int MetavoxelVisitor::encodeOrder(const glm::vec3& direction) {
indexDistances.at(6).index, indexDistances.at(7).index);
}
int MetavoxelVisitor::encodeRandomOrder() {
return DEFAULT_ORDER;
}
const int MetavoxelVisitor::DEFAULT_ORDER = encodeOrder(0, 1, 2, 3, 4, 5, 6, 7);
const int MetavoxelVisitor::STOP_RECURSION = 0;
const int MetavoxelVisitor::SHORT_CIRCUIT = -1;

View file

@ -126,6 +126,10 @@ public:
MetavoxelNode* getRoot(const AttributePointer& attribute) const { return _roots.value(attribute); }
MetavoxelNode* createRoot(const AttributePointer& attribute);
/// Performs a deep comparison between this data and the specified other (as opposed to the == operator, which does a
/// shallow comparison).
bool deepEquals(const MetavoxelData& other, const MetavoxelLOD& lod = MetavoxelLOD()) const;
bool operator==(const MetavoxelData& other) const;
bool operator!=(const MetavoxelData& other) const;
@ -214,6 +218,10 @@ public:
void clearChildren(const AttributePointer& attribute);
/// Performs a deep comparison between this and the specified other node.
bool deepEquals(const AttributePointer& attribute, const MetavoxelNode& other,
const glm::vec3& minimum, float size, const MetavoxelLOD& lod) const;
private:
Q_DISABLE_COPY(MetavoxelNode)
@ -250,6 +258,9 @@ public:
/// Encodes a visitation order sequence that visits each child as sorted along the specified direction.
static int encodeOrder(const glm::vec3& direction);
/// Returns a random visitation order sequence.
static int encodeRandomOrder();
/// The default visitation order.
static const int DEFAULT_ORDER;

View file

@ -32,6 +32,8 @@ static int datagramsSent = 0;
static int datagramsReceived = 0;
static int bytesSent = 0;
static int bytesReceived = 0;
static int maxDatagramsPerPacket = 0;
static int maxBytesPerPacket = 0;
static int highPriorityMessagesSent = 0;
static int highPriorityMessagesReceived = 0;
static int unreliableMessagesSent = 0;
@ -353,6 +355,7 @@ bool MetavoxelTests::run() {
qDebug() << "Sent" << streamedBytesSent << "streamed bytes, received" << streamedBytesReceived;
qDebug() << "Sent" << datagramsSent << "datagrams with" << bytesSent << "bytes, received" <<
datagramsReceived << "with" << bytesReceived << "bytes";
qDebug() << "Max" << maxDatagramsPerPacket << "datagrams," << maxBytesPerPacket << "bytes per packet";
qDebug() << "Created" << sharedObjectsCreated << "shared objects, destroyed" << sharedObjectsDestroyed;
qDebug() << "Performed" << objectMutationsPerformed << "object mutations";
qDebug() << "Created" << scriptObjectsCreated << "script objects, mutated" << scriptMutationsPerformed;
@ -373,7 +376,7 @@ bool MetavoxelTests::run() {
qDebug();
// clear the stats
datagramsSent = bytesSent = datagramsReceived = bytesReceived = 0;
datagramsSent = bytesSent = datagramsReceived = bytesReceived = maxDatagramsPerPacket = maxBytesPerPacket = 0;
// create client and server endpoints
Endpoint client(datagramHeader, Endpoint::METAVOXEL_CLIENT_MODE);
@ -391,6 +394,7 @@ bool MetavoxelTests::run() {
qDebug() << "Sent" << datagramsSent << "datagrams with" << bytesSent << "bytes, received" <<
datagramsReceived << "with" << bytesReceived << "bytes";
qDebug() << "Max" << maxDatagramsPerPacket << "datagrams," << maxBytesPerPacket << "bytes per packet";
}
qDebug() << "All tests passed!";
@ -407,6 +411,34 @@ static SharedObjectPointer createRandomSharedObject() {
}
}
class RandomVisitor : public MetavoxelVisitor {
public:
int leafCount;
RandomVisitor();
virtual int visit(MetavoxelInfo& info);
};
RandomVisitor::RandomVisitor() :
MetavoxelVisitor(QVector<AttributePointer>(),
QVector<AttributePointer>() << AttributeRegistry::getInstance()->getColorAttribute()),
leafCount(0) {
}
const float MAXIMUM_LEAF_SIZE = 0.5f;
const float MINIMUM_LEAF_SIZE = 0.25f;
int RandomVisitor::visit(MetavoxelInfo& info) {
if (info.size > MAXIMUM_LEAF_SIZE || (info.size > MINIMUM_LEAF_SIZE && randomBoolean())) {
return DEFAULT_ORDER;
}
info.outputValues[0] = OwnedAttributeValue(_outputs.at(0), encodeInline<QRgb>(qRgb(randIntInRange(0, 255),
randIntInRange(0, 255), randIntInRange(0, 255))));
leafCount++;
return STOP_RECURSION;
}
Endpoint::Endpoint(const QByteArray& datagramHeader, Mode mode) :
_mode(mode),
_sequencer(new DatagramSequencer(datagramHeader, this)),
@ -434,6 +466,12 @@ Endpoint::Endpoint(const QByteArray& datagramHeader, Mode mode) :
return;
}
if (mode == METAVOXEL_SERVER_MODE) {
_data.expand();
_data.expand();
RandomVisitor visitor;
_data.guide(visitor);
qDebug() << "Created" << visitor.leafCount << "base leaves";
return;
}
// create the object that represents out delta-encoded state
@ -552,6 +590,36 @@ static bool messagesEqual(const QVariant& firstMessage, const QVariant& secondMe
}
}
class MutateVisitor : public MetavoxelVisitor {
public:
MutateVisitor();
virtual int visit(MetavoxelInfo& info);
private:
bool _finished;
};
MutateVisitor::MutateVisitor() :
MetavoxelVisitor(QVector<AttributePointer>(),
QVector<AttributePointer>() << AttributeRegistry::getInstance()->getColorAttribute()),
_finished(false) {
}
int MutateVisitor::visit(MetavoxelInfo& info) {
if (_finished) {
return STOP_RECURSION;
}
if (info.size > MAXIMUM_LEAF_SIZE || (info.size > MINIMUM_LEAF_SIZE && randomBoolean())) {
return encodeRandomOrder();
}
info.outputValues[0] = OwnedAttributeValue(_outputs.at(0), encodeInline<QRgb>(qRgb(randIntInRange(0, 255),
randIntInRange(0, 255), randIntInRange(0, 255))));
_finished = true;
return STOP_RECURSION;
}
bool Endpoint::simulate(int iterationNumber) {
// update/send our delayed datagrams
for (QList<QPair<QByteArray, int> >::iterator it = _delayedDatagrams.begin(); it != _delayedDatagrams.end(); ) {
@ -565,6 +633,8 @@ bool Endpoint::simulate(int iterationNumber) {
}
}
int oldDatagramsSent = datagramsSent;
int oldBytesSent = bytesSent;
if (_mode == METAVOXEL_CLIENT_MODE) {
Bitstream& out = _sequencer->startPacket();
@ -575,69 +645,74 @@ bool Endpoint::simulate(int iterationNumber) {
// record the send
SendRecord record = { _sequencer->getOutgoingPacketNumber(), SharedObjectPointer(), MetavoxelData(), _lod };
_sendRecords.append(record);
return false;
}
if (_mode == METAVOXEL_SERVER_MODE) {
// wait until we have a valid lod
} else if (_mode == METAVOXEL_SERVER_MODE) {
// make a random change
MutateVisitor visitor;
_data.guide(visitor);
// wait until we have a valid lod before sending
if (!_lod.isValid()) {
return false;
}
Bitstream& out = _sequencer->startPacket();
out << QVariant::fromValue(MetavoxelDeltaMessage());
_data.writeDelta(_sendRecords.first().data, _sendRecords.first().lod, out, _lod);
_sequencer->endPacket();
// record the send
SendRecord record = { _sequencer->getOutgoingPacketNumber(), SharedObjectPointer(), _data, _lod };
SendRecord record = { _sequencer->getOutgoingPacketNumber() + 1, SharedObjectPointer(), _data, _lod };
_sendRecords.append(record);
return false;
}
// enqueue some number of high priority messages
const float MIN_HIGH_PRIORITY_MESSAGES = 0.0f;
const float MAX_HIGH_PRIORITY_MESSAGES = 2.0f;
_highPriorityMessagesToSend += randFloatInRange(MIN_HIGH_PRIORITY_MESSAGES, MAX_HIGH_PRIORITY_MESSAGES);
while (_highPriorityMessagesToSend >= 1.0f) {
QVariant message = createRandomMessage();
_highPriorityMessagesSent.append(message);
_sequencer->sendHighPriorityMessage(message);
highPriorityMessagesSent++;
_highPriorityMessagesToSend -= 1.0f;
}
// and some number of reliable messages
const float MIN_RELIABLE_MESSAGES = 0.0f;
const float MAX_RELIABLE_MESSAGES = 4.0f;
_reliableMessagesToSend += randFloatInRange(MIN_RELIABLE_MESSAGES, MAX_RELIABLE_MESSAGES);
while (_reliableMessagesToSend >= 1.0f) {
QVariant message = createRandomMessage();
_reliableMessagesSent.append(message);
_sequencer->getReliableOutputChannel()->sendMessage(message);
reliableMessagesSent++;
_reliableMessagesToSend -= 1.0f;
}
// tweak the local state
_localState = mutate(_localState);
// send a packet
try {
Bitstream& out = _sequencer->startPacket();
SequencedTestMessage message = { iterationNumber, createRandomMessage(), _localState };
_unreliableMessagesSent.append(message);
unreliableMessagesSent++;
out << message;
_sequencer->endPacket();
} else {
// enqueue some number of high priority messages
const float MIN_HIGH_PRIORITY_MESSAGES = 0.0f;
const float MAX_HIGH_PRIORITY_MESSAGES = 2.0f;
_highPriorityMessagesToSend += randFloatInRange(MIN_HIGH_PRIORITY_MESSAGES, MAX_HIGH_PRIORITY_MESSAGES);
while (_highPriorityMessagesToSend >= 1.0f) {
QVariant message = createRandomMessage();
_highPriorityMessagesSent.append(message);
_sequencer->sendHighPriorityMessage(message);
highPriorityMessagesSent++;
_highPriorityMessagesToSend -= 1.0f;
}
// and some number of reliable messages
const float MIN_RELIABLE_MESSAGES = 0.0f;
const float MAX_RELIABLE_MESSAGES = 4.0f;
_reliableMessagesToSend += randFloatInRange(MIN_RELIABLE_MESSAGES, MAX_RELIABLE_MESSAGES);
while (_reliableMessagesToSend >= 1.0f) {
QVariant message = createRandomMessage();
_reliableMessagesSent.append(message);
_sequencer->getReliableOutputChannel()->sendMessage(message);
reliableMessagesSent++;
_reliableMessagesToSend -= 1.0f;
}
// tweak the local state
_localState = mutate(_localState);
// send a packet
try {
Bitstream& out = _sequencer->startPacket();
SequencedTestMessage message = { iterationNumber, createRandomMessage(), _localState };
_unreliableMessagesSent.append(message);
unreliableMessagesSent++;
out << message;
_sequencer->endPacket();
} catch (const QString& message) {
qDebug() << message;
return true;
}
} catch (const QString& message) {
qDebug() << message;
return true;
// record the send
SendRecord record = { _sequencer->getOutgoingPacketNumber(), _localState };
_sendRecords.append(record);
}
// record the send
SendRecord record = { _sequencer->getOutgoingPacketNumber(), _localState };
_sendRecords.append(record);
maxDatagramsPerPacket = qMax(maxDatagramsPerPacket, datagramsSent - oldDatagramsSent);
maxBytesPerPacket = qMax(maxBytesPerPacket, bytesSent - oldBytesSent);
return false;
}
@ -692,9 +767,19 @@ void Endpoint::readMessage(Bitstream& in) {
in >> message;
handleMessage(message, in);
// deep-compare data to sent version
int packetNumber = _sequencer->getIncomingPacketNumber();
foreach (const SendRecord& sendRecord, _other->_sendRecords) {
if (sendRecord.packetNumber == packetNumber) {
if (!sendRecord.data.deepEquals(_data, _sendRecords.first().lod)) {
throw QString("Sent/received metavoxel data mismatch.");
}
break;
}
}
// record the receipt
ReceiveRecord record = { _sequencer->getIncomingPacketNumber(), SharedObjectPointer(),
_data, _sendRecords.first().lod };
ReceiveRecord record = { packetNumber, SharedObjectPointer(), _data, _sendRecords.first().lod };
_receiveRecords.append(record);
return;
}