Optimize land lookup on blendmaps sampling

Minimize number of getLand calls by grouping samples per cell.
macos_ci_fix
elsid 1 year ago
parent ce6ffba986
commit 07c1177b0d
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -430,8 +430,8 @@ namespace ESMTerrain
EXPECT_THAT(samples, EXPECT_THAT(samples,
ElementsAre( // ElementsAre( //
CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 7, .mSrcCol = 0, .mDstRow = 0, .mDstCol = 0 }, CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 7, .mSrcCol = 0, .mDstRow = 0, .mDstCol = 0 },
CellSample{ .mCellX = 0, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 1, .mDstCol = 0 },
CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 7, .mSrcCol = 1, .mDstRow = 0, .mDstCol = 1 }, CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 7, .mSrcCol = 1, .mDstRow = 0, .mDstCol = 1 },
CellSample{ .mCellX = 0, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 1, .mDstCol = 0 },
CellSample{ .mCellX = 0, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 1, .mDstCol = 1 })); CellSample{ .mCellX = 0, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 1, .mDstCol = 1 }));
} }
@ -468,23 +468,23 @@ namespace ESMTerrain
CellSample{ .mCellX = 0, .mCellY = -2, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 4, .mDstCol = 0 }, CellSample{ .mCellX = 0, .mCellY = -2, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 4, .mDstCol = 0 },
CellSample{ .mCellX = -2, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 0, .mDstCol = 1 }, CellSample{ .mCellX = -2, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 0, .mDstCol = 1 },
CellSample{ .mCellX = -2, .mCellY = -1, .mSrcRow = 1, .mSrcCol = 0, .mDstRow = 1, .mDstCol = 1 }, CellSample{ .mCellX = -2, .mCellY = -1, .mSrcRow = 1, .mSrcCol = 0, .mDstRow = 1, .mDstCol = 1 },
CellSample{ .mCellX = -1, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 2, .mDstCol = 1 },
CellSample{ .mCellX = -1, .mCellY = -1, .mSrcRow = 1, .mSrcCol = 0, .mDstRow = 3, .mDstCol = 1 },
CellSample{ .mCellX = 0, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 4, .mDstCol = 1 },
CellSample{ .mCellX = -2, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 0, .mDstCol = 2 }, CellSample{ .mCellX = -2, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 0, .mDstCol = 2 },
CellSample{ .mCellX = -2, .mCellY = -1, .mSrcRow = 1, .mSrcCol = 1, .mDstRow = 1, .mDstCol = 2 }, CellSample{ .mCellX = -2, .mCellY = -1, .mSrcRow = 1, .mSrcCol = 1, .mDstRow = 1, .mDstCol = 2 },
CellSample{ .mCellX = -1, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 2, .mDstCol = 1 },
CellSample{ .mCellX = -1, .mCellY = -1, .mSrcRow = 1, .mSrcCol = 0, .mDstRow = 3, .mDstCol = 1 },
CellSample{ .mCellX = -1, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 2, .mDstCol = 2 }, CellSample{ .mCellX = -1, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 2, .mDstCol = 2 },
CellSample{ .mCellX = -1, .mCellY = -1, .mSrcRow = 1, .mSrcCol = 1, .mDstRow = 3, .mDstCol = 2 }, CellSample{ .mCellX = -1, .mCellY = -1, .mSrcRow = 1, .mSrcCol = 1, .mDstRow = 3, .mDstCol = 2 },
CellSample{ .mCellX = 0, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 4, .mDstCol = 1 },
CellSample{ .mCellX = 0, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 4, .mDstCol = 2 }, CellSample{ .mCellX = 0, .mCellY = -1, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 4, .mDstCol = 2 },
CellSample{ .mCellX = -2, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 0, .mDstCol = 3 }, CellSample{ .mCellX = -2, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 0, .mDstCol = 3 },
CellSample{ .mCellX = -2, .mCellY = 0, .mSrcRow = 1, .mSrcCol = 0, .mDstRow = 1, .mDstCol = 3 }, CellSample{ .mCellX = -2, .mCellY = 0, .mSrcRow = 1, .mSrcCol = 0, .mDstRow = 1, .mDstCol = 3 },
CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 2, .mDstCol = 3 },
CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 1, .mSrcCol = 0, .mDstRow = 3, .mDstCol = 3 },
CellSample{ .mCellX = 0, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 4, .mDstCol = 3 },
CellSample{ .mCellX = -2, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 0, .mDstCol = 4 }, CellSample{ .mCellX = -2, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 0, .mDstCol = 4 },
CellSample{ .mCellX = -2, .mCellY = 0, .mSrcRow = 1, .mSrcCol = 1, .mDstRow = 1, .mDstCol = 4 }, CellSample{ .mCellX = -2, .mCellY = 0, .mSrcRow = 1, .mSrcCol = 1, .mDstRow = 1, .mDstCol = 4 },
CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 2, .mDstCol = 3 },
CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 1, .mSrcCol = 0, .mDstRow = 3, .mDstCol = 3 },
CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 2, .mDstCol = 4 }, CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 2, .mDstCol = 4 },
CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 1, .mSrcCol = 1, .mDstRow = 3, .mDstCol = 4 }, CellSample{ .mCellX = -1, .mCellY = 0, .mSrcRow = 1, .mSrcCol = 1, .mDstRow = 3, .mDstCol = 4 },
CellSample{ .mCellX = 0, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 0, .mDstRow = 4, .mDstCol = 3 },
CellSample{ .mCellX = 0, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 4, .mDstCol = 4 })); CellSample{ .mCellX = 0, .mCellY = 0, .mSrcRow = 0, .mSrcCol = 1, .mDstRow = 4, .mDstCol = 4 }));
} }
} }

