From 53c3f95ac8fdbcbf6a36a589c2bd5ccd11b3efa1 Mon Sep 17 00:00:00 2001 From: elsid Date: Mon, 7 Aug 2023 11:14:27 +0200 Subject: [PATCH] Avoid redundant copy for LandData underlying data --- components/esm/esmterrain.cpp | 69 +++++++++++++++++------------------ components/esm/esmterrain.hpp | 15 +++++--- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/components/esm/esmterrain.cpp b/components/esm/esmterrain.cpp index 18a267d51c..27f21b6a32 100644 --- a/components/esm/esmterrain.cpp +++ b/components/esm/esmterrain.cpp @@ -2,67 +2,64 @@ #include "esmterrain.hpp" +namespace +{ + constexpr std::uint16_t textures[ESM::Land::LAND_NUM_TEXTURES]{ 0 }; + + std::unique_ptr loadData(const ESM::Land& land, int loadFlags) + { + std::unique_ptr result = std::make_unique(); + land.loadData(loadFlags, *result); + return result; + } +} + ESM::LandData::LandData(const ESM::Land& land, int loadFlags) - : mLoadFlags(loadFlags) + : mData(loadData(land, loadFlags)) + , mLoadFlags(mData->mDataLoaded) + , mMinHeight(mData->mMinHeight) + , mMaxHeight(mData->mMaxHeight) , mSize(Constants::CellSizeInUnits) , mLandSize(ESM::Land::LAND_SIZE) , mPlugin(land.getPlugin()) + , mHeights(mData->mHeights) + , mNormals(mData->mNormals) + , mColors(mData->mColours) + , mTextures(mData->mTextures) { - ESM::Land::LandData data; - land.loadData(loadFlags, data); - mLoadFlags = data.mDataLoaded; - std::span heights(data.mHeights); - mHeights = std::vector(heights.begin(), heights.end()); - - std::span normals(data.mNormals); - mNormals = std::vector(normals.begin(), normals.end()); - - std::span colors(data.mColours); - mColors = std::vector(colors.begin(), colors.end()); - - std::span textures(data.mTextures); - mTextures = std::vector(textures.begin(), textures.end()); - - mMinHeight = data.mMinHeight; - mMaxHeight = data.mMaxHeight; } ESM::LandData::LandData(const ESM4::Land& land, int /*loadFlags*/) : mLoadFlags(land.mDataTypes) // ESM4::Land is always fully loaded. TODO: implement lazy loading + , mHeightsData(ESM4::Land::sLandNumVerts) + , mMinHeight(std::numeric_limits::max()) + , mMaxHeight(std::numeric_limits::lowest()) , mSize(Constants::ESM4CellSizeInUnits) , mLandSize(ESM4::Land::sVertsPerSide) + , mNormals(land.mVertNorm) + , mColors(land.mVertColr) + , mTextures(textures) { - - mMinHeight = std::numeric_limits::max(); - mMaxHeight = std::numeric_limits::lowest(); - mHeights.resize(ESM4::Land::sLandNumVerts); - mTextures.resize(ESM::Land::LAND_NUM_TEXTURES); - std::fill(mTextures.begin(), mTextures.end(), 0); - - float row_offset = land.mHeightMap.heightOffset; + float rowOffset = land.mHeightMap.heightOffset; for (int y = 0; y < mLandSize; y++) { - row_offset += land.mHeightMap.gradientData[y * mLandSize]; + rowOffset += land.mHeightMap.gradientData[y * mLandSize]; - const float heightY = row_offset * ESM4::Land::sHeightScale; - mHeights[y * mLandSize] = heightY; + const float heightY = rowOffset * ESM4::Land::sHeightScale; + mHeightsData[y * mLandSize] = heightY; mMinHeight = std::min(mMinHeight, heightY); mMaxHeight = std::max(mMaxHeight, heightY); - float colOffset = row_offset; + float colOffset = rowOffset; for (int x = 1; x < mLandSize; x++) { colOffset += land.mHeightMap.gradientData[y * mLandSize + x]; const float heightX = colOffset * ESM4::Land::sHeightScale; mMinHeight = std::min(mMinHeight, heightX); mMaxHeight = std::max(mMaxHeight, heightX); - mHeights[x + y * mLandSize] = heightX; + mHeightsData[x + y * mLandSize] = heightX; } } - std::span normals(land.mVertNorm); - mNormals = std::vector(normals.begin(), normals.end()); - - std::span colors(land.mVertColr); - mColors = std::vector(colors.begin(), colors.end()); + mHeights = mHeightsData; } diff --git a/components/esm/esmterrain.hpp b/components/esm/esmterrain.hpp index 0f2a5eb1cb..8aaf4d078c 100644 --- a/components/esm/esmterrain.hpp +++ b/components/esm/esmterrain.hpp @@ -2,6 +2,7 @@ #define COMPONENTS_ESM_ESMTERRAIN #include +#include #include #include @@ -15,8 +16,8 @@ namespace ESM public: ~LandData() = default; LandData() = default; - LandData(const ESM::Land& Land, int loadFLags); - LandData(const ESM4::Land& Land, int loadFLags); + LandData(const ESM::Land& Land, int loadFlags); + LandData(const ESM4::Land& Land, int loadFlags); std::span getHeights() const { return mHeights; } std::span getNormals() const { return mNormals; } @@ -30,16 +31,18 @@ namespace ESM int getPlugin() const { return mPlugin; } private: + std::unique_ptr mData; int mLoadFlags = 0; + std::vector mHeightsData; float mMinHeight = 0.f; float mMaxHeight = 0.f; float mSize = 0.f; int mLandSize = 0; int mPlugin = 0; - std::vector mHeights; - std::vector mNormals; - std::vector mColors; - std::vector mTextures; + std::span mHeights; + std::span mNormals; + std::span mColors; + std::span mTextures; }; }