mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
If there's no directly intersecting spanner, find the closest heightfield that
we can project onto.
This commit is contained in:
parent
45b36b383c
commit
2497b2fe39
2 changed files with 65 additions and 8 deletions
|
@ -1957,15 +1957,14 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g
|
|||
}
|
||||
}
|
||||
// determine whether we should ignore this vertex because it will be stitched
|
||||
bool ignore = false;
|
||||
int validCrossings = 0;
|
||||
for (int i = 0; i < crossingCount; i++) {
|
||||
if (qAlpha(crossings[i].color) == 0) {
|
||||
ignore = true;
|
||||
break;
|
||||
if (qAlpha(crossings[i].color) != 0) {
|
||||
validCrossings++;
|
||||
}
|
||||
}
|
||||
NormalIndex index = { { -1, -1, -1, -1 } };
|
||||
if (!ignore) {
|
||||
if (validCrossings != 0) {
|
||||
index.indices[0] = index.indices[1] = index.indices[2] = index.indices[3] = vertices.size();
|
||||
glm::vec3 center;
|
||||
glm::vec3 normals[MAX_NORMALS_PER_VERTEX];
|
||||
|
@ -1978,6 +1977,9 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g
|
|||
int red = 0, green = 0, blue = 0;
|
||||
for (int i = 0; i < crossingCount; i++) {
|
||||
const EdgeCrossing& crossing = crossings[i];
|
||||
if (qAlpha(crossing.color) == 0) {
|
||||
continue;
|
||||
}
|
||||
center += crossing.point;
|
||||
|
||||
int j = 0;
|
||||
|
@ -2013,7 +2015,7 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g
|
|||
}
|
||||
}
|
||||
}
|
||||
center /= crossingCount;
|
||||
center /= validCrossings;
|
||||
|
||||
// use a sequence of Givens rotations to perform a QR decomposition
|
||||
// see http://www.cs.rice.edu/~jwarren/papers/techreport02408.pdf
|
||||
|
@ -2021,6 +2023,9 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g
|
|||
glm::vec4 bottom;
|
||||
for (int i = 0; i < crossingCount; i++) {
|
||||
const EdgeCrossing& crossing = crossings[i];
|
||||
if (qAlpha(crossing.color) == 0) {
|
||||
continue;
|
||||
}
|
||||
bottom = glm::vec4(crossing.normal, glm::dot(crossing.normal, crossing.point - center));
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
|
@ -2085,8 +2090,8 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g
|
|||
materialWeights *= (numeric_limits<quint8>::max() / totalWeight);
|
||||
}
|
||||
VoxelPoint point = { (glm::vec3(clampedX, y, clampedZ) + center) * step,
|
||||
{ (quint8)(red / crossingCount), (quint8)(green / crossingCount),
|
||||
(quint8)(blue / crossingCount) },
|
||||
{ (quint8)(red / validCrossings), (quint8)(green / validCrossings),
|
||||
(quint8)(blue / validCrossings) },
|
||||
{ (char)(normals[0].x * 127.0f), (char)(normals[0].y * 127.0f),
|
||||
(char)(normals[0].z * 127.0f) },
|
||||
{ materials[0], materials[1], materials[2], materials[3] },
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
#include "MetavoxelMessages.h"
|
||||
#include "Spanner.h"
|
||||
|
||||
|
@ -180,6 +182,50 @@ HeightfieldMaterialSpannerEdit::HeightfieldMaterialSpannerEdit(const SharedObjec
|
|||
paint(paint) {
|
||||
}
|
||||
|
||||
class SpannerProjectionFetchVisitor : public SpannerVisitor {
|
||||
public:
|
||||
|
||||
SpannerProjectionFetchVisitor(const Box& bounds, QVector<SharedObjectPointer>& results);
|
||||
|
||||
virtual bool visit(Spanner* spanner);
|
||||
|
||||
private:
|
||||
|
||||
const Box& _bounds;
|
||||
QVector<SharedObjectPointer>& _results;
|
||||
float _closestDistance;
|
||||
};
|
||||
|
||||
SpannerProjectionFetchVisitor::SpannerProjectionFetchVisitor(const Box& bounds, QVector<SharedObjectPointer>& results) :
|
||||
SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute()),
|
||||
_bounds(bounds),
|
||||
_results(results),
|
||||
_closestDistance(FLT_MAX) {
|
||||
}
|
||||
|
||||
bool SpannerProjectionFetchVisitor::visit(Spanner* spanner) {
|
||||
Heightfield* heightfield = qobject_cast<Heightfield*>(spanner);
|
||||
if (!heightfield) {
|
||||
return true;
|
||||
}
|
||||
glm::mat4 transform = glm::scale(1.0f / glm::vec3(heightfield->getScale(),
|
||||
heightfield->getScale() * heightfield->getAspectY(),
|
||||
heightfield->getScale() * heightfield->getAspectZ())) *
|
||||
glm::mat4_cast(glm::inverse(heightfield->getRotation())) * glm::translate(-heightfield->getTranslation());
|
||||
Box transformedBounds = transform * _bounds;
|
||||
if (transformedBounds.maximum.x < 0.0f && transformedBounds.maximum.z < 0.0f &&
|
||||
transformedBounds.minimum.x > 1.0f && transformedBounds.minimum.z > 1.0f) {
|
||||
return true;
|
||||
}
|
||||
float distance = qMin(glm::abs(transformedBounds.minimum.y), glm::abs(transformedBounds.maximum.y));
|
||||
if (distance < _closestDistance) {
|
||||
_results.clear();
|
||||
_results.append(spanner);
|
||||
_closestDistance = distance;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void HeightfieldMaterialSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
||||
// make sure the color meets our transparency requirements
|
||||
QColor color = averageColor;
|
||||
|
@ -193,6 +239,12 @@ void HeightfieldMaterialSpannerEdit::apply(MetavoxelData& data, const WeakShared
|
|||
data.getIntersecting(AttributeRegistry::getInstance()->getSpannersAttribute(),
|
||||
static_cast<Spanner*>(spanner.data())->getBounds(), results);
|
||||
|
||||
// if there's nothing intersecting directly, find the closest heightfield that intersects the projection
|
||||
if (results.isEmpty()) {
|
||||
SpannerProjectionFetchVisitor visitor(static_cast<Spanner*>(spanner.data())->getBounds(), results);
|
||||
data.guide(visitor);
|
||||
}
|
||||
|
||||
foreach (const SharedObjectPointer& result, results) {
|
||||
Spanner* newResult = static_cast<Spanner*>(result.data())->setMaterial(spanner, material, color, paint);
|
||||
if (newResult != result) {
|
||||
|
|
Loading…
Reference in a new issue