1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-03 15:09:39 +00:00

Fix tile bounds scaling

OscillatingRecastMeshObject::update should be called with tile bounds in real
coordinates not in navmesh. But proper scaling was done only in
RecastMeshManager::getMesh and RecastMeshManager::updateObject used tile bounds
in navmesh coordinates.

Add a new function to create tile bounds with proper scaling and pass correct
value into RecastMeshManager constructor through CachedRecastMeshManager
constuctor from TileCachedRecastMeshManager member functions.
This commit is contained in:
elsid 2021-11-05 20:47:11 +01:00
parent b6d2c57de2
commit 5db4898bec
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
7 changed files with 31 additions and 38 deletions

View file

@ -3,9 +3,8 @@
namespace DetourNavigator namespace DetourNavigator
{ {
CachedRecastMeshManager::CachedRecastMeshManager(const Settings& settings, const TileBounds& bounds, CachedRecastMeshManager::CachedRecastMeshManager(const TileBounds& bounds, std::size_t generation)
std::size_t generation) : mImpl(bounds, generation)
: mImpl(settings, bounds, generation)
{} {}
bool CachedRecastMeshManager::addObject(const ObjectId id, const CollisionShape& shape, bool CachedRecastMeshManager::addObject(const ObjectId id, const CollisionShape& shape,

View file

@ -14,7 +14,7 @@ namespace DetourNavigator
class CachedRecastMeshManager class CachedRecastMeshManager
{ {
public: public:
CachedRecastMeshManager(const Settings& settings, const TileBounds& bounds, std::size_t generation); explicit CachedRecastMeshManager(const TileBounds& bounds, std::size_t generation);
bool addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform, bool addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
const AreaType areaType); const AreaType areaType);

View file

@ -28,9 +28,8 @@ namespace
namespace DetourNavigator namespace DetourNavigator
{ {
RecastMeshManager::RecastMeshManager(const Settings& settings, const TileBounds& bounds, std::size_t generation) RecastMeshManager::RecastMeshManager(const TileBounds& bounds, std::size_t generation)
: mSettings(settings) : mGeneration(generation)
, mGeneration(generation)
, mTileBounds(bounds) , mTileBounds(bounds)
{ {
} }
@ -119,10 +118,7 @@ namespace DetourNavigator
std::shared_ptr<RecastMesh> RecastMeshManager::getMesh() const std::shared_ptr<RecastMesh> RecastMeshManager::getMesh() const
{ {
TileBounds tileBounds = mTileBounds; RecastMeshBuilder builder(mTileBounds);
tileBounds.mMin /= mSettings.mRecastScaleFactor;
tileBounds.mMax /= mSettings.mRecastScaleFactor;
RecastMeshBuilder builder(tileBounds);
using Object = std::tuple< using Object = std::tuple<
osg::ref_ptr<const osg::Referenced>, osg::ref_ptr<const osg::Referenced>,
std::reference_wrapper<const btCollisionShape>, std::reference_wrapper<const btCollisionShape>,

View file

@ -34,7 +34,7 @@ namespace DetourNavigator
class RecastMeshManager class RecastMeshManager
{ {
public: public:
RecastMeshManager(const Settings& settings, const TileBounds& bounds, std::size_t generation); explicit RecastMeshManager(const TileBounds& bounds, std::size_t generation);
bool addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform, bool addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
const AreaType areaType); const AreaType areaType);
@ -73,7 +73,6 @@ namespace DetourNavigator
HeightfieldShape mShape; HeightfieldShape mShape;
}; };
const Settings& mSettings;
const std::size_t mGeneration; const std::size_t mGeneration;
const TileBounds mTileBounds; const TileBounds mTileBounds;
mutable std::mutex mMutex; mutable std::mutex mMutex;

View file

@ -96,6 +96,17 @@ namespace DetourNavigator
{ {
return std::floor(std::sqrt(settings.mMaxTilesNumber / osg::PI)) - 1; return std::floor(std::sqrt(settings.mMaxTilesNumber / osg::PI)) - 1;
} }
inline TileBounds makeRealTileBoundsWithBorder(const Settings& settings, const TilePosition& tilePosition)
{
TileBounds result = makeTileBounds(settings, tilePosition);
const float border = getBorderSize(settings);
result.mMin -= osg::Vec2f(border, border);
result.mMax += osg::Vec2f(border, border);
result.mMin /= settings.mRecastScaleFactor;
result.mMax /= settings.mRecastScaleFactor;
return result;
}
} }
#endif #endif

View file

@ -18,12 +18,11 @@ namespace DetourNavigator
const btTransform& transform, const AreaType areaType) const btTransform& transform, const AreaType areaType)
{ {
std::vector<TilePosition> tilesPositions; std::vector<TilePosition> tilesPositions;
const auto border = getBorderSize(mSettings);
{ {
auto tiles = mTiles.lock(); auto tiles = mTiles.lock();
getTilesPositions(shape.getShape(), transform, mSettings, [&] (const TilePosition& tilePosition) getTilesPositions(shape.getShape(), transform, mSettings, [&] (const TilePosition& tilePosition)
{ {
if (addTile(id, shape, transform, areaType, tilePosition, border, tiles.get())) if (addTile(id, shape, transform, areaType, tilePosition, tiles.get()))
tilesPositions.push_back(tilePosition); tilesPositions.push_back(tilePosition);
}); });
} }
@ -58,8 +57,6 @@ namespace DetourNavigator
bool TileCachedRecastMeshManager::addWater(const osg::Vec2i& cellPosition, const int cellSize, bool TileCachedRecastMeshManager::addWater(const osg::Vec2i& cellPosition, const int cellSize,
const osg::Vec3f& shift) const osg::Vec3f& shift)
{ {
const auto border = getBorderSize(mSettings);
auto& tilesPositions = mWaterTilesPositions[cellPosition]; auto& tilesPositions = mWaterTilesPositions[cellPosition];
bool result = false; bool result = false;
@ -84,11 +81,9 @@ namespace DetourNavigator
auto tile = tiles->find(tilePosition); auto tile = tiles->find(tilePosition);
if (tile == tiles->end()) if (tile == tiles->end())
{ {
auto tileBounds = makeTileBounds(mSettings, tilePosition); const TileBounds tileBounds = makeRealTileBoundsWithBorder(mSettings, tilePosition);
tileBounds.mMin -= osg::Vec2f(border, border); tile = tiles->emplace(tilePosition,
tileBounds.mMax += osg::Vec2f(border, border); std::make_shared<CachedRecastMeshManager>(tileBounds, mTilesGeneration)).first;
tile = tiles->insert(std::make_pair(tilePosition,
std::make_shared<CachedRecastMeshManager>(mSettings, tileBounds, mTilesGeneration))).first;
} }
if (tile->second->addWater(cellPosition, cellSize, shift)) if (tile->second->addWater(cellPosition, cellSize, shift))
{ {
@ -133,8 +128,6 @@ namespace DetourNavigator
bool TileCachedRecastMeshManager::addHeightfield(const osg::Vec2i& cellPosition, int cellSize, bool TileCachedRecastMeshManager::addHeightfield(const osg::Vec2i& cellPosition, int cellSize,
const osg::Vec3f& shift, const HeightfieldShape& shape) const osg::Vec3f& shift, const HeightfieldShape& shape)
{ {
const auto border = getBorderSize(mSettings);
auto& tilesPositions = mHeightfieldTilesPositions[cellPosition]; auto& tilesPositions = mHeightfieldTilesPositions[cellPosition];
bool result = false; bool result = false;
@ -145,11 +138,9 @@ namespace DetourNavigator
auto tile = tiles->find(tilePosition); auto tile = tiles->find(tilePosition);
if (tile == tiles->end()) if (tile == tiles->end())
{ {
auto tileBounds = makeTileBounds(mSettings, tilePosition); const TileBounds tileBounds = makeRealTileBoundsWithBorder(mSettings, tilePosition);
tileBounds.mMin -= osg::Vec2f(border, border); tile = tiles->emplace(tilePosition,
tileBounds.mMax += osg::Vec2f(border, border); std::make_shared<CachedRecastMeshManager>(tileBounds, mTilesGeneration)).first;
tile = tiles->insert(std::make_pair(tilePosition,
std::make_shared<CachedRecastMeshManager>(mSettings, tileBounds, mTilesGeneration))).first;
} }
if (tile->second->addHeightfield(cellPosition, cellSize, shift, shape)) if (tile->second->addHeightfield(cellPosition, cellSize, shift, shape))
{ {
@ -219,17 +210,15 @@ namespace DetourNavigator
} }
bool TileCachedRecastMeshManager::addTile(const ObjectId id, const CollisionShape& shape, bool TileCachedRecastMeshManager::addTile(const ObjectId id, const CollisionShape& shape,
const btTransform& transform, const AreaType areaType, const TilePosition& tilePosition, float border, const btTransform& transform, const AreaType areaType, const TilePosition& tilePosition,
TilesMap& tiles) TilesMap& tiles)
{ {
auto tile = tiles.find(tilePosition); auto tile = tiles.find(tilePosition);
if (tile == tiles.end()) if (tile == tiles.end())
{ {
auto tileBounds = makeTileBounds(mSettings, tilePosition); const TileBounds tileBounds = makeRealTileBoundsWithBorder(mSettings, tilePosition);
tileBounds.mMin -= osg::Vec2f(border, border); tile = tiles.emplace(tilePosition,
tileBounds.mMax += osg::Vec2f(border, border); std::make_shared<CachedRecastMeshManager>(tileBounds, mTilesGeneration)).first;
tile = tiles.insert(std::make_pair(
tilePosition, std::make_shared<CachedRecastMeshManager>(mSettings, tileBounds, mTilesGeneration))).first;
} }
return tile->second->addObject(id, shape, transform, areaType); return tile->second->addObject(id, shape, transform, areaType);
} }

View file

@ -33,7 +33,6 @@ namespace DetourNavigator
if (object == mObjectsTilesPositions.end()) if (object == mObjectsTilesPositions.end())
return false; return false;
auto& currentTiles = object->second; auto& currentTiles = object->second;
const auto border = getBorderSize(mSettings);
bool changed = false; bool changed = false;
std::vector<TilePosition> newTiles; std::vector<TilePosition> newTiles;
{ {
@ -49,7 +48,7 @@ namespace DetourNavigator
changed = true; changed = true;
} }
} }
else if (addTile(id, shape, transform, areaType, tilePosition, border, tiles.get())) else if (addTile(id, shape, transform, areaType, tilePosition, tiles.get()))
{ {
newTiles.push_back(tilePosition); newTiles.push_back(tilePosition);
onChangedTile(tilePosition); onChangedTile(tilePosition);
@ -113,7 +112,7 @@ namespace DetourNavigator
std::size_t mTilesGeneration = 0; std::size_t mTilesGeneration = 0;
bool addTile(const ObjectId id, const CollisionShape& shape, const btTransform& transform, bool addTile(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
const AreaType areaType, const TilePosition& tilePosition, float border, TilesMap& tiles); const AreaType areaType, const TilePosition& tilePosition, TilesMap& tiles);
bool updateTile(const ObjectId id, const btTransform& transform, const AreaType areaType, bool updateTile(const ObjectId id, const btTransform& transform, const AreaType areaType,
const TilePosition& tilePosition, TilesMap& tiles); const TilePosition& tilePosition, TilesMap& tiles);