Skip to content

Commit af36402

Browse files
committed
Merge branch 'smoothlandslikesmoothlittlebabies' into 'master'
Editor: Prevent crash on smoothing undefined cell borders (#8299) Closes #8299 See merge request OpenMW/openmw!4512
2 parents df681a0 + d3fe318 commit af36402

File tree

2 files changed

+53
-43
lines changed

2 files changed

+53
-43
lines changed

CHANGELOG.md

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

apps/opencs/view/render/terrainshapemode.cpp

+52-43
Original file line numberDiff line numberDiff line change
@@ -761,89 +761,98 @@ void CSVRender::TerrainShapeMode::smoothHeight(
761761
// this = this Cell
762762
// left = x - 1, up = y - 1, right = x + 1, down = y + 1
763763
// Altered = transient edit (in current edited)
764-
float thisAlteredHeight = 0.0f;
765-
if (paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) != nullptr)
766-
thisAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY);
767764
float thisHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX];
768-
float leftHeight = 0.0f;
769-
float leftAlteredHeight = 0.0f;
770-
float upAlteredHeight = 0.0f;
771-
float rightHeight = 0.0f;
772-
float rightAlteredHeight = 0.0f;
773-
float downHeight = 0.0f;
774-
float downAlteredHeight = 0.0f;
775-
float upHeight = 0.0f;
765+
float* thisAlteredHeightPtr = paged->getCellAlteredHeight(cellCoords, inCellX, inCellY);
766+
float thisAlteredHeight = thisAlteredHeightPtr != nullptr ? *thisAlteredHeightPtr : 0.f;
767+
float leftHeight = thisHeight;
768+
float leftAlteredHeight = thisAlteredHeight;
769+
float rightHeight = thisHeight;
770+
float rightAlteredHeight = thisAlteredHeight;
771+
float downHeight = thisHeight;
772+
float downAlteredHeight = thisAlteredHeight;
773+
float upHeight = thisHeight;
774+
float upAlteredHeight = thisAlteredHeight;
776775

777776
if (allowLandShapeEditing(cellId))
778777
{
779778
// Get key values for calculating average, handle cell edges, check for null pointers
780779
if (inCellX == 0)
781780
{
782781
cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX() - 1, cellCoords.getY());
783-
const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer
784-
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
785-
.value<CSMWorld::LandHeightsColumn::DataType>();
786-
leftHeight = landLeftShapePointer[inCellY * ESM::Land::LAND_SIZE + (ESM::Land::LAND_SIZE - 2)];
787-
if (paged->getCellAlteredHeight(cellCoords.move(-1, 0), inCellX, ESM::Land::LAND_SIZE - 2))
788-
leftAlteredHeight
789-
= *paged->getCellAlteredHeight(cellCoords.move(-1, 0), ESM::Land::LAND_SIZE - 2, inCellY);
782+
if (isLandLoaded(cellId))
783+
{
784+
const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer
785+
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
786+
.value<CSMWorld::LandHeightsColumn::DataType>();
787+
leftHeight = landLeftShapePointer[inCellY * ESM::Land::LAND_SIZE + (ESM::Land::LAND_SIZE - 2)];
788+
float* alteredHeightPtr
789+
= paged->getCellAlteredHeight(cellCoords.move(-1, 0), ESM::Land::LAND_SIZE - 2, inCellY);
790+
leftAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
791+
}
790792
}
791793
if (inCellY == 0)
792794
{
793795
cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() - 1);
794-
const CSMWorld::LandHeightsColumn::DataType landUpShapePointer
795-
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
796-
.value<CSMWorld::LandHeightsColumn::DataType>();
797-
upHeight = landUpShapePointer[(ESM::Land::LAND_SIZE - 2) * ESM::Land::LAND_SIZE + inCellX];
798-
if (paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2))
799-
upAlteredHeight
800-
= *paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2);
796+
if (isLandLoaded(cellId))
797+
{
798+
const CSMWorld::LandHeightsColumn::DataType landUpShapePointer
799+
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
800+
.value<CSMWorld::LandHeightsColumn::DataType>();
801+
upHeight = landUpShapePointer[(ESM::Land::LAND_SIZE - 2) * ESM::Land::LAND_SIZE + inCellX];
802+
float* alteredHeightPtr
803+
= paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2);
804+
upAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
805+
}
801806
}
802807
if (inCellX > 0)
803808
{
804809
leftHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX - 1];
805-
leftAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX - 1, inCellY);
810+
float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords, inCellX - 1, inCellY);
811+
leftAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
806812
}
807813
if (inCellY > 0)
808814
{
809815
upHeight = landShapePointer[(inCellY - 1) * ESM::Land::LAND_SIZE + inCellX];
810-
upAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY - 1);
816+
float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords, inCellX, inCellY - 1);
817+
upAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
811818
}
812819
if (inCellX == ESM::Land::LAND_SIZE - 1)
813820
{
814821
cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX() + 1, cellCoords.getY());
815-
const CSMWorld::LandHeightsColumn::DataType landRightShapePointer
816-
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
817-
.value<CSMWorld::LandHeightsColumn::DataType>();
818-
rightHeight = landRightShapePointer[inCellY * ESM::Land::LAND_SIZE + 1];
819-
if (paged->getCellAlteredHeight(cellCoords.move(1, 0), 1, inCellY))
822+
if (isLandLoaded(cellId))
820823
{
821-
rightAlteredHeight = *paged->getCellAlteredHeight(cellCoords.move(1, 0), 1, inCellY);
824+
const CSMWorld::LandHeightsColumn::DataType landRightShapePointer
825+
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
826+
.value<CSMWorld::LandHeightsColumn::DataType>();
827+
rightHeight = landRightShapePointer[inCellY * ESM::Land::LAND_SIZE + 1];
828+
float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords.move(1, 0), 1, inCellY);
829+
rightAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
822830
}
823831
}
824832
if (inCellY == ESM::Land::LAND_SIZE - 1)
825833
{
826834
cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() + 1);
827-
const CSMWorld::LandHeightsColumn::DataType landDownShapePointer
828-
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
829-
.value<CSMWorld::LandHeightsColumn::DataType>();
830-
downHeight = landDownShapePointer[1 * ESM::Land::LAND_SIZE + inCellX];
831-
if (paged->getCellAlteredHeight(cellCoords.move(0, 1), inCellX, 1))
835+
if (isLandLoaded(cellId))
832836
{
833-
downAlteredHeight = *paged->getCellAlteredHeight(cellCoords.move(0, 1), inCellX, 1);
837+
const CSMWorld::LandHeightsColumn::DataType landDownShapePointer
838+
= landTable.data(landTable.getModelIndex(cellId, landshapeColumn))
839+
.value<CSMWorld::LandHeightsColumn::DataType>();
840+
downHeight = landDownShapePointer[1 * ESM::Land::LAND_SIZE + inCellX];
841+
float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords.move(0, 1), inCellX, 1);
842+
downAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
834843
}
835844
}
836845
if (inCellX < ESM::Land::LAND_SIZE - 1)
837846
{
838847
rightHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX + 1];
839-
if (paged->getCellAlteredHeight(cellCoords, inCellX + 1, inCellY))
840-
rightAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX + 1, inCellY);
848+
float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords, inCellX + 1, inCellY);
849+
rightAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
841850
}
842851
if (inCellY < ESM::Land::LAND_SIZE - 1)
843852
{
844853
downHeight = landShapePointer[(inCellY + 1) * ESM::Land::LAND_SIZE + inCellX];
845-
if (paged->getCellAlteredHeight(cellCoords, inCellX, inCellY + 1))
846-
downAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY + 1);
854+
float* alteredHeightPtr = paged->getCellAlteredHeight(cellCoords, inCellX, inCellY + 1);
855+
downAlteredHeight = alteredHeightPtr != nullptr ? *alteredHeightPtr : 0.f;
847856
}
848857

849858
float averageHeight = (upHeight + downHeight + rightHeight + leftHeight + upAlteredHeight

0 commit comments

Comments
 (0)