From c711179b8f8e5f045d6a0018e07ceb6879e3f055 Mon Sep 17 00:00:00 2001 From: Calandiel Date: Tue, 20 Aug 2024 22:52:55 +0200 Subject: [PATCH] apply changes requested in the code review --- apps/openmw/mwlua/landbindings.cpp | 18 +++++++++--------- components/esmterrain/storage.cpp | 5 +++-- components/esmterrain/storage.hpp | 2 +- files/lua_api/openmw/core.lua | 4 ++-- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwlua/landbindings.cpp b/apps/openmw/mwlua/landbindings.cpp index 37e95183ca..3f5c0f2e40 100644 --- a/apps/openmw/mwlua/landbindings.cpp +++ b/apps/openmw/mwlua/landbindings.cpp @@ -17,13 +17,6 @@ namespace MWLua sol::state_view& lua = context.mLua->sol(); sol::table landApi(lua, sol::create); - // Constants - landApi["RANGE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - { "Self", ESM::RT_Self }, - { "Touch", ESM::RT_Touch }, - { "Target", ESM::RT_Target }, - })); - landApi["getHeightAt"] = [](const osg::Vec3f& pos, sol::object cellOrName) { ESM::RefId worldspace; if (cellOrName.is()) @@ -63,7 +56,7 @@ namespace MWLua return ESMTerrain::Storage::getHeightAt(landData->mHeights, landData->sLandSize, pos, cellSize); }; - landApi["getLandTextureAt"] = [lua = context.mLua](const osg::Vec3f& pos, sol::object cellOrName) { + landApi["getTextureAt"] = [lua = context.mLua](const osg::Vec3f& pos, sol::object cellOrName) { sol::variadic_results values; ESM::RefId worldspace; if (cellOrName.is()) @@ -85,6 +78,11 @@ namespace MWLua auto store = MWBase::Environment::get().getESMStore(); // We need to read land twice. Once to get the amount of texture samples per cell edge, and the second time // to get the actual data + // This is because the visual land textures are offset with regards to quads that are rendered for terrain. + // To properly calculate that offset, we need to know how many texture samples exist per cell edge, + // as it differs between tes3 and tes4. It's equal - + // Once we know the value, we will calculate the offset and retrieve a sample again, this time + // with the offset taken into account. auto landStore = store->get(); auto land = landStore.search(cellX, cellY); const ESM::Land::LandData* landData = nullptr; @@ -105,6 +103,8 @@ namespace MWLua return values; } + // Use landData to get amount of sampler per cell edge (sLandTextureSize) + // and then get the corrected position that will map to the rendered texture const osg::Vec3f correctedPos = ESMTerrain::Storage::getTextureCorrectedWorldPos(pos, landData->sLandTextureSize, cellSize); int correctedCellX = static_cast(std::floor(correctedPos.x() / cellSize)); @@ -128,7 +128,7 @@ namespace MWLua // We're passing in sLandTextureSize, NOT sLandSize like with getHeightAt const ESMTerrain::UniqueTextureId textureId - = ESMTerrain::Storage::getLandTextureAt(correctedLandData->mTextures, correctedLand->getPlugin(), + = ESMTerrain::Storage::getTextureAt(correctedLandData->mTextures, correctedLand->getPlugin(), correctedLandData->sLandTextureSize, correctedPos, cellSize); // Need to check for 0, 0 so that we can safely subtract 1 later, as per documentation on UniqueTextureId diff --git a/components/esmterrain/storage.cpp b/components/esmterrain/storage.cpp index 903ec11c29..aa9ef3e362 100644 --- a/components/esmterrain/storage.cpp +++ b/components/esmterrain/storage.cpp @@ -2,11 +2,11 @@ #include #include -#include #include #include #include +#include #include #include @@ -475,6 +475,7 @@ namespace ESMTerrain blendmaps.clear(); // If a single texture fills the whole terrain, there is no need to blend } + // Returns a position that can be used to look up a land texture, while taking their offset into account osg::Vec3f Storage::getTextureCorrectedWorldPos( const osg::Vec3f& uncorrectedWorldPos, const int textureSize, const float cellSize) { @@ -485,7 +486,7 @@ namespace ESMTerrain } // Takes in a corrected world pos to match the visuals. - UniqueTextureId Storage::getLandTextureAt(const std::span landData, const int plugin, + UniqueTextureId Storage::getTextureAt(const std::span landData, const int plugin, const int textureSize, const osg::Vec3f& correctedWorldPos, const float cellSize) { int cellX = static_cast(std::floor(correctedWorldPos.x() / cellSize)); diff --git a/components/esmterrain/storage.hpp b/components/esmterrain/storage.hpp index 7b4e9f8694..6ca33b18bf 100644 --- a/components/esmterrain/storage.hpp +++ b/components/esmterrain/storage.hpp @@ -120,7 +120,7 @@ namespace ESMTerrain static osg::Vec3f getTextureCorrectedWorldPos( const osg::Vec3f& uncorrectedWorldPos, const int textureSize, const float cellSize); - static UniqueTextureId getLandTextureAt(const std::span landData, const int plugin, + static UniqueTextureId getTextureAt(const std::span landData, const int plugin, const int textureSize, const osg::Vec3f& worldPos, const float cellSize); /// Get the transformation factor for mapping cell units to world units. diff --git a/files/lua_api/openmw/core.lua b/files/lua_api/openmw/core.lua index 30db9b6791..0636682669 100644 --- a/files/lua_api/openmw/core.lua +++ b/files/lua_api/openmw/core.lua @@ -467,10 +467,10 @@ --- -- Get the terrain texture at a given location. --- @function [parent=#Land] getLandTextureAt +-- @function [parent=#Land] getTextureAt -- @param openmw.util#Vector3 position -- @param #any cellOrName (optional) cell or cell name in their exterior world space to query --- @return #nil, #number Land texture index or nil if failed to retrieve the texture +-- @return #nil, #number Land texture index or nil if failed to retrieve the texture. Landscape textures created through editors such as openmw-cs can be assigned an id to differentiate them, that is also used for terrain rendering. The value returned here corresponds to that value. See also LTEX records (https://en.uesp.net/wiki/Morrowind_Mod:Mod_File_Format/LTEX) -- @return #nil, #number Plugin id or nil if failed to retrieve the texture -- @return #nil, #string Texture path or nil if one isn't defined