@ -132,26 +132,16 @@ namespace ESMTerrain
return static_cast<int>(textureSize * size) + 1; return static_cast<int>(textureSize * size) + 1;
} }
inline void adjustTextureCoordinates(int textureSize, int& cellX, int& cellY, int& x, int& y) inline std::pair<std::size_t, std::size_t> getBlendmapLocalRange(
int cell, int minCell, int textureSize, int min, int max)
{ {
--x; const int cellMin = (cell - minCell) * textureSize;
if (x < 0) const int cellMax = cellMin + textureSize - 1;
{ const std::size_t begin = min > cellMin ? min - cellMin : 0;
--cellX; const std::size_t end = cellMax < max ? textureSize : max - cellMin + 1;
x += textureSize; assert(begin < end);
} assert(static_cast<int>(end) <= textureSize);
return { begin, end };
while (x >= textureSize)
{
++cellX;
x -= textureSize;
}
while (y >= textureSize)
{
++cellY;
y -= textureSize;
}
} }
template <class F> template <class F>
@ -163,32 +153,52 @@ namespace ESMTerrain
if (textureSize <= 0) if (textureSize <= 0)
throw std::invalid_argument("Invalid texture size for blendmap sampling: " + std::to_string(textureSize)); throw std::invalid_argument("Invalid texture size for blendmap sampling: " + std::to_string(textureSize));
const int beginCellX = static_cast<int>(std::floor(minX)); int minCellX = static_cast<int>(std::floor(minX));
const int beginCellY = static_cast<int>(std::floor(minY)); const int minCellY = static_cast<int>(std::floor(minY));
const int beginRow = static_cast<int>((minX - beginCellX) * (textureSize + 1)); int minRow = static_cast<int>((minX - minCellX) * (textureSize + 1)) - 1;
const int beginCol = static_cast<int>((minY - beginCellY) * (textureSize + 1)); const int minCol = static_cast<int>((minY - minCellY) * (textureSize + 1));
const int blendmapSize = getBlendmapSize(size, textureSize);
for (int y = 0; y < blendmapSize; y++) if (minRow < 0)
{ {
for (int x = 0; x < blendmapSize; x++) --minCellX;
minRow += textureSize;
}
const int maxRow = minRow + static_cast<int>(textureSize * size);
const int maxCol = minCol + static_cast<int>(textureSize * size);
const int maxCellX = minCellX + maxRow / textureSize;
const int maxCellY = minCellY + maxCol / textureSize;
std::size_t baseDstCol = 0;
for (int cellY = minCellY; cellY <= maxCellY; ++cellY)
{ {
int cellX = beginCellX; std::size_t baseDstRow = 0;
int cellY = beginCellY;
int srcX = x + beginRow;
int srcY = y + beginCol;
adjustTextureCoordinates(textureSize, cellX, cellY, srcX, srcY); const auto [localBeginCol, localEndCol]
= getBlendmapLocalRange(cellY, minCellY, textureSize, minCol, maxCol);
const std::size_t colCount = localEndCol - localBeginCol;
for (int cellX = minCellX; cellX <= maxCellX; ++cellX)
{
const auto [localBeginRow, localEndRow]
= getBlendmapLocalRange(cellX, minCellX, textureSize, minRow, maxRow);
const std::size_t rowCount = localEndRow - localBeginRow;
for (std::size_t col = 0; col < colCount; ++col)
for (std::size_t row = 0; row < rowCount; ++row)
f(CellSample{ f(CellSample{
.mCellX = cellX, .mCellX = cellX,
.mCellY = cellY, .mCellY = cellY,
.mSrcRow = static_cast<std::size_t>(srcX), .mSrcRow = localBeginRow + row,
.mSrcCol = static_cast<std::size_t>(srcY), .mSrcCol = localBeginCol + col,
.mDstRow = static_cast<std::size_t>(x), .mDstRow = baseDstRow + row,
.mDstCol = static_cast<std::size_t>(y), .mDstCol = baseDstCol + col,
}); });
baseDstRow += rowCount;
} }
baseDstCol += colCount;
} }
} }
} }

Loading…
Cancel
Save