CS: Make painting terrain height over a cell border equalize the height

at both edge
This commit is contained in:
Marius DAVID 2025-08-27 18:08:54 +02:00
parent 77b08943a7
commit 0f500df183
7 changed files with 148 additions and 96 deletions

View File

@ -371,6 +371,11 @@ float CSVRender::Cell::getSumOfAlteredAndTrueHeight(int cellX, int cellY, int in
return mTerrainStorage->getSumOfAlteredAndTrueHeight(cellX, cellY, inCellX, inCellY);
}
std::optional<float> CSVRender::Cell::getOriginalHeight(int cellX, int cellY, int inCellX, int inCellY)
{
return mTerrainStorage->getOriginalHeight(cellX, cellY, inCellX, inCellY);
}
float* CSVRender::Cell::getAlteredHeight(int inCellX, int inCellY)
{
return mTerrainStorage->getAlteredHeight(inCellX, inCellY);

View File

@ -125,6 +125,8 @@ namespace CSVRender
float getSumOfAlteredAndTrueHeight(int cellX, int cellY, int inCellX, int inCellY);
std::optional<float> getOriginalHeight(int cellX, int cellY, int inCellX, int inCellY);
float* getAlteredHeight(int inCellX, int inCellY);
void resetAlteredHeights();

View File

@ -824,6 +824,30 @@ CSVRender::Cell* CSVRender::PagedWorldspaceWidget::getCell(const CSMWorld::CellC
return nullptr;
}
void CSVRender::PagedWorldspaceWidget::setCellAlteredAbsoluteHeight(
const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY, float absoluteHeight)
{
std::map<CSMWorld::CellCoordinates, Cell*>::iterator searchResult = mCells.find(coords);
if (searchResult != mCells.end())
{
std::optional<float> baseHeight
= searchResult->second->getOriginalHeight(coords.getX(), coords.getY(), inCellX, inCellY);
if (baseHeight)
searchResult->second->setAlteredHeight(inCellX, inCellY, absoluteHeight - *baseHeight);
}
}
std::optional<float> CSVRender::PagedWorldspaceWidget::getCellOriginalHeight(
const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY)
{
std::map<CSMWorld::CellCoordinates, Cell*>::iterator searchResult = mCells.find(coords);
if (searchResult != mCells.end())
{
return searchResult->second->getOriginalHeight(coords.getX(), coords.getY(), inCellX, inCellY);
}
return {};
}
void CSVRender::PagedWorldspaceWidget::setCellAlteredHeight(
const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY, float height)
{

View File

@ -153,6 +153,11 @@ namespace CSVRender
Cell* getCell(const CSMWorld::CellCoordinates& coords) const override;
void setCellAlteredAbsoluteHeight(
const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY, float absoluteHeight);
std::optional<float> getCellOriginalHeight(const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY);
void setCellAlteredHeight(const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY, float height);
float* getCellAlteredHeight(const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY);

View File

@ -609,9 +609,12 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c
if ((inCellX != 0 && inCellY != 0 && inCellX != ESM::Land::LAND_SIZE - 1 && inCellY != ESM::Land::LAND_SIZE - 1)
|| !useAndAlterAdjacentCell)
paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight);
if (useAndAlterAdjacentCell)
else
{
std::optional<float> originalHeight = paged->getCellOriginalHeight(cellCoords, inCellX, inCellY);
if (originalHeight)
{
float absoluteHeight = *originalHeight + alteredHeight;
// Change values of cornering cells
if ((inCellX == 0 && inCellY == 0) && (useTool || isLandLoaded(cellUpLeftId)))
{
@ -620,10 +623,11 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c
{
CSMWorld::CellCoordinates cornerCellCoords = cellCoords.move(-1, -1);
if (useTool
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end())
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords)
== mAlteredCells.end())
mAlteredCells.emplace_back(cornerCellCoords);
paged->setCellAlteredHeight(
cornerCellCoords, ESM::Land::LAND_SIZE - 1, ESM::Land::LAND_SIZE - 1, alteredHeight);
paged->setCellAlteredAbsoluteHeight(
cornerCellCoords, ESM::Land::LAND_SIZE - 1, ESM::Land::LAND_SIZE - 1, absoluteHeight);
}
else
return;
@ -635,9 +639,10 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c
{
CSMWorld::CellCoordinates cornerCellCoords = cellCoords.move(-1, 1);
if (useTool
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end())
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords)
== mAlteredCells.end())
mAlteredCells.emplace_back(cornerCellCoords);
paged->setCellAlteredHeight(cornerCellCoords, ESM::Land::LAND_SIZE - 1, 0, alteredHeight);
paged->setCellAlteredAbsoluteHeight(cornerCellCoords, ESM::Land::LAND_SIZE - 1, 0, absoluteHeight);
}
else
return;
@ -649,9 +654,10 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c
{
CSMWorld::CellCoordinates cornerCellCoords = cellCoords.move(1, -1);
if (useTool
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end())
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords)
== mAlteredCells.end())
mAlteredCells.emplace_back(cornerCellCoords);
paged->setCellAlteredHeight(cornerCellCoords, 0, ESM::Land::LAND_SIZE - 1, alteredHeight);
paged->setCellAlteredAbsoluteHeight(cornerCellCoords, 0, ESM::Land::LAND_SIZE - 1, absoluteHeight);
}
else
return;
@ -664,9 +670,10 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c
{
CSMWorld::CellCoordinates cornerCellCoords = cellCoords.move(1, 1);
if (useTool
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end())
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords)
== mAlteredCells.end())
mAlteredCells.emplace_back(cornerCellCoords);
paged->setCellAlteredHeight(cornerCellCoords, 0, 0, alteredHeight);
paged->setCellAlteredAbsoluteHeight(cornerCellCoords, 0, 0, absoluteHeight);
}
else
return;
@ -682,7 +689,8 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), edgeCellCoords) == mAlteredCells.end())
mAlteredCells.emplace_back(edgeCellCoords);
paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight);
paged->setCellAlteredHeight(edgeCellCoords, ESM::Land::LAND_SIZE - 1, inCellY, alteredHeight);
paged->setCellAlteredAbsoluteHeight(
edgeCellCoords, ESM::Land::LAND_SIZE - 1, inCellY, absoluteHeight);
}
}
if ((inCellY == 0) && (useTool || isLandLoaded(cellUpId)))
@ -694,7 +702,8 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), edgeCellCoords) == mAlteredCells.end())
mAlteredCells.emplace_back(edgeCellCoords);
paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight);
paged->setCellAlteredHeight(edgeCellCoords, inCellX, ESM::Land::LAND_SIZE - 1, alteredHeight);
paged->setCellAlteredAbsoluteHeight(
edgeCellCoords, inCellX, ESM::Land::LAND_SIZE - 1, absoluteHeight);
}
}
@ -707,7 +716,7 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), edgeCellCoords) == mAlteredCells.end())
mAlteredCells.emplace_back(edgeCellCoords);
paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight);
paged->setCellAlteredHeight(edgeCellCoords, 0, inCellY, alteredHeight);
paged->setCellAlteredAbsoluteHeight(edgeCellCoords, 0, inCellY, absoluteHeight);
}
}
if ((inCellY == ESM::Land::LAND_SIZE - 1) && (useTool || isLandLoaded(cellDownId)))
@ -719,7 +728,8 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c
&& std::find(mAlteredCells.begin(), mAlteredCells.end(), edgeCellCoords) == mAlteredCells.end())
mAlteredCells.emplace_back(edgeCellCoords);
paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight);
paged->setCellAlteredHeight(edgeCellCoords, inCellX, 0, alteredHeight);
paged->setCellAlteredAbsoluteHeight(edgeCellCoords, inCellX, 0, absoluteHeight);
}
}
}
}

View File

@ -59,16 +59,21 @@ namespace CSVRender
float TerrainStorage::getSumOfAlteredAndTrueHeight(int cellX, int cellY, int inCellX, int inCellY)
{
float height = 0.f;
std::optional<float> true_height = getOriginalHeight(cellX, cellY, inCellX, inCellY);
if (true_height)
return *true_height + *getAlteredHeight(inCellX, inCellY);
return 0.0f;
}
std::optional<float> TerrainStorage::getOriginalHeight(int cellX, int cellY, int inCellX, int inCellY)
{
const int index
= mData.getLand().searchId(ESM::RefId::stringRefId(CSMWorld::Land::createUniqueRecordId(cellX, cellY)));
if (index == -1) // no land!
return height;
return {};
const ESM::Land::LandData* landData = mData.getLand().getRecord(index).get().getLandData(ESM::Land::DATA_VHGT);
height = landData->mHeights[inCellY * ESM::Land::LAND_SIZE + inCellX];
return mAlteredHeight[inCellY * ESM::Land::LAND_SIZE + inCellX] + height;
return landData->mHeights[inCellY * ESM::Land::LAND_SIZE + inCellX];
}
float* TerrainStorage::getAlteredHeight(int inCellX, int inCellY)

View File

@ -31,6 +31,7 @@ namespace CSVRender
bool useAlteration() const override { return true; }
float getSumOfAlteredAndTrueHeight(int cellX, int cellY, int inCellX, int inCellY);
std::optional<float> getOriginalHeight(int cellX, int cellY, int inCellX, int inCellY);
float* getAlteredHeight(int inCellX, int inCellY);
private: