mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 17:01:18 +02:00
Merge pull request #3563 from ey6es/metavoxels
Basic averaging for dual contour data, added option to display Hermite data.
This commit is contained in:
commit
27a5042943
8 changed files with 299 additions and 44 deletions
|
@ -13,16 +13,19 @@
|
||||||
|
|
||||||
uniform float pointScale;
|
uniform float pointScale;
|
||||||
|
|
||||||
void main(void) {
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
// standard diffuse lighting
|
void main(void) {
|
||||||
gl_FrontColor = vec4(gl_Color.rgb * (gl_LightModel.ambient.rgb + gl_LightSource[0].ambient.rgb +
|
// transform and store the normal for interpolation
|
||||||
gl_LightSource[0].diffuse.rgb * max(0.0, dot(gl_NormalMatrix * gl_Normal, gl_LightSource[0].position.xyz))),
|
normal = vec4(normalize(gl_NormalMatrix * gl_Normal), 0.0);
|
||||||
0.0);
|
|
||||||
|
|
||||||
// extract the first three components of the vertex for position
|
// extract the first three components of the vertex for position
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0);
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0);
|
||||||
|
|
||||||
// the final component is the size in world space
|
// the final component is the size in world space
|
||||||
gl_PointSize = pointScale * gl_Vertex.w / gl_Position.w;
|
gl_PointSize = pointScale * gl_Vertex.w / gl_Position.w;
|
||||||
|
|
||||||
|
// copy the color for interpolation
|
||||||
|
gl_FrontColor = vec4(gl_Color.rgb, 0.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -423,6 +423,10 @@ Menu::Menu() :
|
||||||
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges);
|
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges);
|
||||||
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableAutoAdjustLOD);
|
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableAutoAdjustLOD);
|
||||||
|
|
||||||
|
QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels");
|
||||||
|
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false,
|
||||||
|
Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData()));
|
||||||
|
|
||||||
QMenu* handOptionsMenu = developerMenu->addMenu("Hands");
|
QMenu* handOptionsMenu = developerMenu->addMenu("Hands");
|
||||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false);
|
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false);
|
||||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlternateIK, 0, false);
|
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlternateIK, 0, false);
|
||||||
|
|
|
@ -374,6 +374,7 @@ namespace MenuOption {
|
||||||
const QString DisplayFrustum = "Display Frustum";
|
const QString DisplayFrustum = "Display Frustum";
|
||||||
const QString DisplayHands = "Show Hand Info";
|
const QString DisplayHands = "Show Hand Info";
|
||||||
const QString DisplayHandTargets = "Show Hand Targets";
|
const QString DisplayHandTargets = "Show Hand Targets";
|
||||||
|
const QString DisplayHermiteData = "Display Hermite Data";
|
||||||
const QString DisplayModelBounds = "Display Model Bounds";
|
const QString DisplayModelBounds = "Display Model Bounds";
|
||||||
const QString DisplayModelElementChildProxies = "Display Model Element Children";
|
const QString DisplayModelElementChildProxies = "Display Model Element Children";
|
||||||
const QString DisplayModelElementProxy = "Display Model Element Bounds";
|
const QString DisplayModelElementProxy = "Display Model Element Bounds";
|
||||||
|
|
|
@ -137,6 +137,18 @@ void MetavoxelSystem::render() {
|
||||||
emit rendering();
|
emit rendering();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetavoxelSystem::refreshVoxelData() {
|
||||||
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
|
if (node->getType() == NodeType::MetavoxelServer) {
|
||||||
|
QMutexLocker locker(&node->getMutex());
|
||||||
|
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
|
||||||
|
if (client) {
|
||||||
|
QMetaObject::invokeMethod(client, "refreshVoxelData");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class RayHeightfieldIntersectionVisitor : public RayIntersectionVisitor {
|
class RayHeightfieldIntersectionVisitor : public RayIntersectionVisitor {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -577,6 +589,14 @@ void Augmenter::run() {
|
||||||
QMetaObject::invokeMethod(node->getLinkedData(), "setAugmentedData", Q_ARG(const MetavoxelData&, _data));
|
QMetaObject::invokeMethod(node->getLinkedData(), "setAugmentedData", Q_ARG(const MetavoxelData&, _data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetavoxelSystemClient::refreshVoxelData() {
|
||||||
|
// make it look as if all the colors have changed
|
||||||
|
MetavoxelData oldData = getAugmentedData();
|
||||||
|
oldData.touch(AttributeRegistry::getInstance()->getVoxelColorAttribute());
|
||||||
|
|
||||||
|
QThreadPool::globalInstance()->start(new Augmenter(_node, _data, oldData, _remoteDataLOD));
|
||||||
|
}
|
||||||
|
|
||||||
void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) {
|
void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) {
|
||||||
MetavoxelClient::dataChanged(oldData);
|
MetavoxelClient::dataChanged(oldData);
|
||||||
QThreadPool::globalInstance()->start(new Augmenter(_node, _data, getAugmentedData(), _remoteDataLOD));
|
QThreadPool::globalInstance()->start(new Augmenter(_node, _data, getAugmentedData(), _remoteDataLOD));
|
||||||
|
@ -970,12 +990,14 @@ void VoxelPoint::setNormal(const glm::vec3& normal) {
|
||||||
this->normal[2] = (char)(normal.z * 127.0f);
|
this->normal[2] = (char)(normal.z * 127.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices,
|
VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices, const QVector<glm::vec3>& hermite,
|
||||||
const QVector<SharedObjectPointer>& materials) :
|
const QVector<SharedObjectPointer>& materials) :
|
||||||
_vertices(vertices),
|
_vertices(vertices),
|
||||||
_indices(indices),
|
_indices(indices),
|
||||||
|
_hermite(hermite),
|
||||||
_vertexCount(vertices.size()),
|
_vertexCount(vertices.size()),
|
||||||
_indexCount(indices.size()),
|
_indexCount(indices.size()),
|
||||||
|
_hermiteCount(hermite.size()),
|
||||||
_indexBuffer(QOpenGLBuffer::IndexBuffer),
|
_indexBuffer(QOpenGLBuffer::IndexBuffer),
|
||||||
_materials(materials) {
|
_materials(materials) {
|
||||||
}
|
}
|
||||||
|
@ -1095,6 +1117,39 @@ void VoxelBuffer::render(bool cursor) {
|
||||||
|
|
||||||
_vertexBuffer.release();
|
_vertexBuffer.release();
|
||||||
_indexBuffer.release();
|
_indexBuffer.release();
|
||||||
|
|
||||||
|
if (_hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) {
|
||||||
|
if (!_hermiteBuffer.isCreated()) {
|
||||||
|
_hermiteBuffer.create();
|
||||||
|
_hermiteBuffer.bind();
|
||||||
|
_hermiteBuffer.allocate(_hermite.constData(), _hermite.size() * sizeof(glm::vec3));
|
||||||
|
_hermite.clear();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_hermiteBuffer.bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
|
glVertexPointer(3, GL_FLOAT, 0, 0);
|
||||||
|
|
||||||
|
Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind();
|
||||||
|
|
||||||
|
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
|
glLineWidth(1.0f);
|
||||||
|
|
||||||
|
glDrawArrays(GL_LINES, 0, _hermiteCount);
|
||||||
|
|
||||||
|
DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind();
|
||||||
|
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
|
_hermiteBuffer.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferDataAttribute::BufferDataAttribute(const QString& name) :
|
BufferDataAttribute::BufferDataAttribute(const QString& name) :
|
||||||
|
@ -1117,7 +1172,10 @@ AttributeValue BufferDataAttribute::inherit(const AttributeValue& parentValue) c
|
||||||
|
|
||||||
void DefaultMetavoxelRendererImplementation::init() {
|
void DefaultMetavoxelRendererImplementation::init() {
|
||||||
if (!_pointProgram.isLinked()) {
|
if (!_pointProgram.isLinked()) {
|
||||||
_pointProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert");
|
_pointProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||||
|
"shaders/metavoxel_point.vert");
|
||||||
|
_pointProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||||
|
"shaders/metavoxel_voxel_base.frag");
|
||||||
_pointProgram.link();
|
_pointProgram.link();
|
||||||
|
|
||||||
_pointProgram.bind();
|
_pointProgram.bind();
|
||||||
|
@ -1560,18 +1618,19 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
if (!info.isLeaf) {
|
if (!info.isLeaf) {
|
||||||
return DEFAULT_ORDER;
|
return DEFAULT_ORDER;
|
||||||
}
|
}
|
||||||
VoxelBuffer* buffer = NULL;
|
BufferData* buffer = NULL;
|
||||||
VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue<VoxelColorDataPointer>();
|
VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue<VoxelColorDataPointer>();
|
||||||
VoxelMaterialDataPointer material = info.inputValues.at(1).getInlineValue<VoxelMaterialDataPointer>();
|
VoxelMaterialDataPointer material = info.inputValues.at(1).getInlineValue<VoxelMaterialDataPointer>();
|
||||||
VoxelHermiteDataPointer hermite = info.inputValues.at(2).getInlineValue<VoxelHermiteDataPointer>();
|
VoxelHermiteDataPointer hermite = info.inputValues.at(2).getInlineValue<VoxelHermiteDataPointer>();
|
||||||
if (color && material && hermite) {
|
|
||||||
|
if (color && hermite) {
|
||||||
QVector<VoxelPoint> vertices;
|
QVector<VoxelPoint> vertices;
|
||||||
QVector<int> indices;
|
QVector<int> indices;
|
||||||
|
QVector<glm::vec3> hermiteSegments;
|
||||||
|
|
||||||
// see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the
|
// 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
|
// dual contour algorithm for generating meshes from voxel data using Hermite-tagged edges
|
||||||
const QVector<QRgb>& colorContents = color->getContents();
|
const QVector<QRgb>& colorContents = color->getContents();
|
||||||
const QByteArray& materialContents = material->getContents();
|
|
||||||
const QVector<QRgb>& hermiteContents = hermite->getContents();
|
const QVector<QRgb>& hermiteContents = hermite->getContents();
|
||||||
int size = color->getSize();
|
int size = color->getSize();
|
||||||
int area = size * size;
|
int area = size * size;
|
||||||
|
@ -1589,7 +1648,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
int hermiteStride = hermite->getSize() * VoxelHermiteData::EDGE_COUNT;
|
int hermiteStride = hermite->getSize() * VoxelHermiteData::EDGE_COUNT;
|
||||||
int hermiteArea = hermiteStride * hermite->getSize();
|
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
|
// 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
|
// (element, line, section--x, y, z) so that we can connect generated vertices as quads
|
||||||
|
@ -1605,6 +1664,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
float highest = size - 1.0f;
|
float highest = size - 1.0f;
|
||||||
float scale = info.size / highest;
|
float scale = info.size / highest;
|
||||||
const int ALPHA_OFFSET = 24;
|
const int ALPHA_OFFSET = 24;
|
||||||
|
bool displayHermite = Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData);
|
||||||
for (int z = 0; z < expanded; z++) {
|
for (int z = 0; z < expanded; z++) {
|
||||||
const QRgb* colorY = colorZ;
|
const QRgb* colorY = colorZ;
|
||||||
for (int y = 0; y < expanded; y++) {
|
for (int y = 0; y < expanded; y++) {
|
||||||
|
@ -1667,7 +1727,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
int clampedX = qMax(x - 1, 0), clampedY = qMax(y - 1, 0), clampedZ = qMax(z - 1, 0);
|
int clampedX = qMax(x - 1, 0), clampedY = qMax(y - 1, 0), clampedZ = qMax(z - 1, 0);
|
||||||
const QRgb* hermiteBase = hermiteData + clampedZ * hermiteArea + clampedY * hermiteStride +
|
const QRgb* hermiteBase = hermiteData + clampedZ * hermiteArea + clampedY * hermiteStride +
|
||||||
clampedX * VoxelHermiteData::EDGE_COUNT;
|
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;
|
int crossingCount = 0;
|
||||||
if (middleX) {
|
if (middleX) {
|
||||||
if (alpha0 != alpha1) {
|
if (alpha0 != alpha1) {
|
||||||
|
@ -1676,10 +1737,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha0 == 0) {
|
if (alpha0 == 0) {
|
||||||
crossing.color = colorX[1];
|
crossing.color = colorX[1];
|
||||||
crossing.material = materialBase[1];
|
crossing.material = materialBase ? materialBase[1] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[0];
|
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.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f);
|
||||||
crossing.axis = 0;
|
crossing.axis = 0;
|
||||||
|
@ -1691,10 +1752,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha1 == 0) {
|
if (alpha1 == 0) {
|
||||||
crossing.color = colorX[offset3];
|
crossing.color = colorX[offset3];
|
||||||
crossing.material = materialBase[offset3];
|
crossing.material = materialBase ? materialBase[offset3] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[1];
|
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.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);
|
||||||
crossing.axis = 1;
|
crossing.axis = 1;
|
||||||
|
@ -1705,10 +1766,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha2 == 0) {
|
if (alpha2 == 0) {
|
||||||
crossing.color = colorX[offset3];
|
crossing.color = colorX[offset3];
|
||||||
crossing.material = materialBase[offset3];
|
crossing.material = materialBase ? materialBase[offset3] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[size];
|
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.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f);
|
||||||
crossing.axis = 0;
|
crossing.axis = 0;
|
||||||
|
@ -1720,10 +1781,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha3 == 0) {
|
if (alpha3 == 0) {
|
||||||
crossing.color = colorX[offset7];
|
crossing.color = colorX[offset7];
|
||||||
crossing.material = materialBase[offset7];
|
crossing.material = materialBase ? materialBase[offset7] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[offset3];
|
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.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
|
||||||
crossing.axis = 2;
|
crossing.axis = 2;
|
||||||
|
@ -1734,10 +1795,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha5 == 0) {
|
if (alpha5 == 0) {
|
||||||
crossing.color = colorX[offset7];
|
crossing.color = colorX[offset7];
|
||||||
crossing.material = materialBase[offset7];
|
crossing.material = materialBase ? materialBase[offset7] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[offset5];
|
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.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);
|
||||||
crossing.axis = 1;
|
crossing.axis = 1;
|
||||||
|
@ -1748,10 +1809,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha6 == 0) {
|
if (alpha6 == 0) {
|
||||||
crossing.color = colorX[offset7];
|
crossing.color = colorX[offset7];
|
||||||
crossing.material = materialBase[offset7];
|
crossing.material = materialBase ? materialBase[offset7] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[offset6];
|
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.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f);
|
||||||
crossing.axis = 0;
|
crossing.axis = 0;
|
||||||
|
@ -1765,10 +1826,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha1 == 0) {
|
if (alpha1 == 0) {
|
||||||
crossing.color = colorX[offset5];
|
crossing.color = colorX[offset5];
|
||||||
crossing.material = materialBase[offset5];
|
crossing.material = materialBase ? materialBase[offset5] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[1];
|
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.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
|
||||||
crossing.axis = 2;
|
crossing.axis = 2;
|
||||||
|
@ -1779,10 +1840,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha4 == 0) {
|
if (alpha4 == 0) {
|
||||||
crossing.color = colorX[offset5];
|
crossing.color = colorX[offset5];
|
||||||
crossing.material = materialBase[offset5];
|
crossing.material = materialBase ? materialBase[offset5] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[area];
|
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.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f);
|
||||||
crossing.axis = 0;
|
crossing.axis = 0;
|
||||||
|
@ -1796,10 +1857,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha0 == 0) {
|
if (alpha0 == 0) {
|
||||||
crossing.color = colorX[size];
|
crossing.color = colorX[size];
|
||||||
crossing.material = materialBase[size];
|
crossing.material = materialBase ? materialBase[size] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[0];
|
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.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);
|
||||||
crossing.axis = 1;
|
crossing.axis = 1;
|
||||||
|
@ -1811,10 +1872,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha2 == 0) {
|
if (alpha2 == 0) {
|
||||||
crossing.color = colorX[offset6];
|
crossing.color = colorX[offset6];
|
||||||
crossing.material = materialBase[offset6];
|
crossing.material = materialBase ? materialBase[offset6] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[size];
|
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.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
|
||||||
crossing.axis = 2;
|
crossing.axis = 2;
|
||||||
|
@ -1825,10 +1886,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha4 == 0) {
|
if (alpha4 == 0) {
|
||||||
crossing.color = colorX[offset6];
|
crossing.color = colorX[offset6];
|
||||||
crossing.material = materialBase[offset6];
|
crossing.material = materialBase ? materialBase[offset6] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[area];
|
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.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);
|
||||||
crossing.axis = 1;
|
crossing.axis = 1;
|
||||||
|
@ -1841,10 +1902,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
crossing.normal = unpackNormal(hermite);
|
crossing.normal = unpackNormal(hermite);
|
||||||
if (alpha0 == 0) {
|
if (alpha0 == 0) {
|
||||||
crossing.color = colorX[area];
|
crossing.color = colorX[area];
|
||||||
crossing.material = materialBase[area];
|
crossing.material = materialBase ? materialBase[area] : 0;
|
||||||
} else {
|
} else {
|
||||||
crossing.color = colorX[0];
|
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.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
|
||||||
crossing.axis = 2;
|
crossing.axis = 2;
|
||||||
|
@ -1866,6 +1927,13 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
green += qGreen(crossing.color);
|
green += qGreen(crossing.color);
|
||||||
blue += qBlue(crossing.color);
|
blue += qBlue(crossing.color);
|
||||||
|
|
||||||
|
if (displayHermite) {
|
||||||
|
glm::vec3 start = info.minimum + (glm::vec3(clampedX, clampedY, clampedZ) +
|
||||||
|
crossing.point) * scale;
|
||||||
|
hermiteSegments.append(start);
|
||||||
|
hermiteSegments.append(start + crossing.normal * scale);
|
||||||
|
}
|
||||||
|
|
||||||
// when assigning a material, search for its presence and, if not found,
|
// when assigning a material, search for its presence and, if not found,
|
||||||
// place it in the first empty slot
|
// place it in the first empty slot
|
||||||
if (crossing.material != 0) {
|
if (crossing.material != 0) {
|
||||||
|
@ -2090,8 +2158,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
colorZ += area;
|
colorZ += area;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
buffer = new VoxelBuffer(vertices, indices, hermiteSegments,
|
||||||
buffer = new VoxelBuffer(vertices, indices, material->getMaterials());
|
material ? material->getMaterials() : QVector<SharedObjectPointer>());
|
||||||
}
|
}
|
||||||
BufferDataPointer pointer(buffer);
|
BufferDataPointer pointer(buffer);
|
||||||
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer));
|
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer));
|
||||||
|
|
|
@ -56,6 +56,10 @@ signals:
|
||||||
|
|
||||||
void rendering();
|
void rendering();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void refreshVoxelData();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual MetavoxelClient* createClient(const SharedNodePointer& node);
|
virtual MetavoxelClient* createClient(const SharedNodePointer& node);
|
||||||
|
@ -102,6 +106,8 @@ public:
|
||||||
|
|
||||||
virtual int parseData(const QByteArray& packet);
|
virtual int parseData(const QByteArray& packet);
|
||||||
|
|
||||||
|
Q_INVOKABLE void refreshVoxelData();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void dataChanged(const MetavoxelData& oldData);
|
virtual void dataChanged(const MetavoxelData& oldData);
|
||||||
|
@ -234,7 +240,7 @@ public:
|
||||||
class VoxelBuffer : public BufferData {
|
class VoxelBuffer : public BufferData {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices,
|
VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices, const QVector<glm::vec3>& hermite,
|
||||||
const QVector<SharedObjectPointer>& materials = QVector<SharedObjectPointer>());
|
const QVector<SharedObjectPointer>& materials = QVector<SharedObjectPointer>());
|
||||||
|
|
||||||
virtual void render(bool cursor = false);
|
virtual void render(bool cursor = false);
|
||||||
|
@ -243,10 +249,13 @@ private:
|
||||||
|
|
||||||
QVector<VoxelPoint> _vertices;
|
QVector<VoxelPoint> _vertices;
|
||||||
QVector<int> _indices;
|
QVector<int> _indices;
|
||||||
|
QVector<glm::vec3> _hermite;
|
||||||
int _vertexCount;
|
int _vertexCount;
|
||||||
int _indexCount;
|
int _indexCount;
|
||||||
|
int _hermiteCount;
|
||||||
QOpenGLBuffer _vertexBuffer;
|
QOpenGLBuffer _vertexBuffer;
|
||||||
QOpenGLBuffer _indexBuffer;
|
QOpenGLBuffer _indexBuffer;
|
||||||
|
QOpenGLBuffer _hermiteBuffer;
|
||||||
QVector<SharedObjectPointer> _materials;
|
QVector<SharedObjectPointer> _materials;
|
||||||
QVector<NetworkTexturePointer> _networkTextures;
|
QVector<NetworkTexturePointer> _networkTextures;
|
||||||
};
|
};
|
||||||
|
@ -272,6 +281,9 @@ public:
|
||||||
|
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
|
static ProgramObject& getPointProgram() { return _pointProgram; }
|
||||||
|
static int getPointScaleLocation() { return _pointScaleLocation; }
|
||||||
|
|
||||||
static ProgramObject& getBaseHeightfieldProgram() { return _baseHeightfieldProgram; }
|
static ProgramObject& getBaseHeightfieldProgram() { return _baseHeightfieldProgram; }
|
||||||
static int getBaseHeightScaleLocation() { return _baseHeightScaleLocation; }
|
static int getBaseHeightScaleLocation() { return _baseHeightScaleLocation; }
|
||||||
static int getBaseColorScaleLocation() { return _baseColorScaleLocation; }
|
static int getBaseColorScaleLocation() { return _baseColorScaleLocation; }
|
||||||
|
|
|
@ -1616,8 +1616,74 @@ bool VoxelColorAttribute::merge(void*& parent, void* children[], bool postRead)
|
||||||
maxSize = qMax(maxSize, pointer->getSize());
|
maxSize = qMax(maxSize, pointer->getSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (maxSize == 0) {
|
||||||
*(VoxelColorDataPointer*)&parent = VoxelColorDataPointer();
|
*(VoxelColorDataPointer*)&parent = VoxelColorDataPointer();
|
||||||
return maxSize == 0;
|
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);
|
||||||
|
if (a0 == 0) {
|
||||||
|
*dest++ = qRgba(0, 0, 0, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7;
|
||||||
|
*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;
|
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());
|
maxSize = qMax(maxSize, pointer->getSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (maxSize == 0) {
|
||||||
*(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer();
|
*(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer();
|
||||||
return maxSize == 0;
|
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,
|
SharedObjectAttribute::SharedObjectAttribute(const QString& name, const QMetaObject* metaObject,
|
||||||
|
|
|
@ -374,6 +374,13 @@ void MetavoxelData::clear(const AttributePointer& attribute) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetavoxelData::touch(const AttributePointer& attribute) {
|
||||||
|
MetavoxelNode* root = _roots.value(attribute);
|
||||||
|
if (root) {
|
||||||
|
setRoot(attribute, root->touch(attribute));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class FirstRaySpannerIntersectionVisitor : public RaySpannerIntersectionVisitor {
|
class FirstRaySpannerIntersectionVisitor : public RaySpannerIntersectionVisitor {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -1249,6 +1256,16 @@ void MetavoxelNode::countNodes(const AttributePointer& attribute, const glm::vec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetavoxelNode* MetavoxelNode::touch(const AttributePointer& attribute) const {
|
||||||
|
MetavoxelNode* node = new MetavoxelNode(getAttributeValue(attribute));
|
||||||
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
if (_children[i]) {
|
||||||
|
node->setChild(i, _children[i]->touch(attribute));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
MetavoxelInfo::MetavoxelInfo(MetavoxelInfo* parentInfo, int inputValuesSize, int outputValuesSize) :
|
MetavoxelInfo::MetavoxelInfo(MetavoxelInfo* parentInfo, int inputValuesSize, int outputValuesSize) :
|
||||||
parentInfo(parentInfo),
|
parentInfo(parentInfo),
|
||||||
inputValues(inputValuesSize),
|
inputValues(inputValuesSize),
|
||||||
|
|
|
@ -112,6 +112,9 @@ public:
|
||||||
/// Clears all data in the specified attribute layer.
|
/// Clears all data in the specified attribute layer.
|
||||||
void clear(const AttributePointer& attribute);
|
void clear(const AttributePointer& attribute);
|
||||||
|
|
||||||
|
/// "Touches" all data in the specified attribute layer, making it look as if it has changed.
|
||||||
|
void touch(const AttributePointer& attribute);
|
||||||
|
|
||||||
/// Convenience function that finds the first spanner intersecting the provided ray.
|
/// Convenience function that finds the first spanner intersecting the provided ray.
|
||||||
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());
|
||||||
|
@ -254,6 +257,8 @@ public:
|
||||||
void countNodes(const AttributePointer& attribute, const glm::vec3& minimum,
|
void countNodes(const AttributePointer& attribute, const glm::vec3& minimum,
|
||||||
float size, const MetavoxelLOD& lod, int& internalNodes, int& leaves) const;
|
float size, const MetavoxelLOD& lod, int& internalNodes, int& leaves) const;
|
||||||
|
|
||||||
|
MetavoxelNode* touch(const AttributePointer& attribute) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(MetavoxelNode)
|
Q_DISABLE_COPY(MetavoxelNode)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue