mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 13:38:02 +02:00
More progress on metavoxels with generic attributes.
This commit is contained in:
parent
6ba750a963
commit
88eeb17f28
4 changed files with 72 additions and 21 deletions
|
@ -11,6 +11,22 @@
|
||||||
#include "MetavoxelSystem.h"
|
#include "MetavoxelSystem.h"
|
||||||
|
|
||||||
void MetavoxelSystem::init() {
|
void MetavoxelSystem::init() {
|
||||||
qDebug() << "Howdy hello\n";
|
MetavoxelPath p1;
|
||||||
|
p1 += 0;
|
||||||
|
p1 += 1;
|
||||||
|
p1 += 2;
|
||||||
|
|
||||||
|
AttributePointer blerp = AttributeRegistry::getInstance()->getAttribute("blerp");
|
||||||
|
|
||||||
|
void* foo = encodeInline(5.0f);
|
||||||
|
_data.setAttributeValue(p1, AttributeValue(blerp, &foo));
|
||||||
|
|
||||||
|
//p1 += 0;
|
||||||
|
|
||||||
|
MetavoxelPath p2;
|
||||||
|
|
||||||
|
AttributeValue value = _data.getAttributeValue(p2, blerp);
|
||||||
|
|
||||||
|
qDebug("fliggedy bloo %g\n", decodeInline<float>(value.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,11 +95,19 @@ private:
|
||||||
QString _name;
|
QString _name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class T> inline void* encodeInline(const T& value) {
|
||||||
|
return *(void**)const_cast<T*>(&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline T decodeInline(void* value) {
|
||||||
|
return *(T*)&value;
|
||||||
|
}
|
||||||
|
|
||||||
/// A simple attribute class that stores its values inline.
|
/// A simple attribute class that stores its values inline.
|
||||||
template<class T, int bits> class InlineAttribute : public Attribute {
|
template<class T, int bits> class InlineAttribute : public Attribute {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
InlineAttribute(const QString& name, T defaultValue = T()) : Attribute(name), _defaultValue(*(void**)&defaultValue) { }
|
InlineAttribute(const QString& name, T defaultValue = T()) : Attribute(name), _defaultValue(encodeInline(defaultValue)) { }
|
||||||
|
|
||||||
virtual void* create(void* const* copy = NULL) const { return (copy == NULL) ? _defaultValue : *copy; }
|
virtual void* create(void* const* copy = NULL) const { return (copy == NULL) ? _defaultValue : *copy; }
|
||||||
virtual void destroy(void* value) const { /* no-op */ }
|
virtual void destroy(void* value) const { /* no-op */ }
|
||||||
|
@ -121,10 +129,10 @@ private:
|
||||||
template<class T, int bits> inline void* InlineAttribute<T, bits>::createAveraged(void* values[]) const {
|
template<class T, int bits> inline void* InlineAttribute<T, bits>::createAveraged(void* values[]) const {
|
||||||
T total = T();
|
T total = T();
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
total += *(T*)(values + i);
|
total += decodeInline<T>(values[i]);
|
||||||
}
|
}
|
||||||
total /= 8;
|
total /= 8;
|
||||||
return *(void**)&total;
|
return encodeInline(total);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(__interface__AttributeRegistry__) */
|
#endif /* defined(__interface__AttributeRegistry__) */
|
||||||
|
|
|
@ -25,7 +25,7 @@ void MetavoxelData::setAttributeValue(const MetavoxelPath& path, const Attribute
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
node = new MetavoxelNode(attributeValue.getAttribute());
|
node = new MetavoxelNode(attributeValue.getAttribute());
|
||||||
}
|
}
|
||||||
if (node->setAttributeValue(path, 0, attributeValue)) {
|
if (node->setAttributeValue(path, 0, attributeValue) && attributeValue.isDefault()) {
|
||||||
node->destroy(attributeValue.getAttribute());
|
node->destroy(attributeValue.getAttribute());
|
||||||
delete node;
|
delete node;
|
||||||
_roots.remove(attributeValue.getAttribute());
|
_roots.remove(attributeValue.getAttribute());
|
||||||
|
@ -41,7 +41,7 @@ AttributeValue MetavoxelData::getAttributeValue(const MetavoxelPath& path, const
|
||||||
int index = path[i];
|
int index = path[i];
|
||||||
MetavoxelNode* child = node->getChild(i);
|
MetavoxelNode* child = node->getChild(i);
|
||||||
if (child == NULL) {
|
if (child == NULL) {
|
||||||
return AttributeValue(attribute);
|
return node->getAttributeValue(attribute);
|
||||||
}
|
}
|
||||||
node = child;
|
node = child;
|
||||||
}
|
}
|
||||||
|
@ -58,39 +58,53 @@ MetavoxelNode::MetavoxelNode(const AttributeValue& attributeValue) {
|
||||||
bool MetavoxelNode::setAttributeValue(const MetavoxelPath& path, int index, const AttributeValue& attributeValue) {
|
bool MetavoxelNode::setAttributeValue(const MetavoxelPath& path, int index, const AttributeValue& attributeValue) {
|
||||||
if (index == path.getSize()) {
|
if (index == path.getSize()) {
|
||||||
setAttributeValue(attributeValue);
|
setAttributeValue(attributeValue);
|
||||||
return attributeValue.isDefault();
|
return true;
|
||||||
}
|
}
|
||||||
int element = path[index];
|
int element = path[index];
|
||||||
if (_children[element] == NULL) {
|
if (_children[element] == NULL) {
|
||||||
_children[element] = new MetavoxelNode(attributeValue.getAttribute());
|
AttributeValue ownAttributeValue = getAttributeValue(attributeValue.getAttribute());
|
||||||
}
|
|
||||||
if (_children[element]->setAttributeValue(path, index + 1, attributeValue)) {
|
|
||||||
_children[element]->destroy(attributeValue.getAttribute());
|
|
||||||
delete _children[element];
|
|
||||||
_children[element] = NULL;
|
|
||||||
if (allChildrenNull()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void* childValues[CHILD_COUNT];
|
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
childValues[i] = (_children[i] == NULL) ? attributeValue.getAttribute()->getDefaultValue() :
|
_children[i] = new MetavoxelNode(ownAttributeValue);
|
||||||
_children[i]->_attributeValue;
|
}
|
||||||
|
}
|
||||||
|
_children[element]->setAttributeValue(path, index + 1, attributeValue);
|
||||||
|
|
||||||
|
void* childValues[CHILD_COUNT];
|
||||||
|
bool allLeaves = true;
|
||||||
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
childValues[i] = _children[i]->_attributeValue;
|
||||||
|
allLeaves &= _children[i]->isLeaf();
|
||||||
}
|
}
|
||||||
attributeValue.getAttribute()->destroy(_attributeValue);
|
attributeValue.getAttribute()->destroy(_attributeValue);
|
||||||
_attributeValue = attributeValue.getAttribute()->createAveraged(childValues);
|
_attributeValue = attributeValue.getAttribute()->createAveraged(childValues);
|
||||||
|
|
||||||
|
if (allLeaves && allChildrenEqual(attributeValue.getAttribute())) {
|
||||||
|
clearChildren(attributeValue.getAttribute());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelNode::setAttributeValue(const AttributeValue& attributeValue) {
|
void MetavoxelNode::setAttributeValue(const AttributeValue& attributeValue) {
|
||||||
attributeValue.getAttribute()->destroy(_attributeValue);
|
attributeValue.getAttribute()->destroy(_attributeValue);
|
||||||
_attributeValue = attributeValue.copy();
|
_attributeValue = attributeValue.copy();
|
||||||
|
clearChildren(attributeValue.getAttribute());
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeValue MetavoxelNode::getAttributeValue(const AttributePointer& attribute) const {
|
AttributeValue MetavoxelNode::getAttributeValue(const AttributePointer& attribute) const {
|
||||||
return AttributeValue(attribute, &_attributeValue);
|
return AttributeValue(attribute, &_attributeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MetavoxelNode::isLeaf() const {
|
||||||
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
if (_children[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void MetavoxelNode::destroy(const AttributePointer& attribute) {
|
void MetavoxelNode::destroy(const AttributePointer& attribute) {
|
||||||
attribute->destroy(_attributeValue);
|
attribute->destroy(_attributeValue);
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
@ -101,15 +115,25 @@ void MetavoxelNode::destroy(const AttributePointer& attribute) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetavoxelNode::allChildrenNull() const {
|
bool MetavoxelNode::allChildrenEqual(const AttributePointer& attribute) const {
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
if (_children[i] != NULL) {
|
if (!attribute->equal(_attributeValue, _children[i]->_attributeValue)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetavoxelNode::clearChildren(const AttributePointer& attribute) {
|
||||||
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
if (_children[i]) {
|
||||||
|
_children[i]->destroy(attribute);
|
||||||
|
delete _children[i];
|
||||||
|
_children[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int MetavoxelPath::operator[](int index) const {
|
int MetavoxelPath::operator[](int index) const {
|
||||||
return _array.at(index * BITS_PER_ELEMENT) | (_array.at(index * BITS_PER_ELEMENT + 1) << 1) |
|
return _array.at(index * BITS_PER_ELEMENT) | (_array.at(index * BITS_PER_ELEMENT + 1) << 1) |
|
||||||
(_array.at(index * BITS_PER_ELEMENT + 2) << 2);
|
(_array.at(index * BITS_PER_ELEMENT + 2) << 2);
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
/// Descends the voxel tree in order to set the value of a node.
|
/// Descends the voxel tree in order to set the value of a node.
|
||||||
/// \param path the path to follow
|
/// \param path the path to follow
|
||||||
/// \param index the position in the path
|
/// \param index the position in the path
|
||||||
/// \return whether or not the node is entirely equal to the default attribute, and can thus be collapsed
|
/// \return whether or not the node is entirely equal to the value
|
||||||
bool setAttributeValue(const MetavoxelPath& path, int index, const AttributeValue& attributeValue);
|
bool setAttributeValue(const MetavoxelPath& path, int index, const AttributeValue& attributeValue);
|
||||||
|
|
||||||
void setAttributeValue(const AttributeValue& attributeValue);
|
void setAttributeValue(const AttributeValue& attributeValue);
|
||||||
|
@ -61,12 +61,15 @@ public:
|
||||||
MetavoxelNode* getChild(int index) const { return _children[index]; }
|
MetavoxelNode* getChild(int index) const { return _children[index]; }
|
||||||
void setChild(int index, MetavoxelNode* child) { _children[index] = child; }
|
void setChild(int index, MetavoxelNode* child) { _children[index] = child; }
|
||||||
|
|
||||||
|
bool isLeaf() const;
|
||||||
|
|
||||||
void destroy(const AttributePointer& attribute);
|
void destroy(const AttributePointer& attribute);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(MetavoxelNode)
|
Q_DISABLE_COPY(MetavoxelNode)
|
||||||
|
|
||||||
bool allChildrenNull() const;
|
bool allChildrenEqual(const AttributePointer& attribute) const;
|
||||||
|
void clearChildren(const AttributePointer& attribute);
|
||||||
|
|
||||||
void* _attributeValue;
|
void* _attributeValue;
|
||||||
MetavoxelNode* _children[CHILD_COUNT];
|
MetavoxelNode* _children[CHILD_COUNT];
|
||||||
|
|
Loading…
Reference in a new issue