mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 16:41:02 +02:00
Merge pull request #3657 from ey6es/metavoxels
Further incremental improvements to heightfield voxelization.
This commit is contained in:
commit
3f7df5962d
6 changed files with 126 additions and 71 deletions
|
@ -26,11 +26,14 @@ varying vec4 normal;
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// transform and store the normal for interpolation
|
// transform and store the normal for interpolation
|
||||||
vec2 heightCoord = gl_MultiTexCoord0.st;
|
vec2 heightCoord = gl_MultiTexCoord0.st;
|
||||||
float deltaX = texture2D(heightMap, heightCoord - vec2(heightScale, 0.0)).r -
|
vec4 neighborHeights = vec4(texture2D(heightMap, heightCoord - vec2(heightScale, 0.0)).r,
|
||||||
texture2D(heightMap, heightCoord + vec2(heightScale, 0.0)).r;
|
texture2D(heightMap, heightCoord + vec2(heightScale, 0.0)).r,
|
||||||
float deltaZ = texture2D(heightMap, heightCoord - vec2(0.0, heightScale)).r -
|
texture2D(heightMap, heightCoord - vec2(0.0, heightScale)).r,
|
||||||
texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r;
|
texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r);
|
||||||
normal = normalize(gl_ModelViewMatrix * vec4(deltaX, heightScale, deltaZ, 0.0));
|
vec4 neighborsZero = step(1.0 / 255.0, neighborHeights);
|
||||||
|
normal = normalize(gl_ModelViewMatrix * vec4(
|
||||||
|
(neighborHeights.x - neighborHeights.y) * neighborsZero.x * neighborsZero.y, heightScale,
|
||||||
|
(neighborHeights.z - neighborHeights.w) * neighborsZero.z * neighborsZero.w, 0.0));
|
||||||
|
|
||||||
// add the height to the position
|
// add the height to the position
|
||||||
float height = texture2D(heightMap, heightCoord).r;
|
float height = texture2D(heightMap, heightCoord).r;
|
||||||
|
|
|
@ -432,6 +432,8 @@ Menu::Menu() :
|
||||||
QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels");
|
QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels");
|
||||||
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false,
|
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false,
|
||||||
Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData()));
|
Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData()));
|
||||||
|
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::RenderHeightfields, 0, true);
|
||||||
|
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::RenderDualContourSurfaces, 0, true);
|
||||||
addActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::NetworkSimulator, 0, this,
|
addActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::NetworkSimulator, 0, this,
|
||||||
SLOT(showMetavoxelNetworkSimulator()));
|
SLOT(showMetavoxelNetworkSimulator()));
|
||||||
|
|
||||||
|
|
|
@ -446,8 +446,10 @@ namespace MenuOption {
|
||||||
const QString Quit = "Quit";
|
const QString Quit = "Quit";
|
||||||
const QString ReloadAllScripts = "Reload All Scripts";
|
const QString ReloadAllScripts = "Reload All Scripts";
|
||||||
const QString RenderBoundingCollisionShapes = "Show Bounding Collision Shapes";
|
const QString RenderBoundingCollisionShapes = "Show Bounding Collision Shapes";
|
||||||
|
const QString RenderDualContourSurfaces = "Render Dual Contour Surfaces";
|
||||||
const QString RenderFocusIndicator = "Show Eye Focus";
|
const QString RenderFocusIndicator = "Show Eye Focus";
|
||||||
const QString RenderHeadCollisionShapes = "Show Head Collision Shapes";
|
const QString RenderHeadCollisionShapes = "Show Head Collision Shapes";
|
||||||
|
const QString RenderHeightfields = "Render Heightfields";
|
||||||
const QString RenderLookAtVectors = "Show Look-at Vectors";
|
const QString RenderLookAtVectors = "Show Look-at Vectors";
|
||||||
const QString RenderSkeletonCollisionShapes = "Show Skeleton Collision Shapes";
|
const QString RenderSkeletonCollisionShapes = "Show Skeleton Collision Shapes";
|
||||||
const QString RenderResolution = "Scale Resolution";
|
const QString RenderResolution = "Scale Resolution";
|
||||||
|
|
|
@ -2772,6 +2772,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
|
||||||
|
|
||||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeightfields)) {
|
||||||
_baseHeightfieldProgram.bind();
|
_baseHeightfieldProgram.bind();
|
||||||
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
@ -2779,16 +2780,12 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
|
||||||
BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute());
|
BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute());
|
||||||
data.guide(heightfieldRenderVisitor);
|
data.guide(heightfieldRenderVisitor);
|
||||||
|
|
||||||
_baseHeightfieldProgram.release();
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
_baseHeightfieldProgram.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderDualContourSurfaces)) {
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
|
@ -2799,13 +2796,15 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
|
||||||
|
|
||||||
_baseVoxelProgram.release();
|
_baseVoxelProgram.release();
|
||||||
|
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
|
||||||
|
|
||||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2486,8 +2486,39 @@ bool Heightfield::intersects(const glm::vec3& start, const glm::vec3& end, float
|
||||||
if (!getBounds().findRayIntersection(start, direction, rayDistance) || rayDistance > 1.0f) {
|
if (!getBounds().findRayIntersection(start, direction, rayDistance) || rayDistance > 1.0f) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
glm::vec3 entry = (start + direction * rayDistance - getBounds().minimum) / _increment;
|
glm::vec3 entry = start + direction * rayDistance;
|
||||||
direction /= _increment;
|
const float DISTANCE_THRESHOLD = 0.001f;
|
||||||
|
if (glm::abs(entry.x - getBounds().minimum.x) < DISTANCE_THRESHOLD) {
|
||||||
|
normal = glm::vec3(-1.0f, 0.0f, 0.0f);
|
||||||
|
distance = rayDistance;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else if (glm::abs(entry.x - getBounds().maximum.x) < DISTANCE_THRESHOLD) {
|
||||||
|
normal = glm::vec3(1.0f, 0.0f, 0.0f);
|
||||||
|
distance = rayDistance;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else if (glm::abs(entry.y - getBounds().minimum.y) < DISTANCE_THRESHOLD) {
|
||||||
|
normal = glm::vec3(0.0f, -1.0f, 0.0f);
|
||||||
|
distance = rayDistance;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else if (glm::abs(entry.y - getBounds().maximum.y) < DISTANCE_THRESHOLD) {
|
||||||
|
normal = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||||
|
distance = rayDistance;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else if (glm::abs(entry.z - getBounds().minimum.z) < DISTANCE_THRESHOLD) {
|
||||||
|
normal = glm::vec3(0.0f, 0.0f, -1.0f);
|
||||||
|
distance = rayDistance;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else if (glm::abs(entry.z - getBounds().maximum.z) < DISTANCE_THRESHOLD) {
|
||||||
|
normal = glm::vec3(0.0f, 0.0f, 1.0f);
|
||||||
|
distance = rayDistance;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
entry = (entry - getBounds().minimum) / _increment;
|
||||||
glm::vec3 floors = glm::floor(entry);
|
glm::vec3 floors = glm::floor(entry);
|
||||||
glm::vec3 ceils = glm::ceil(entry);
|
glm::vec3 ceils = glm::ceil(entry);
|
||||||
if (floors.x == ceils.x) {
|
if (floors.x == ceils.x) {
|
||||||
|
|
|
@ -998,10 +998,13 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) {
|
||||||
_spannerBounds.maximum = (glm::ceil(_bounds.maximum / increment) + glm::vec3(1.0f, 0.0f, 1.0f)) * increment;
|
_spannerBounds.maximum = (glm::ceil(_bounds.maximum / increment) + glm::vec3(1.0f, 0.0f, 1.0f)) * increment;
|
||||||
_spannerBounds.minimum.y = bounds.minimum.y;
|
_spannerBounds.minimum.y = bounds.minimum.y;
|
||||||
_spannerBounds.maximum.y = bounds.maximum.y;
|
_spannerBounds.maximum.y = bounds.maximum.y;
|
||||||
_heightfieldWidth = (int)glm::round((_spannerBounds.maximum.x - _spannerBounds.minimum.x) / increment) + 1;
|
_heightfieldWidth = (int)glm::round((_spannerBounds.maximum.x - _spannerBounds.minimum.x) / increment);
|
||||||
_heightfieldHeight = (int)glm::round((_spannerBounds.maximum.z - _spannerBounds.minimum.z) / increment) + 1;
|
_heightfieldHeight = (int)glm::round((_spannerBounds.maximum.z - _spannerBounds.minimum.z) / increment);
|
||||||
int heightfieldArea = _heightfieldWidth * _heightfieldHeight;
|
int heightfieldArea = _heightfieldWidth * _heightfieldHeight;
|
||||||
_spanner = spanner = new Heightfield(_spannerBounds, increment, QByteArray(heightfieldArea, 0),
|
Box innerBounds = _spannerBounds;
|
||||||
|
innerBounds.maximum.x -= increment;
|
||||||
|
innerBounds.maximum.z -= increment;
|
||||||
|
_spanner = spanner = new Heightfield(innerBounds, increment, QByteArray(heightfieldArea, 0),
|
||||||
QByteArray(heightfieldArea * DataBlock::COLOR_BYTES, 0), QByteArray(heightfieldArea, 0),
|
QByteArray(heightfieldArea * DataBlock::COLOR_BYTES, 0), QByteArray(heightfieldArea, 0),
|
||||||
QVector<SharedObjectPointer>());
|
QVector<SharedObjectPointer>());
|
||||||
}
|
}
|
||||||
|
@ -1049,19 +1052,21 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if all is gone, clear the node
|
// if all is gone, clear the node
|
||||||
if (!foundNonZero) {
|
if (foundNonZero) {
|
||||||
info.outputValues[0] = AttributeValue(_outputs.at(0),
|
|
||||||
encodeInline<HeightfieldHeightDataPointer>(HeightfieldHeightDataPointer()));
|
|
||||||
info.outputValues[1] = AttributeValue(_outputs.at(1),
|
|
||||||
encodeInline<HeightfieldColorDataPointer>(HeightfieldColorDataPointer()));
|
|
||||||
info.outputValues[2] = AttributeValue(_outputs.at(2),
|
|
||||||
encodeInline<HeightfieldMaterialDataPointer>(HeightfieldMaterialDataPointer()));
|
|
||||||
return STOP_RECURSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
HeightfieldHeightDataPointer newHeightPointer(new HeightfieldHeightData(contents));
|
HeightfieldHeightDataPointer newHeightPointer(new HeightfieldHeightData(contents));
|
||||||
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline<HeightfieldHeightDataPointer>(newHeightPointer));
|
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline<HeightfieldHeightDataPointer>(newHeightPointer));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
info.outputValues[0] = AttributeValue(_outputs.at(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow a border for what we clear in terms of color/material
|
||||||
|
innerBounds.minimum.x += increment;
|
||||||
|
innerBounds.minimum.z += increment;
|
||||||
|
innerBounds.maximum.x -= increment;
|
||||||
|
innerBounds.maximum.z -= increment;
|
||||||
|
innerOverlap = bounds.getIntersection(innerBounds);
|
||||||
|
|
||||||
HeightfieldColorDataPointer colorPointer = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>();
|
HeightfieldColorDataPointer colorPointer = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>();
|
||||||
if (colorPointer) {
|
if (colorPointer) {
|
||||||
contents = colorPointer->getContents();
|
contents = colorPointer->getContents();
|
||||||
|
@ -1083,10 +1088,12 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) {
|
||||||
memcpy(dest, src, destWidth * DataBlock::COLOR_BYTES);
|
memcpy(dest, src, destWidth * DataBlock::COLOR_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (foundNonZero) {
|
||||||
destX = (innerOverlap.minimum.x - info.minimum.x) * heightScale;
|
destX = (innerOverlap.minimum.x - info.minimum.x) * heightScale;
|
||||||
destY = (innerOverlap.minimum.z - info.minimum.z) * heightScale;
|
destY = (innerOverlap.minimum.z - info.minimum.z) * heightScale;
|
||||||
destWidth = glm::ceil((innerOverlap.maximum.x - innerOverlap.minimum.x) * heightScale);
|
destWidth = glm::ceil((innerOverlap.maximum.x - innerOverlap.minimum.x) * heightScale);
|
||||||
destHeight = glm::ceil((innerOverlap.maximum.z - innerOverlap.minimum.z) * heightScale);
|
destHeight = glm::ceil((innerOverlap.maximum.z - innerOverlap.minimum.z) * heightScale);
|
||||||
|
if (destWidth > 0 && destHeight > 0) {
|
||||||
dest = contents.data() + (destY * size + destX) * DataBlock::COLOR_BYTES;
|
dest = contents.data() + (destY * size + destX) * DataBlock::COLOR_BYTES;
|
||||||
|
|
||||||
for (int y = 0; y < destHeight; y++, dest += size * DataBlock::COLOR_BYTES) {
|
for (int y = 0; y < destHeight; y++, dest += size * DataBlock::COLOR_BYTES) {
|
||||||
|
@ -1094,7 +1101,12 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HeightfieldColorDataPointer newColorPointer(new HeightfieldColorData(contents));
|
HeightfieldColorDataPointer newColorPointer(new HeightfieldColorData(contents));
|
||||||
info.outputValues[1] = AttributeValue(_outputs.at(1), encodeInline<HeightfieldColorDataPointer>(newColorPointer));
|
info.outputValues[1] = AttributeValue(_outputs.at(1),
|
||||||
|
encodeInline<HeightfieldColorDataPointer>(newColorPointer));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info.outputValues[1] = AttributeValue(_outputs.at(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HeightfieldMaterialDataPointer materialPointer = info.inputValues.at(2).getInlineValue<HeightfieldMaterialDataPointer>();
|
HeightfieldMaterialDataPointer materialPointer = info.inputValues.at(2).getInlineValue<HeightfieldMaterialDataPointer>();
|
||||||
|
@ -1130,10 +1142,12 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (foundNonZero) {
|
||||||
destX = (innerOverlap.minimum.x - info.minimum.x) * heightScale;
|
destX = (innerOverlap.minimum.x - info.minimum.x) * heightScale;
|
||||||
destY = (innerOverlap.minimum.z - info.minimum.z) * heightScale;
|
destY = (innerOverlap.minimum.z - info.minimum.z) * heightScale;
|
||||||
destWidth = glm::ceil((innerOverlap.maximum.x - innerOverlap.minimum.x) * heightScale);
|
destWidth = glm::ceil((innerOverlap.maximum.x - innerOverlap.minimum.x) * heightScale);
|
||||||
destHeight = glm::ceil((innerOverlap.maximum.z - innerOverlap.minimum.z) * heightScale);
|
destHeight = glm::ceil((innerOverlap.maximum.z - innerOverlap.minimum.z) * heightScale);
|
||||||
|
if (destWidth > 0 && destHeight > 0) {
|
||||||
dest = (uchar*)contents.data() + destY * size + destX;
|
dest = (uchar*)contents.data() + destY * size + destX;
|
||||||
|
|
||||||
for (int y = 0; y < destHeight; y++, dest += size) {
|
for (int y = 0; y < destHeight; y++, dest += size) {
|
||||||
|
@ -1145,6 +1159,10 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) {
|
||||||
info.outputValues[2] = AttributeValue(_outputs.at(2),
|
info.outputValues[2] = AttributeValue(_outputs.at(2),
|
||||||
encodeInline<HeightfieldMaterialDataPointer>(newMaterialPointer));
|
encodeInline<HeightfieldMaterialDataPointer>(newMaterialPointer));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
info.outputValues[2] = AttributeValue(_outputs.at(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return STOP_RECURSION;
|
return STOP_RECURSION;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue