Working on ability to set a region of the metavoxel data directly.

This commit is contained in:
Andrzej Kapolka 2014-04-02 12:40:01 -07:00
parent 7f6dc7ac2f
commit 40844d2000
6 changed files with 139 additions and 6 deletions

View file

@ -95,6 +95,8 @@ MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const SharedNodePoin
connect(&_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readPacket(Bitstream&))); connect(&_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readPacket(Bitstream&)));
connect(&_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(clearSendRecordsBefore(int))); connect(&_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(clearSendRecordsBefore(int)));
connect(&_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)), SLOT(handleMessage(const QVariant&))); connect(&_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)), SLOT(handleMessage(const QVariant&)));
connect(_sequencer.getReliableInputChannel(), SIGNAL(receivedMessage(const QVariant&)),
SLOT(handleMessage(const QVariant&)));
// insert the baseline send record // insert the baseline send record
SendRecord record = { 0 }; SendRecord record = { 0 };

View file

@ -920,6 +920,13 @@ public:
_Pragma(STRINGIFY(unused(_TypePtr##X))) _Pragma(STRINGIFY(unused(_TypePtr##X)))
#endif #endif
/// Registers a simple type and its streamer.
template<class T> int registerSimpleMetaType() {
int type = qRegisterMetaType<T>();
Bitstream::registerTypeStreamer(type, new SimpleTypeStreamer<T>());
return type;
}
/// Registers a streamable type and its streamer. /// Registers a streamable type and its streamer.
template<class T> int registerStreamableMetaType() { template<class T> int registerStreamableMetaType() {
int type = qRegisterMetaType<T>(); int type = qRegisterMetaType<T>();

View file

@ -24,6 +24,8 @@ REGISTER_META_OBJECT(Spanner)
REGISTER_META_OBJECT(Sphere) REGISTER_META_OBJECT(Sphere)
REGISTER_META_OBJECT(StaticModel) REGISTER_META_OBJECT(StaticModel)
static int metavoxelDataTypeId = registerSimpleMetaType<MetavoxelData>();
MetavoxelLOD::MetavoxelLOD(const glm::vec3& position, float threshold) : MetavoxelLOD::MetavoxelLOD(const glm::vec3& position, float threshold) :
position(position), position(position),
threshold(threshold) { threshold(threshold) {
@ -327,6 +329,67 @@ const int Y_MAXIMUM_FLAG = 2;
const int Z_MAXIMUM_FLAG = 4; const int Z_MAXIMUM_FLAG = 4;
const int MAXIMUM_FLAG_MASK = X_MAXIMUM_FLAG | Y_MAXIMUM_FLAG | Z_MAXIMUM_FLAG; const int MAXIMUM_FLAG_MASK = X_MAXIMUM_FLAG | Y_MAXIMUM_FLAG | Z_MAXIMUM_FLAG;
static glm::vec3 getNextMinimum(const glm::vec3& minimum, float nextSize, int index) {
return minimum + glm::vec3(
(index & X_MAXIMUM_FLAG) ? nextSize : 0.0f,
(index & Y_MAXIMUM_FLAG) ? nextSize : 0.0f,
(index & Z_MAXIMUM_FLAG) ? nextSize : 0.0f);
}
static void setNode(const AttributePointer& attribute, MetavoxelNode*& node, MetavoxelNode* other) {
if (node) {
node->decrementReferenceCount(attribute);
}
(node = other)->incrementReferenceCount();
}
static void setNode(const AttributeValue& value, MetavoxelNode*& node, const glm::vec3& minimum, float size,
MetavoxelNode* other, const glm::vec3& otherMinimum, float otherSize) {
if (otherSize >= size) {
setNode(value.getAttribute(), node, other);
return;
}
if (!node) {
node = new MetavoxelNode(value);
}
int index = 0;
float otherHalfSize = otherSize * 0.5f;
float nextSize = size * 0.5f;
if (otherMinimum.x + otherHalfSize >= minimum.x + nextSize) {
index |= X_MAXIMUM_FLAG;
}
if (otherMinimum.y + otherHalfSize >= minimum.y + nextSize) {
index |= Y_MAXIMUM_FLAG;
}
if (otherMinimum.z + otherHalfSize >= minimum.z + nextSize) {
index |= Z_MAXIMUM_FLAG;
}
if (node->isLeaf()) {
for (int i = 1; i < MetavoxelNode::CHILD_COUNT; i++) {
node->setChild((index + i) % MetavoxelNode::CHILD_COUNT, new MetavoxelNode(
node->getAttributeValue(value.getAttribute())));
}
}
MetavoxelNode* nextNode = node->getChild(index);
setNode(node->getAttributeValue(value.getAttribute()), nextNode, getNextMinimum(minimum, nextSize, index),
nextSize, other, otherMinimum, otherSize);
node->setChild(index, nextNode);
}
void MetavoxelData::set(const glm::vec3& minimum, const MetavoxelData& data) {
// expand to fit the entire data
Box bounds = minimum + glm::vec3(data.getSize(), data.getSize(), data.getSize());
while (!getBounds().contains(bounds)) {
expand();
}
// set each attribute separately
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = data._roots.constBegin();
it != data._roots.constEnd(); it++) {
setNode(it.key(), _roots[it.key()], getMinimum(), getSize(), it.value(), minimum, data.getSize());
}
}
static int getOppositeIndex(int index) { static int getOppositeIndex(int index) {
return index ^ MAXIMUM_FLAG_MASK; return index ^ MAXIMUM_FLAG_MASK;
} }
@ -511,6 +574,14 @@ MetavoxelNode* MetavoxelData::createRoot(const AttributePointer& attribute) {
return root = new MetavoxelNode(attribute); return root = new MetavoxelNode(attribute);
} }
bool MetavoxelData::operator==(const MetavoxelData& other) const {
return _size == other._size && _roots == other._roots;
}
bool MetavoxelData::operator!=(const MetavoxelData& other) const {
return _size != other._size || _roots != other._roots;
}
void MetavoxelData::incrementRootReferenceCounts() { void MetavoxelData::incrementRootReferenceCounts() {
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) { for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) {
it.value()->incrementReferenceCount(); it.value()->incrementReferenceCount();
@ -523,11 +594,22 @@ void MetavoxelData::decrementRootReferenceCounts() {
} }
} }
static glm::vec3 getNextMinimum(const glm::vec3& minimum, float nextSize, int index) { Bitstream& operator<<(Bitstream& out, const MetavoxelData& data) {
return minimum + glm::vec3( data.write(out);
(index & X_MAXIMUM_FLAG) ? nextSize : 0.0f, return out;
(index & Y_MAXIMUM_FLAG) ? nextSize : 0.0f, }
(index & Z_MAXIMUM_FLAG) ? nextSize : 0.0f);
Bitstream& operator>>(Bitstream& in, MetavoxelData& data) {
data.read(in);
return in;
}
template<> void Bitstream::writeDelta(const MetavoxelData& value, const MetavoxelData& reference) {
value.writeDelta(reference, MetavoxelLOD(), *this, MetavoxelLOD());
}
template<> void Bitstream::readDelta(MetavoxelData& value, const MetavoxelData& reference) {
value.readDelta(reference, MetavoxelLOD(), *this, MetavoxelLOD());
} }
bool MetavoxelStreamState::shouldSubdivide() const { bool MetavoxelStreamState::shouldSubdivide() const {

View file

@ -90,6 +90,9 @@ public:
SharedObjectPointer findFirstRaySpannerIntersection(const glm::vec3& origin, const glm::vec3& direction, SharedObjectPointer findFirstRaySpannerIntersection(const glm::vec3& origin, const glm::vec3& direction,
const AttributePointer& attribute, float& distance, const MetavoxelLOD& lod = MetavoxelLOD()); const AttributePointer& attribute, float& distance, const MetavoxelLOD& lod = MetavoxelLOD());
/// Sets part of the data.
void set(const glm::vec3& minimum, const MetavoxelData& data);
/// Expands the tree, increasing its capacity in all dimensions. /// Expands the tree, increasing its capacity in all dimensions.
void expand(); void expand();
@ -103,6 +106,9 @@ public:
MetavoxelNode* getRoot(const AttributePointer& attribute) const { return _roots.value(attribute); } MetavoxelNode* getRoot(const AttributePointer& attribute) const { return _roots.value(attribute); }
MetavoxelNode* createRoot(const AttributePointer& attribute); MetavoxelNode* createRoot(const AttributePointer& attribute);
bool operator==(const MetavoxelData& other) const;
bool operator!=(const MetavoxelData& other) const;
private: private:
friend class MetavoxelVisitation; friend class MetavoxelVisitation;
@ -114,6 +120,16 @@ private:
QHash<AttributePointer, MetavoxelNode*> _roots; QHash<AttributePointer, MetavoxelNode*> _roots;
}; };
Bitstream& operator<<(Bitstream& out, const MetavoxelData& data);
Bitstream& operator>>(Bitstream& in, MetavoxelData& data);
template<> void Bitstream::writeDelta(const MetavoxelData& value, const MetavoxelData& reference);
template<> void Bitstream::readDelta(MetavoxelData& value, const MetavoxelData& reference);
Q_DECLARE_METATYPE(MetavoxelData)
/// Holds the state used in streaming metavoxel data. /// Holds the state used in streaming metavoxel data.
class MetavoxelStreamState { class MetavoxelStreamState {
public: public:
@ -592,7 +608,7 @@ public:
const QUrl& getURL() const { return _url; } const QUrl& getURL() const { return _url; }
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
const glm::vec3& clipMinimum, float clipSize,float& distance) const; const glm::vec3& clipMinimum, float clipSize, float& distance) const;
signals: signals:

View file

@ -305,3 +305,12 @@ void SetSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& obje
setIntersectingMasked(spanner->getBounds(), data); setIntersectingMasked(spanner->getBounds(), data);
} }
SetDataEdit::SetDataEdit(const glm::vec3& minimum, const MetavoxelData& data) :
minimum(minimum),
data(data) {
}
void SetDataEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
data.set(minimum, this->data);
}

View file

@ -176,4 +176,21 @@ public:
DECLARE_STREAMABLE_METATYPE(SetSpannerEdit) DECLARE_STREAMABLE_METATYPE(SetSpannerEdit)
/// An edit that directly sets part of the metavoxel data.
class SetDataEdit : public MetavoxelEdit {
STREAMABLE
public:
STREAM glm::vec3 minimum;
STREAM MetavoxelData data;
SetDataEdit(const glm::vec3& minimum = glm::vec3(), const MetavoxelData& data = MetavoxelData());
virtual void apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const;
};
DECLARE_STREAMABLE_METATYPE(SetDataEdit)
#endif /* defined(__interface__MetavoxelMessages__) */ #endif /* defined(__interface__MetavoxelMessages__) */