mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 05:23:33 +02:00
More progress on stack edits.
This commit is contained in:
parent
ab52f434c9
commit
068d6035c0
1 changed files with 74 additions and 40 deletions
|
@ -2389,8 +2389,8 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
Box transformedBounds = inverseTransform * spanner->getBounds();
|
Box transformedBounds = inverseTransform * spanner->getBounds();
|
||||||
glm::mat4 transform = glm::inverse(inverseTransform);
|
glm::mat4 transform = glm::inverse(inverseTransform);
|
||||||
|
|
||||||
glm::vec3 start = glm::floor(transformedBounds.minimum);
|
glm::vec3 start = glm::ceil(transformedBounds.maximum);
|
||||||
glm::vec3 end = glm::ceil(transformedBounds.maximum);
|
glm::vec3 end = glm::floor(transformedBounds.minimum);
|
||||||
|
|
||||||
float stepX = (float)innerHeightWidth / qMax(innerHeightWidth, qMax(innerColorWidth, innerMaterialWidth));
|
float stepX = (float)innerHeightWidth / qMax(innerHeightWidth, qMax(innerColorWidth, innerMaterialWidth));
|
||||||
float stepZ = (float)innerHeightHeight / qMax(innerHeightHeight, qMax(innerColorHeight, innerMaterialHeight));
|
float stepZ = (float)innerHeightHeight / qMax(innerHeightHeight, qMax(innerColorHeight, innerMaterialHeight));
|
||||||
|
@ -2399,25 +2399,25 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
float startZ = glm::clamp(start.z, 0.0f, (float)highestHeightZ), endZ = glm::clamp(end.z, 0.0f, (float)highestHeightZ);
|
float startZ = glm::clamp(start.z, 0.0f, (float)highestHeightZ), endZ = glm::clamp(end.z, 0.0f, (float)highestHeightZ);
|
||||||
glm::vec3 worldStart = glm::vec3(transform * glm::vec4(startX, start.y, startZ, 1.0f));
|
glm::vec3 worldStart = glm::vec3(transform * glm::vec4(startX, start.y, startZ, 1.0f));
|
||||||
glm::vec3 worldStepX = glm::vec3(transform * glm::vec4(stepX, 0.0f, 0.0f, 0.0f));
|
glm::vec3 worldStepX = glm::vec3(transform * glm::vec4(stepX, 0.0f, 0.0f, 0.0f));
|
||||||
glm::vec3 worldStepY = glm::vec3(transform * glm::vec4(0.0f, end.y - start.y, 0.0f, 0.0f));
|
glm::vec3 worldStepY = glm::vec3(transform * glm::vec4(0.0f, start.y - end.y, 0.0f, 0.0f));
|
||||||
glm::vec3 worldStepZ = glm::vec3(transform * glm::vec4(0.0f, 0.0f, stepZ, 0.0f));
|
glm::vec3 worldStepZ = glm::vec3(transform * glm::vec4(0.0f, 0.0f, stepZ, 0.0f));
|
||||||
float voxelStep = scale.x / innerHeightWidth;
|
float voxelStep = scale.x / innerHeightWidth;
|
||||||
float voxelScale = scale.y / (numeric_limits<quint16>::max() * voxelStep);
|
float voxelScale = scale.y / (numeric_limits<quint16>::max() * voxelStep);
|
||||||
glm::vec3 voxelStepY = glm::vec3(transform * glm::vec4(0.0f, 1.0f / voxelScale, 0.0f, 0.0f));
|
glm::vec3 voxelStepY = glm::vec3(transform * glm::vec4(0.0f, 1.0f / voxelScale, 0.0f, 0.0f));
|
||||||
int newTop = end.y * voxelScale;
|
int newTop = start.y * voxelScale;
|
||||||
int newBottom = start.y * voxelScale;
|
int newBottom = end.y * voxelScale;
|
||||||
char r = color.red(), g = color.green(), b = color.blue(), a = color.alpha();
|
char r = color.red(), g = color.green(), b = color.blue(), a = color.alpha();
|
||||||
bool erase = (a == 0);
|
bool erase = (a == 0);
|
||||||
uchar materialIndex = getMaterialIndex(material, newMaterialMaterials, newMaterialContents);
|
uchar materialIndex = getMaterialIndex(material, newMaterialMaterials, newMaterialContents);
|
||||||
bool hasOwnColors = spanner->hasOwnColors();
|
bool hasOwnColors = spanner->hasOwnColors();
|
||||||
bool hasOwnMaterials = spanner->hasOwnMaterials();
|
bool hasOwnMaterials = spanner->hasOwnMaterials();
|
||||||
QHash<int, int> materialMappings;
|
QHash<int, int> materialMappings;
|
||||||
for (float z = startZ; z <= endZ; z += stepZ, worldStart += worldStepZ) {
|
for (float z = startZ; z >= endZ; z -= stepZ, worldStart -= worldStepZ) {
|
||||||
quint16* heightDest = newHeightContents.data() + (int)z * heightWidth;
|
quint16* heightDest = newHeightContents.data() + (int)z * heightWidth;
|
||||||
glm::vec3 worldPos = worldStart;
|
glm::vec3 worldPos = worldStart;
|
||||||
for (float x = startX; x <= endX; x += stepX, worldPos += worldStepX) {
|
for (float x = startX; x >= endX; x -= stepX, worldPos -= worldStepX) {
|
||||||
quint16* heightLineDest = heightDest + (int)x;
|
quint16* heightLineDest = heightDest + (int)x;
|
||||||
glm::vec3 endPos = worldPos + worldStepY;
|
glm::vec3 endPos = worldPos - worldStepY;
|
||||||
float distance;
|
float distance;
|
||||||
glm::vec3 normal;
|
glm::vec3 normal;
|
||||||
|
|
||||||
|
@ -2443,49 +2443,83 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
char* entryDest = stackDest->data() + offset;
|
char* entryDest = stackDest->data() + offset;
|
||||||
glm::vec3 pos = glm::vec3(transform * glm::vec4(x, 0.0f, z, 1.0f)) + voxelStepY * (float)newTop;
|
glm::vec3 pos = glm::vec3(transform * glm::vec4(x, 0.0f, z, 1.0f)) + voxelStepY * (float)newTop;
|
||||||
for (int y = newTop; y >= newBottom; y--, entryDest += HeightfieldStack::ENTRY_BYTES, pos -= voxelStepY) {
|
for (int y = newTop; y >= newBottom; y--, entryDest += HeightfieldStack::ENTRY_BYTES, pos -= voxelStepY) {
|
||||||
if (!spanner->contains(pos)) {
|
if (spanner->contains(pos)) {
|
||||||
continue;
|
if (hasOwnColors && !erase) {
|
||||||
}
|
QRgb spannerColor = spanner->getColorAt(pos);
|
||||||
if (hasOwnColors && !erase) {
|
entryDest[0] = qRed(spannerColor);
|
||||||
QRgb spannerColor = spanner->getColorAt(pos);
|
entryDest[1] = qGreen(spannerColor);
|
||||||
entryDest[0] = qRed(spannerColor);
|
entryDest[2] = qBlue(spannerColor);
|
||||||
entryDest[1] = qGreen(spannerColor);
|
entryDest[3] = qAlpha(spannerColor);
|
||||||
entryDest[2] = qBlue(spannerColor);
|
|
||||||
entryDest[3] = qAlpha(spannerColor);
|
} else {
|
||||||
|
entryDest[0] = r;
|
||||||
} else {
|
entryDest[1] = g;
|
||||||
entryDest[0] = r;
|
entryDest[2] = b;
|
||||||
entryDest[1] = g;
|
entryDest[3] = a;
|
||||||
entryDest[2] = b;
|
|
||||||
entryDest[3] = a;
|
|
||||||
}
|
|
||||||
if (hasOwnMaterials && !erase) {
|
|
||||||
int index = spanner->getMaterialAt(pos);
|
|
||||||
if (index != 0) {
|
|
||||||
int& mapping = materialMappings[index];
|
|
||||||
if (mapping == 0) {
|
|
||||||
mapping = getMaterialIndex(spanner->getMaterials().at(index - 1),
|
|
||||||
newMaterialMaterials, newMaterialContents);
|
|
||||||
}
|
|
||||||
index = mapping;
|
|
||||||
}
|
}
|
||||||
entryDest[4] = index;
|
if (hasOwnMaterials && !erase) {
|
||||||
|
int index = spanner->getMaterialAt(pos);
|
||||||
|
if (index != 0) {
|
||||||
|
int& mapping = materialMappings[index];
|
||||||
|
if (mapping == 0) {
|
||||||
|
mapping = getMaterialIndex(spanner->getMaterials().at(index - 1),
|
||||||
|
newMaterialMaterials, newMaterialContents);
|
||||||
|
}
|
||||||
|
index = mapping;
|
||||||
|
}
|
||||||
|
entryDest[4] = index;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
entryDest[4] = materialIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int nextStackX = (int)stackX + 1;
|
||||||
|
if (nextStackX <= innerStackWidth) {
|
||||||
|
QByteArray* nextStackDest = newStackContents.data() + (int)stackZ * stackWidth + (int)nextStackX;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (entryDest != stackDest->data()) {
|
||||||
|
bool previousSet = ((entryDest - HeightfieldStack::ENTRY_BYTES)[3] != 0);
|
||||||
|
bool currentSet = (entryDest[3] != 0);
|
||||||
|
if (previousSet == currentSet) {
|
||||||
|
entryDest[9] = entryDest[10] = entryDest[11] = entryDest[12] = 0;
|
||||||
|
} else {
|
||||||
|
bool intersects;
|
||||||
|
if (erase == previousSet) {
|
||||||
|
if ((intersects = spanner->intersects(pos - voxelStepY, pos, distance, normal))) {
|
||||||
|
distance = 1.0f - distance;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
intersects = spanner->intersects(pos, pos - voxelStepY, distance, normal);
|
||||||
|
}
|
||||||
|
if (intersects) {
|
||||||
|
if (erase) {
|
||||||
|
normal = -normal;
|
||||||
|
}
|
||||||
|
entryDest[9] = normal.x * numeric_limits<qint8>::max();
|
||||||
|
entryDest[10] = normal.y * numeric_limits<qint8>::max();
|
||||||
|
entryDest[11] = normal.z * numeric_limits<qint8>::max();
|
||||||
|
entryDest[12] = distance * numeric_limits<quint8>::max();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int nextStackZ = (int)stackZ + 1;
|
||||||
|
if (nextStackZ <= innerStackHeight) {
|
||||||
|
QByteArray* nextStackDest = newStackContents.data() + (int)nextStackZ * stackWidth + (int)stackX;
|
||||||
|
|
||||||
} else {
|
|
||||||
entryDest[4] = materialIndex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (erase) {
|
if (erase) {
|
||||||
if (spanner->intersects(worldPos, endPos, distance, normal)) {
|
if (spanner->intersects(endPos, worldPos, distance, normal)) {
|
||||||
quint16 height = glm::round(glm::mix(start.y, end.y, distance));
|
quint16 height = glm::round(glm::mix(end.y, start.y, distance));
|
||||||
if (height <= *heightLineDest) {
|
if (height <= *heightLineDest) {
|
||||||
*heightLineDest = height;
|
*heightLineDest = height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (spanner->intersects(endPos, worldPos, distance, normal)) {
|
} else if (spanner->intersects(worldPos, endPos, distance, normal)) {
|
||||||
quint16 height = glm::round(glm::mix(end.y, start.y, distance));
|
quint16 height = glm::round(glm::mix(start.y, end.y, distance));
|
||||||
if (height >= *heightLineDest) {
|
if (height >= *heightLineDest) {
|
||||||
*heightLineDest = height;
|
*heightLineDest = height;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue