mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
More progress on generic attributes; color attributes.
This commit is contained in:
parent
79a2e409a8
commit
dce9599201
5 changed files with 104 additions and 48 deletions
|
@ -13,11 +13,13 @@
|
|||
class DebugVisitor : public MetavoxelVisitor {
|
||||
public:
|
||||
|
||||
virtual bool visit(const QVector<AttributeValue>& attributeValues);
|
||||
virtual bool visit(const MetavoxelInfo& info);
|
||||
};
|
||||
|
||||
bool DebugVisitor::visit(const QVector<AttributeValue>& attributeValues) {
|
||||
qDebug() << decodeInline<float>(attributeValues.at(0).getValue()) << "\n";
|
||||
bool DebugVisitor::visit(const MetavoxelInfo& info) {
|
||||
QRgb color = info.attributeValues.at(0).getInlineValue<QRgb>();
|
||||
qDebug("%g %g %g %g %d %d %d %d\n", info.minimum.x, info.minimum.y, info.minimum.z, info.size,
|
||||
qRed(color), qGreen(color), qBlue(color), qAlpha(color));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -27,20 +29,12 @@ void MetavoxelSystem::init() {
|
|||
p1 += 1;
|
||||
p1 += 2;
|
||||
|
||||
AttributePointer blerp = AttributeRegistry::getInstance()->getAttribute("blerp");
|
||||
AttributePointer diffuseColor = AttributeRegistry::getInstance()->getAttribute("diffuseColor");
|
||||
|
||||
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()));
|
||||
void* white = encodeInline(qRgba(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
_data.setAttributeValue(p1, AttributeValue(diffuseColor, &white));
|
||||
|
||||
DebugVisitor visitor;
|
||||
_data.visitVoxels(QVector<AttributePointer>() << blerp, visitor);
|
||||
_data.visitVoxels(QVector<AttributePointer>() << diffuseColor, visitor);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
AttributeRegistry AttributeRegistry::_instance;
|
||||
|
||||
AttributeRegistry::AttributeRegistry() {
|
||||
registerAttribute(AttributePointer(new InlineAttribute<float, 32>("blerp")));
|
||||
registerAttribute(AttributePointer(new QRgbAttribute("diffuseColor")));
|
||||
}
|
||||
|
||||
AttributePointer AttributeRegistry::registerAttribute(AttributePointer attribute) {
|
||||
|
@ -75,3 +75,24 @@ Attribute::Attribute(const QString& name) : _name(name) {
|
|||
Attribute::~Attribute() {
|
||||
}
|
||||
|
||||
QRgbAttribute::QRgbAttribute(const QString& name, QRgb defaultValue) :
|
||||
InlineAttribute<QRgb, 32>(name, defaultValue) {
|
||||
}
|
||||
|
||||
void* QRgbAttribute::createAveraged(void* values[]) const {
|
||||
int totalRed = 0;
|
||||
int totalGreen = 0;
|
||||
int totalBlue = 0;
|
||||
int totalAlpha = 0;
|
||||
for (int i = 0; i < AVERAGE_COUNT; i++) {
|
||||
QRgb value = decodeInline<QRgb>(values[i]);
|
||||
totalRed += qRed(value);
|
||||
totalGreen += qGreen(value);
|
||||
totalBlue += qBlue(value);
|
||||
totalAlpha += qAlpha(value);
|
||||
}
|
||||
const int SHIFT_FACTOR = 3;
|
||||
return encodeInline(qRgba(totalRed / AVERAGE_COUNT, totalGreen / AVERAGE_COUNT,
|
||||
totalBlue / AVERAGE_COUNT, totalAlpha / AVERAGE_COUNT));
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef __interface__AttributeRegistry__
|
||||
#define __interface__AttributeRegistry__
|
||||
|
||||
#include <QColor>
|
||||
#include <QHash>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
@ -43,6 +44,16 @@ private:
|
|||
QHash<QString, AttributePointer> _attributes;
|
||||
};
|
||||
|
||||
/// Converts a value to a void pointer.
|
||||
template<class T> inline void* encodeInline(T value) {
|
||||
return *(void**)&value;
|
||||
}
|
||||
|
||||
/// Extracts a value from a void pointer.
|
||||
template<class T> inline T decodeInline(void* value) {
|
||||
return *(T*)&value;
|
||||
}
|
||||
|
||||
/// Pairs an attribute value with its type.
|
||||
class AttributeValue {
|
||||
public:
|
||||
|
@ -56,6 +67,9 @@ public:
|
|||
AttributePointer getAttribute() const { return _attribute; }
|
||||
void* getValue() const { return _value; }
|
||||
|
||||
template<class T> void setInlineValue(T value) { _value = encodeInline(value); }
|
||||
template<class T> T getInlineValue() const { return decodeInline<T>(_value); }
|
||||
|
||||
void* copy() const;
|
||||
|
||||
bool isDefault() const;
|
||||
|
@ -73,6 +87,8 @@ private:
|
|||
class Attribute {
|
||||
public:
|
||||
|
||||
static const int AVERAGE_COUNT = 8;
|
||||
|
||||
Attribute(const QString& name);
|
||||
virtual ~Attribute();
|
||||
|
||||
|
@ -95,14 +111,6 @@ private:
|
|||
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.
|
||||
template<class T, int bits> class InlineAttribute : public Attribute {
|
||||
public:
|
||||
|
@ -128,11 +136,20 @@ private:
|
|||
|
||||
template<class T, int bits> inline void* InlineAttribute<T, bits>::createAveraged(void* values[]) const {
|
||||
T total = T();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int i = 0; i < AVERAGE_COUNT; i++) {
|
||||
total += decodeInline<T>(values[i]);
|
||||
}
|
||||
total /= 8;
|
||||
total /= AVERAGE_COUNT;
|
||||
return encodeInline(total);
|
||||
}
|
||||
|
||||
/// Provides appropriate averaging for RGBA values.
|
||||
class QRgbAttribute : public InlineAttribute<QRgb, 32> {
|
||||
public:
|
||||
|
||||
QRgbAttribute(const QString& name, QRgb defaultValue = QRgb());
|
||||
|
||||
virtual void* createAveraged(void* values[]) const;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__AttributeRegistry__) */
|
||||
|
|
|
@ -19,45 +19,58 @@ class Visitation {
|
|||
public:
|
||||
MetavoxelVisitor& visitor;
|
||||
QVector<MetavoxelNode*> nodes;
|
||||
QVector<AttributeValue> attributeValues;
|
||||
MetavoxelInfo info;
|
||||
|
||||
void apply();
|
||||
|
||||
protected:
|
||||
|
||||
bool allNodesLeaves() const;
|
||||
};
|
||||
|
||||
const int X_MAXIMUM_FLAG = 1;
|
||||
const int Y_MAXIMUM_FLAG = 2;
|
||||
const int Z_MAXIMUM_FLAG = 4;
|
||||
|
||||
void Visitation::apply() {
|
||||
Visitation nextVisitation = { visitor, QVector<MetavoxelNode*>(nodes.size()), attributeValues };
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
MetavoxelNode* node = nodes.at(i);
|
||||
if (node) {
|
||||
nextVisitation.attributeValues[i] = node->getAttributeValue(attributeValues[i].getAttribute());
|
||||
}
|
||||
}
|
||||
|
||||
if (!visitor.visit(nextVisitation.attributeValues)) {
|
||||
if (!visitor.visit(info) || allNodesLeaves()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Visitation nextVisitation = { visitor, QVector<MetavoxelNode*>(nodes.size()),
|
||||
{ glm::vec3(), info.size * 0.5f, QVector<AttributeValue>(nodes.size()) } };
|
||||
for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) {
|
||||
bool anyChildrenPresent = false;
|
||||
for (int j = 0; j < nodes.size(); j++) {
|
||||
MetavoxelNode* node = nodes.at(j);
|
||||
if ((nextVisitation.nodes[j] = node ? node->getChild(i) : NULL)) {
|
||||
anyChildrenPresent = true;
|
||||
}
|
||||
MetavoxelNode* child = node ? node->getChild(i) : NULL;
|
||||
nextVisitation.info.attributeValues[j] = ((nextVisitation.nodes[j] = child)) ?
|
||||
child->getAttributeValue(info.attributeValues[j].getAttribute()) : info.attributeValues[j];
|
||||
}
|
||||
if (anyChildrenPresent) {
|
||||
nextVisitation.apply();
|
||||
nextVisitation.info.minimum = info.minimum + glm::vec3(
|
||||
(i & X_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f,
|
||||
(i & Y_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f,
|
||||
(i & Z_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f);
|
||||
nextVisitation.apply();
|
||||
}
|
||||
}
|
||||
|
||||
bool Visitation::allNodesLeaves() const {
|
||||
foreach (MetavoxelNode* node, nodes) {
|
||||
if (node != NULL && !node->isLeaf()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MetavoxelData::visitVoxels(const QVector<AttributePointer>& attributes, MetavoxelVisitor& visitor) {
|
||||
// start with the root values/defaults
|
||||
const float TOP_LEVEL_SIZE = 1.0f;
|
||||
Visitation firstVisitation = { visitor, QVector<MetavoxelNode*>(attributes.size()),
|
||||
QVector<AttributeValue>(attributes.size()) };
|
||||
{ glm::vec3(), TOP_LEVEL_SIZE, QVector<AttributeValue>(attributes.size()) } };
|
||||
for (int i = 0; i < attributes.size(); i++) {
|
||||
firstVisitation.nodes[i] = _roots.value(attributes[i]);
|
||||
firstVisitation.attributeValues[i] = attributes[i];
|
||||
MetavoxelNode* node = _roots.value(attributes[i]);
|
||||
firstVisitation.nodes[i] = node;
|
||||
firstVisitation.info.attributeValues[i] = node ? node->getAttributeValue(attributes[i]) : attributes[i];
|
||||
}
|
||||
firstVisitation.apply();
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <QScopedPointer>
|
||||
#include <QVector>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "AttributeRegistry.h"
|
||||
|
||||
class MetavoxelNode;
|
||||
|
@ -94,14 +96,23 @@ private:
|
|||
QBitArray _array;
|
||||
};
|
||||
|
||||
/// Contains information about a metavoxel (explicit or procedural).
|
||||
class MetavoxelInfo {
|
||||
public:
|
||||
|
||||
glm::vec3 minimum; ///< the minimum extent of the area covered by the voxel
|
||||
float size; ///< the size of the voxel in all dimensions
|
||||
QVector<AttributeValue> attributeValues;
|
||||
};
|
||||
|
||||
/// Interface for visitors to metavoxels.
|
||||
class MetavoxelVisitor {
|
||||
public:
|
||||
|
||||
/// Visits a metavoxel.
|
||||
/// \param attributeValues the values of the desired attributes
|
||||
/// \param info the metavoxel ata
|
||||
/// \param if true, continue descending; if false, stop
|
||||
virtual bool visit(const QVector<AttributeValue>& attributeValues) = 0;
|
||||
virtual bool visit(const MetavoxelInfo& info) = 0;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__MetavoxelData__) */
|
||||
|
|
Loading…
Reference in a new issue