mirror of
https://github.com/lubosz/overte.git
synced 2025-04-16 09:29:16 +02:00
Working on ability to set a region of the metavoxel data directly.
This commit is contained in:
parent
7f6dc7ac2f
commit
40844d2000
6 changed files with 139 additions and 6 deletions
|
@ -95,6 +95,8 @@ MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const SharedNodePoin
|
|||
connect(&_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readPacket(Bitstream&)));
|
||||
connect(&_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(clearSendRecordsBefore(int)));
|
||||
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
|
||||
SendRecord record = { 0 };
|
||||
|
|
|
@ -920,6 +920,13 @@ public:
|
|||
_Pragma(STRINGIFY(unused(_TypePtr##X)))
|
||||
#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.
|
||||
template<class T> int registerStreamableMetaType() {
|
||||
int type = qRegisterMetaType<T>();
|
||||
|
|
|
@ -24,6 +24,8 @@ REGISTER_META_OBJECT(Spanner)
|
|||
REGISTER_META_OBJECT(Sphere)
|
||||
REGISTER_META_OBJECT(StaticModel)
|
||||
|
||||
static int metavoxelDataTypeId = registerSimpleMetaType<MetavoxelData>();
|
||||
|
||||
MetavoxelLOD::MetavoxelLOD(const glm::vec3& position, float threshold) :
|
||||
position(position),
|
||||
threshold(threshold) {
|
||||
|
@ -327,6 +329,67 @@ const int Y_MAXIMUM_FLAG = 2;
|
|||
const int Z_MAXIMUM_FLAG = 4;
|
||||
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) {
|
||||
return index ^ MAXIMUM_FLAG_MASK;
|
||||
}
|
||||
|
@ -511,6 +574,14 @@ MetavoxelNode* MetavoxelData::createRoot(const AttributePointer& 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() {
|
||||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) {
|
||||
it.value()->incrementReferenceCount();
|
||||
|
@ -523,11 +594,22 @@ void MetavoxelData::decrementRootReferenceCounts() {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
Bitstream& operator<<(Bitstream& out, const MetavoxelData& data) {
|
||||
data.write(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -90,6 +90,9 @@ public:
|
|||
SharedObjectPointer findFirstRaySpannerIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
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.
|
||||
void expand();
|
||||
|
||||
|
@ -103,6 +106,9 @@ public:
|
|||
MetavoxelNode* getRoot(const AttributePointer& attribute) const { return _roots.value(attribute); }
|
||||
MetavoxelNode* createRoot(const AttributePointer& attribute);
|
||||
|
||||
bool operator==(const MetavoxelData& other) const;
|
||||
bool operator!=(const MetavoxelData& other) const;
|
||||
|
||||
private:
|
||||
|
||||
friend class MetavoxelVisitation;
|
||||
|
@ -114,6 +120,16 @@ private:
|
|||
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.
|
||||
class MetavoxelStreamState {
|
||||
public:
|
||||
|
@ -592,7 +608,7 @@ public:
|
|||
const QUrl& getURL() const { return _url; }
|
||||
|
||||
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:
|
||||
|
||||
|
|
|
@ -305,3 +305,12 @@ void SetSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& obje
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -176,4 +176,21 @@ public:
|
|||
|
||||
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__) */
|
||||
|
|
Loading…
Reference in a new issue