1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-30 16:20:21 +00:00

Merge branch 'smoothlandslikesmoothlittlebabies' into 'master'

Editor: Prevent crash on smoothing undefined cell borders (#8299)

Closes #8299

See merge request OpenMW/openmw!4512
This commit is contained in:
psi29a 2025-01-14 11:18:28 +00:00
commit af3640217e
2 changed files with 53 additions and 43 deletions

View File

@ -227,6 +227,7 @@
Bug #8237: Non-bipedal creatures should *not* use spellcast equip/unequip animations Bug #8237: Non-bipedal creatures should *not* use spellcast equip/unequip animations
Bug #8252: Plugin dependencies are not required to be loaded Bug #8252: Plugin dependencies are not required to be loaded
Bug #8295: Post-processing chain is case-sensitive Bug #8295: Post-processing chain is case-sensitive
Bug #8299: Crash while smoothing landscape
Feature #1415: Infinite fall failsafe Feature #1415: Infinite fall failsafe
Feature #2566: Handle NAM9 records for manual cell references Feature #2566: Handle NAM9 records for manual cell references
Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking

View File

@ -761,18 +761,17 @@ void CSVRender::TerrainShapeMode::smoothHeight(
// this = this Cell // this = this Cell
// left = x - 1, up = y - 1, right = x + 1, down = y + 1 // left = x - 1, up = y - 1, right = x + 1, down = y + 1
// Altered = transient edit (in current edited) // Altered = transient edit (in current edited)
float thisAlteredHeight = 0.0f;
if (paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) != nullptr)
thisAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY);
float thisHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX]; float thisHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX];
float leftHeight = 0.0f; float* thisAlteredHeightPtr = paged->getCellAlteredHeight(cellCoords, inCellX, inCellY);
float leftAlteredHeight = 0.0f; float thisAlteredHeight = thisAlteredHeightPtr != nullptr ? *thisAlteredHeightPtr : 0.f;
float upAlteredHeight = 0.0f; float leftHeight = thisHeight;
float rightHeight = 0.0f; float leftAlteredHeight = thisAlteredHeight;
float rightAlteredHeight = 0.0f; float rightHeight = thisHeight;
float downHeight = 0.0f; float rightAlteredHeight = thisAlteredHeight;
float downAlteredHeight = 0.0f; float downHeight = thisHeight;
float upHeight = 0.0f; float downAlteredHeight = thisAlteredHeight;
float upHeight = thisHeight;
float upAlteredHeight = thisAlteredHeight;
if (allowLandShapeEditing(cellId)) if (allowLandShapeEditing(cellId))
{ {
@ -780,70 +779,80 @@ void CSVRender::TerrainShapeMode::smoothHeight(
if (inCellX == 0) if (inCellX == 0)
{ {
cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX() - 1, cellCoords.getY()); cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX() - 1, cellCoords.getY());
const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer if (isLandLoaded(cellId))
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) {
.value<CSMWorld::LandHeightsColumn::DataType>(); const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer
leftHeight = landLeftShapePointer[inCellY * ESM::Land::LAND_SIZE + (ESM::Land::LAND_SIZE - 2)]; = landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
if (paged->getCellAlteredHeight(cellCoords.move(-1, 0), inCellX, ESM::Land::LAND_SIZE - 2)) .value<CSMWorld::LandHeightsColumn::DataType>();
leftAlteredHeight leftHeight = landLeftShapePointer[inCellY * ESM::Land::LAND_SIZE + (ESM::Land::LAND_SIZE - 2)];
= *paged->getCellAlteredHeight(cellCoords.move(-1, 0), ESM::Land::LAND_SIZE - 2, inCellY); float* alteredHeightPtr
= paged->getCellAlteredHeight(cellCoords.move(-1, 0), ESM::Land::LAND_SIZE - 2, inCellY);
leftAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
}
} }
if (inCellY == 0) if (inCellY == 0)
{ {
cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() - 1); cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() - 1);
const CSMWorld::LandHeightsColumn::DataType landUpShapePointer if (isLandLoaded(cellId))
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) {
.value<CSMWorld::LandHeightsColumn::DataType>(); const CSMWorld::LandHeightsColumn::DataType landUpShapePointer
upHeight = landUpShapePointer[(ESM::Land::LAND_SIZE - 2) * ESM::Land::LAND_SIZE + inCellX]; = landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
if (paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2)) .value<CSMWorld::LandHeightsColumn::DataType>();
upAlteredHeight upHeight = landUpShapePointer[(ESM::Land::LAND_SIZE - 2) * ESM::Land::LAND_SIZE + inCellX];
= *paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2); float* alteredHeightPtr
= paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2);
upAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
}
} }
if (inCellX > 0) if (inCellX > 0)
{ {
leftHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX - 1]; leftHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX - 1];
leftAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX - 1, inCellY); float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords, inCellX - 1, inCellY);
leftAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
} }
if (inCellY > 0) if (inCellY > 0)
{ {
upHeight = landShapePointer[(inCellY - 1) * ESM::Land::LAND_SIZE + inCellX]; upHeight = landShapePointer[(inCellY - 1) * ESM::Land::LAND_SIZE + inCellX];
upAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY - 1); float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords, inCellX, inCellY - 1);
upAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
} }
if (inCellX == ESM::Land::LAND_SIZE - 1) if (inCellX == ESM::Land::LAND_SIZE - 1)
{ {
cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX() + 1, cellCoords.getY()); cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX() + 1, cellCoords.getY());
const CSMWorld::LandHeightsColumn::DataType landRightShapePointer if (isLandLoaded(cellId))
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
.value<CSMWorld::LandHeightsColumn::DataType>();
rightHeight = landRightShapePointer[inCellY * ESM::Land::LAND_SIZE + 1];
if (paged->getCellAlteredHeight(cellCoords.move(1, 0), 1, inCellY))
{ {
rightAlteredHeight = *paged->getCellAlteredHeight(cellCoords.move(1, 0), 1, inCellY); const CSMWorld::LandHeightsColumn::DataType landRightShapePointer
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
.value<CSMWorld::LandHeightsColumn::DataType>();
rightHeight = landRightShapePointer[inCellY * ESM::Land::LAND_SIZE + 1];
float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords.move(1, 0), 1, inCellY);
rightAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
} }
} }
if (inCellY == ESM::Land::LAND_SIZE - 1) if (inCellY == ESM::Land::LAND_SIZE - 1)
{ {
cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() + 1); cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() + 1);
const CSMWorld::LandHeightsColumn::DataType landDownShapePointer if (isLandLoaded(cellId))
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
.value<CSMWorld::LandHeightsColumn::DataType>();
downHeight = landDownShapePointer[1 * ESM::Land::LAND_SIZE + inCellX];
if (paged->getCellAlteredHeight(cellCoords.move(0, 1), inCellX, 1))
{ {
downAlteredHeight = *paged->getCellAlteredHeight(cellCoords.move(0, 1), inCellX, 1); const CSMWorld::LandHeightsColumn::DataType landDownShapePointer
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
.value<CSMWorld::LandHeightsColumn::DataType>();
downHeight = landDownShapePointer[1 * ESM::Land::LAND_SIZE + inCellX];
float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords.move(0, 1), inCellX, 1);
downAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
} }
} }
if (inCellX < ESM::Land::LAND_SIZE - 1) if (inCellX < ESM::Land::LAND_SIZE - 1)
{ {
rightHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX + 1]; rightHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX + 1];
if (paged->getCellAlteredHeight(cellCoords, inCellX + 1, inCellY)) float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords, inCellX + 1, inCellY);
rightAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX + 1, inCellY); rightAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
} }
if (inCellY < ESM::Land::LAND_SIZE - 1) if (inCellY < ESM::Land::LAND_SIZE - 1)
{ {
downHeight = landShapePointer[(inCellY + 1) * ESM::Land::LAND_SIZE + inCellX]; downHeight = landShapePointer[(inCellY + 1) * ESM::Land::LAND_SIZE + inCellX];
if (paged->getCellAlteredHeight(cellCoords, inCellX, inCellY + 1)) float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords, inCellX, inCellY + 1);
downAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY + 1); downAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
} }
float averageHeight = (upHeight + downHeight + rightHeight + leftHeight + upAlteredHeight float averageHeight = (upHeight + downHeight + rightHeight + leftHeight + upAlteredHeight