mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 09:44:21 +02:00
Working on metavoxel averaging. Still pretty rough.
This commit is contained in:
parent
0d5f81c062
commit
9fc0abe2b3
3 changed files with 179 additions and 34 deletions
|
@ -1564,14 +1564,13 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue<VoxelColorDataPointer>();
|
||||
VoxelMaterialDataPointer material = info.inputValues.at(1).getInlineValue<VoxelMaterialDataPointer>();
|
||||
VoxelHermiteDataPointer hermite = info.inputValues.at(2).getInlineValue<VoxelHermiteDataPointer>();
|
||||
if (color && material && hermite) {
|
||||
if (color && hermite) {
|
||||
QVector<VoxelPoint> vertices;
|
||||
QVector<int> indices;
|
||||
|
||||
// see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the
|
||||
// dual contour algorithm for generating meshes from voxel data using Hermite-tagged edges
|
||||
const QVector<QRgb>& colorContents = color->getContents();
|
||||
const QByteArray& materialContents = material->getContents();
|
||||
const QVector<QRgb>& hermiteContents = hermite->getContents();
|
||||
int size = color->getSize();
|
||||
int area = size * size;
|
||||
|
@ -1589,7 +1588,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
int hermiteStride = hermite->getSize() * VoxelHermiteData::EDGE_COUNT;
|
||||
int hermiteArea = hermiteStride * hermite->getSize();
|
||||
|
||||
const char* materialData = materialContents.constData();
|
||||
const char* materialData = material ? material->getContents().constData() : NULL;
|
||||
|
||||
// as we scan down the cube generating vertices between grid points, we remember the indices of the last
|
||||
// (element, line, section--x, y, z) so that we can connect generated vertices as quads
|
||||
|
@ -1667,7 +1666,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
int clampedX = qMax(x - 1, 0), clampedY = qMax(y - 1, 0), clampedZ = qMax(z - 1, 0);
|
||||
const QRgb* hermiteBase = hermiteData + clampedZ * hermiteArea + clampedY * hermiteStride +
|
||||
clampedX * VoxelHermiteData::EDGE_COUNT;
|
||||
const char* materialBase = materialData + clampedZ * area + clampedY * size + clampedX;
|
||||
const char* materialBase = materialData ?
|
||||
(materialData + clampedZ * area + clampedY * size + clampedX) : NULL;
|
||||
int crossingCount = 0;
|
||||
if (middleX) {
|
||||
if (alpha0 != alpha1) {
|
||||
|
@ -1676,10 +1676,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha0 == 0) {
|
||||
crossing.color = colorX[1];
|
||||
crossing.material = materialBase[1];
|
||||
crossing.material = materialBase ? materialBase[1] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[0];
|
||||
crossing.material = materialBase[0];
|
||||
crossing.material = materialBase ? materialBase[0] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f);
|
||||
crossing.axis = 0;
|
||||
|
@ -1691,10 +1691,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha1 == 0) {
|
||||
crossing.color = colorX[offset3];
|
||||
crossing.material = materialBase[offset3];
|
||||
crossing.material = materialBase ? materialBase[offset3] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[1];
|
||||
crossing.material = materialBase[1];
|
||||
crossing.material = materialBase ? materialBase[1] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);
|
||||
crossing.axis = 1;
|
||||
|
@ -1705,10 +1705,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha2 == 0) {
|
||||
crossing.color = colorX[offset3];
|
||||
crossing.material = materialBase[offset3];
|
||||
crossing.material = materialBase ? materialBase[offset3] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[size];
|
||||
crossing.material = materialBase[size];
|
||||
crossing.material = materialBase ? materialBase[size] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f);
|
||||
crossing.axis = 0;
|
||||
|
@ -1720,10 +1720,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha3 == 0) {
|
||||
crossing.color = colorX[offset7];
|
||||
crossing.material = materialBase[offset7];
|
||||
crossing.material = materialBase ? materialBase[offset7] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[offset3];
|
||||
crossing.material = materialBase[offset3];
|
||||
crossing.material = materialBase ? materialBase[offset3] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
|
||||
crossing.axis = 2;
|
||||
|
@ -1734,10 +1734,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha5 == 0) {
|
||||
crossing.color = colorX[offset7];
|
||||
crossing.material = materialBase[offset7];
|
||||
crossing.material = materialBase ? materialBase[offset7] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[offset5];
|
||||
crossing.material = materialBase[offset5];
|
||||
crossing.material = materialBase ? materialBase[offset5] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);
|
||||
crossing.axis = 1;
|
||||
|
@ -1748,10 +1748,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha6 == 0) {
|
||||
crossing.color = colorX[offset7];
|
||||
crossing.material = materialBase[offset7];
|
||||
crossing.material = materialBase ? materialBase[offset7] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[offset6];
|
||||
crossing.material = materialBase[offset6];
|
||||
crossing.material = materialBase ? materialBase[offset6] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f);
|
||||
crossing.axis = 0;
|
||||
|
@ -1765,10 +1765,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha1 == 0) {
|
||||
crossing.color = colorX[offset5];
|
||||
crossing.material = materialBase[offset5];
|
||||
crossing.material = materialBase ? materialBase[offset5] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[1];
|
||||
crossing.material = materialBase[1];
|
||||
crossing.material = materialBase ? materialBase[1] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
|
||||
crossing.axis = 2;
|
||||
|
@ -1779,10 +1779,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha4 == 0) {
|
||||
crossing.color = colorX[offset5];
|
||||
crossing.material = materialBase[offset5];
|
||||
crossing.material = materialBase ? materialBase[offset5] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[area];
|
||||
crossing.material = materialBase[area];
|
||||
crossing.material = materialBase ? materialBase[area] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f);
|
||||
crossing.axis = 0;
|
||||
|
@ -1796,10 +1796,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha0 == 0) {
|
||||
crossing.color = colorX[size];
|
||||
crossing.material = materialBase[size];
|
||||
crossing.material = materialBase ? materialBase[size] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[0];
|
||||
crossing.material = materialBase[0];
|
||||
crossing.material = materialBase ? materialBase[0] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);
|
||||
crossing.axis = 1;
|
||||
|
@ -1811,10 +1811,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha2 == 0) {
|
||||
crossing.color = colorX[offset6];
|
||||
crossing.material = materialBase[offset6];
|
||||
crossing.material = materialBase ? materialBase[offset6] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[size];
|
||||
crossing.material = materialBase[size];
|
||||
crossing.material = materialBase ? materialBase[size] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
|
||||
crossing.axis = 2;
|
||||
|
@ -1825,10 +1825,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha4 == 0) {
|
||||
crossing.color = colorX[offset6];
|
||||
crossing.material = materialBase[offset6];
|
||||
crossing.material = materialBase ? materialBase[offset6] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[area];
|
||||
crossing.material = materialBase[area];
|
||||
crossing.material = materialBase ? materialBase[area] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);
|
||||
crossing.axis = 1;
|
||||
|
@ -1841,10 +1841,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
crossing.normal = unpackNormal(hermite);
|
||||
if (alpha0 == 0) {
|
||||
crossing.color = colorX[area];
|
||||
crossing.material = materialBase[area];
|
||||
crossing.material = materialBase ? materialBase[area] : 0;
|
||||
} else {
|
||||
crossing.color = colorX[0];
|
||||
crossing.material = materialBase[0];
|
||||
crossing.material = materialBase ? materialBase[0] : 0;
|
||||
}
|
||||
crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
|
||||
crossing.axis = 2;
|
||||
|
@ -2091,7 +2091,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
}
|
||||
}
|
||||
|
||||
buffer = new VoxelBuffer(vertices, indices, material->getMaterials());
|
||||
buffer = new VoxelBuffer(vertices, indices, material ? material->getMaterials() : QVector<SharedObjectPointer>());
|
||||
}
|
||||
BufferDataPointer pointer(buffer);
|
||||
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer));
|
||||
|
|
|
@ -48,7 +48,7 @@ enum GridPlane {
|
|||
const glm::vec2 INVALID_VECTOR(FLT_MAX, FLT_MAX);
|
||||
|
||||
MetavoxelEditor::MetavoxelEditor() :
|
||||
QWidget(Application::getInstance()->getGLWidget(), Qt::Tool | Qt::WindowStaysOnTopHint) {
|
||||
QWidget(Application::getInstance()->getGLWidget(), Qt::Tool) {
|
||||
|
||||
setWindowTitle("Metavoxel Editor");
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
|
|
@ -1616,8 +1616,74 @@ bool VoxelColorAttribute::merge(void*& parent, void* children[], bool postRead)
|
|||
maxSize = qMax(maxSize, pointer->getSize());
|
||||
}
|
||||
}
|
||||
*(VoxelColorDataPointer*)&parent = VoxelColorDataPointer();
|
||||
return maxSize == 0;
|
||||
if (maxSize == 0) {
|
||||
*(VoxelColorDataPointer*)&parent = VoxelColorDataPointer();
|
||||
return true;
|
||||
}
|
||||
int size = maxSize;
|
||||
int area = size * size;
|
||||
QVector<QRgb> contents(area * size);
|
||||
int halfSize = size / 2;
|
||||
int halfSizeComplement = size - halfSize;
|
||||
for (int i = 0; i < MERGE_COUNT; i++) {
|
||||
VoxelColorDataPointer child = decodeInline<VoxelColorDataPointer>(children[i]);
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
const QVector<QRgb>& childContents = child->getContents();
|
||||
int childSize = child->getSize();
|
||||
int childArea = childSize * childSize;
|
||||
const int INDEX_MASK = 1;
|
||||
int xIndex = i & INDEX_MASK;
|
||||
const int Y_SHIFT = 1;
|
||||
int yIndex = (i >> Y_SHIFT) & INDEX_MASK;
|
||||
int Z_SHIFT = 2;
|
||||
int zIndex = (i >> Z_SHIFT) & INDEX_MASK;
|
||||
QRgb* dest = contents.data() + (zIndex * halfSize * area) + (yIndex * halfSize * size) + (xIndex * halfSize);
|
||||
const QRgb* src = childContents.data();
|
||||
|
||||
const int MAX_ALPHA = 255;
|
||||
if (childSize == size) {
|
||||
// simple case: one destination value for four child values
|
||||
for (int z = 0; z < halfSizeComplement; z++) {
|
||||
int offset4 = (z == halfSize) ? 0 : childArea;
|
||||
for (int y = 0; y < halfSizeComplement; y++) {
|
||||
int offset2 = (y == halfSize) ? 0 : childSize;
|
||||
int offset6 = offset4 + offset2;
|
||||
for (QRgb* end = dest + halfSizeComplement; dest != end; ) {
|
||||
int offset1 = (dest == end - 1) ? 0 : 1;
|
||||
QRgb v0 = src[0], v1 = src[offset1], v2 = src[offset2], v3 = src[offset2 + offset1], v4 = src[offset4],
|
||||
v5 = src[offset4 + offset1], v6 = src[offset6], v7 = src[offset6 + offset1];
|
||||
src += (1 + offset1);
|
||||
int a0 = qAlpha(v0), a1 = qAlpha(v1), a2 = qAlpha(v2), a3 = qAlpha(v3),
|
||||
a4 = qAlpha(v4), a5 = qAlpha(v5), a6 = qAlpha(v6), a7 = qAlpha(v7);
|
||||
int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7;
|
||||
if (alphaTotal == 0) {
|
||||
*dest++ = qRgba(0, 0, 0, 0);
|
||||
continue;
|
||||
}
|
||||
*dest++ = qRgba(
|
||||
(qRed(v0) * a0 + qRed(v1) * a1 + qRed(v2) * a2 + qRed(v3) * a3 +
|
||||
qRed(v4) * a4 + qRed(v5) * a5 + qRed(v6) * a6 + qRed(v7) * a7) / alphaTotal,
|
||||
(qGreen(v0) * a0 + qGreen(v1) * a1 + qGreen(v2) * a2 + qGreen(v3) * a3 +
|
||||
qGreen(v4) * a4 + qGreen(v5) * a5 + qGreen(v6) * a6 + qGreen(v7) * a7) / alphaTotal,
|
||||
(qBlue(v0) * a0 + qBlue(v1) * a1 + qBlue(v2) * a2 + qBlue(v3) * a3 +
|
||||
qBlue(v4) * a4 + qBlue(v5) * a5 + qBlue(v6) * a6 + qBlue(v7) * a7) / alphaTotal,
|
||||
MAX_ALPHA);
|
||||
}
|
||||
dest += halfSize;
|
||||
src += offset2;
|
||||
}
|
||||
dest += halfSize * size;
|
||||
src += offset4;
|
||||
}
|
||||
} else {
|
||||
// more complex: N destination values for four child values
|
||||
// ...
|
||||
}
|
||||
}
|
||||
*(VoxelColorDataPointer*)&parent = VoxelColorDataPointer(new VoxelColorData(contents, size));
|
||||
return false;
|
||||
}
|
||||
|
||||
const int VOXEL_MATERIAL_HEADER_SIZE = sizeof(qint32) * 6;
|
||||
|
@ -2020,8 +2086,87 @@ bool VoxelHermiteAttribute::merge(void*& parent, void* children[], bool postRead
|
|||
maxSize = qMax(maxSize, pointer->getSize());
|
||||
}
|
||||
}
|
||||
*(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer();
|
||||
return maxSize == 0;
|
||||
if (maxSize == 0) {
|
||||
*(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer();
|
||||
return true;
|
||||
}
|
||||
int size = maxSize;
|
||||
int area = size * size;
|
||||
QVector<QRgb> contents(area * size * VoxelHermiteData::EDGE_COUNT);
|
||||
int halfSize = size / 2;
|
||||
int halfSizeComplement = size - halfSize;
|
||||
for (int i = 0; i < MERGE_COUNT; i++) {
|
||||
VoxelHermiteDataPointer child = decodeInline<VoxelHermiteDataPointer>(children[i]);
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
const QVector<QRgb>& childContents = child->getContents();
|
||||
int childSize = child->getSize();
|
||||
int childArea = childSize * childSize;
|
||||
const int INDEX_MASK = 1;
|
||||
int xIndex = i & INDEX_MASK;
|
||||
const int Y_SHIFT = 1;
|
||||
int yIndex = (i >> Y_SHIFT) & INDEX_MASK;
|
||||
int Z_SHIFT = 2;
|
||||
int zIndex = (i >> Z_SHIFT) & INDEX_MASK;
|
||||
QRgb* dest = contents.data() + ((zIndex * halfSize * area) + (yIndex * halfSize * size) + (xIndex * halfSize)) *
|
||||
VoxelHermiteData::EDGE_COUNT;
|
||||
const QRgb* src = childContents.data();
|
||||
|
||||
if (childSize == size) {
|
||||
// simple case: one destination value for four child values
|
||||
for (int z = 0; z < halfSizeComplement; z++) {
|
||||
int offset4 = (z == halfSize) ? 0 : (childArea * VoxelHermiteData::EDGE_COUNT);
|
||||
for (int y = 0; y < halfSizeComplement; y++) {
|
||||
int offset2 = (y == halfSize) ? 0 : (childSize * VoxelHermiteData::EDGE_COUNT);
|
||||
int offset6 = offset4 + offset2;
|
||||
for (QRgb* end = dest + halfSizeComplement * VoxelHermiteData::EDGE_COUNT; dest != end;
|
||||
dest += VoxelHermiteData::EDGE_COUNT) {
|
||||
int offset1 = (dest == end - VoxelHermiteData::EDGE_COUNT) ? 0 : VoxelHermiteData::EDGE_COUNT;
|
||||
for (int i = 0; i < VoxelHermiteData::EDGE_COUNT; i++) {
|
||||
QRgb v[] = { src[i], src[offset1 + i], src[offset2 + i], src[offset2 + offset1 + i],
|
||||
src[offset4 + i], src[offset4 + offset1 + i], src[offset6 + i], src[offset6 + offset1 + i] };
|
||||
glm::vec3 n[] = { unpackNormal(v[0]), unpackNormal(v[1]), unpackNormal(v[2]), unpackNormal(v[3]),
|
||||
unpackNormal(v[4]), unpackNormal(v[5]), unpackNormal(v[6]), unpackNormal(v[7]) };
|
||||
float l[] = { glm::length(n[0]), glm::length(n[1]), glm::length(n[2]), glm::length(n[3]),
|
||||
glm::length(n[4]), glm::length(n[5]), glm::length(n[6]), glm::length(n[7]) };
|
||||
float lengthTotal = l[0] + l[1] + l[2] + l[3] + l[4] + l[5] + l[6] + l[7];
|
||||
if (lengthTotal == 0.0f) {
|
||||
dest[i] = qRgba(0, 0, 0, 0);
|
||||
continue;
|
||||
}
|
||||
glm::vec3 combinedNormal = n[0] * l[0] + n[1] * l[1] + n[2] * l[2] + n[3] * l[3] + n[4] * l[4] +
|
||||
n[5] * l[5] + n[6] * l[6] + n[7] * l[7];
|
||||
float combinedLength = glm::length(combinedNormal);
|
||||
if (combinedLength > 0.0f) {
|
||||
combinedNormal /= combinedLength;
|
||||
}
|
||||
float combinedOffset = 0.0f;
|
||||
int mask = 1 << i;
|
||||
for (int j = 0; j < MERGE_COUNT; j++) {
|
||||
float offset = qAlpha(v[j]) * (0.5f / EIGHT_BIT_MAXIMUM);
|
||||
if (j & mask) {
|
||||
offset += 0.5f;
|
||||
}
|
||||
combinedOffset += offset * l[j];
|
||||
}
|
||||
dest[i] = packNormal(combinedNormal, EIGHT_BIT_MAXIMUM * combinedOffset / lengthTotal);
|
||||
}
|
||||
src += (VoxelHermiteData::EDGE_COUNT + offset1);
|
||||
}
|
||||
dest += (halfSize * VoxelHermiteData::EDGE_COUNT);
|
||||
src += offset2;
|
||||
}
|
||||
dest += (halfSize * size * VoxelHermiteData::EDGE_COUNT);
|
||||
src += offset4;
|
||||
}
|
||||
} else {
|
||||
// more complex: N destination values for four child values
|
||||
// ...
|
||||
}
|
||||
}
|
||||
*(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer(new VoxelHermiteData(contents, size));
|
||||
return false;
|
||||
}
|
||||
|
||||
SharedObjectAttribute::SharedObjectAttribute(const QString& name, const QMetaObject* metaObject,
|
||||
|
|
Loading…
Reference in a new issue