1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-29 22:20:33 +00:00

Split tiles position range creation and iteration over

This commit is contained in:
elsid 2021-12-18 00:37:32 +01:00
parent d1d29a2452
commit bba7beb0c5
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40
9 changed files with 114 additions and 69 deletions

View File

@ -188,8 +188,13 @@ namespace NavMeshTool
std::vector<TilePosition> worldspaceTiles;
DetourNavigator::getTilesPositions(
Misc::Convert::toOsg(input->mAabb.m_min), Misc::Convert::toOsg(input->mAabb.m_max), settings.mRecast,
[&] (const TilePosition& tilePosition) { worldspaceTiles.push_back(tilePosition); });
DetourNavigator::makeTilesPositionsRange(
Misc::Convert::toOsg(input->mAabb.m_min),
Misc::Convert::toOsg(input->mAabb.m_max),
settings.mRecast
),
[&] (const TilePosition& tilePosition) { worldspaceTiles.push_back(tilePosition); }
);
tiles += worldspaceTiles.size();

View File

@ -1,5 +1,6 @@
#include <components/detournavigator/gettilespositions.hpp>
#include <components/detournavigator/debug.hpp>
#include <components/detournavigator/settings.hpp>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
@ -36,35 +37,35 @@ namespace
TEST_F(DetourNavigatorGetTilesPositionsTest, for_object_in_single_tile_should_return_one_tile)
{
getTilesPositions(osg::Vec3f(2, 2, 0), osg::Vec3f(31, 31, 1), mSettings, mCollect);
getTilesPositions(makeTilesPositionsRange(osg::Vec3f(2, 2, 0), osg::Vec3f(31, 31, 1), mSettings), mCollect);
EXPECT_THAT(mTilesPositions, ElementsAre(TilePosition(0, 0)));
}
TEST_F(DetourNavigatorGetTilesPositionsTest, for_object_with_x_bounds_in_two_tiles_should_return_two_tiles)
{
getTilesPositions(osg::Vec3f(0, 0, 0), osg::Vec3f(32, 31, 1), mSettings, mCollect);
getTilesPositions(makeTilesPositionsRange(osg::Vec3f(0, 0, 0), osg::Vec3f(32, 31, 1), mSettings), mCollect);
EXPECT_THAT(mTilesPositions, ElementsAre(TilePosition(0, 0), TilePosition(1, 0)));
}
TEST_F(DetourNavigatorGetTilesPositionsTest, for_object_with_y_bounds_in_two_tiles_should_return_two_tiles)
{
getTilesPositions(osg::Vec3f(0, 0, 0), osg::Vec3f(31, 32, 1), mSettings, mCollect);
getTilesPositions(makeTilesPositionsRange(osg::Vec3f(0, 0, 0), osg::Vec3f(31, 32, 1), mSettings), mCollect);
EXPECT_THAT(mTilesPositions, ElementsAre(TilePosition(0, 0), TilePosition(0, 1)));
}
TEST_F(DetourNavigatorGetTilesPositionsTest, tiling_works_only_for_x_and_y_coordinates)
{
getTilesPositions(osg::Vec3f(0, 0, 0), osg::Vec3f(31, 31, 32), mSettings, mCollect);
getTilesPositions(makeTilesPositionsRange(osg::Vec3f(0, 0, 0), osg::Vec3f(31, 31, 32), mSettings), mCollect);
EXPECT_THAT(mTilesPositions, ElementsAre(TilePosition(0, 0)));
}
TEST_F(DetourNavigatorGetTilesPositionsTest, tiling_should_work_with_negative_coordinates)
{
getTilesPositions(osg::Vec3f(-31, -31, 0), osg::Vec3f(31, 31, 1), mSettings, mCollect);
getTilesPositions(makeTilesPositionsRange(osg::Vec3f(-31, -31, 0), osg::Vec3f(31, 31, 1), mSettings), mCollect);
EXPECT_THAT(mTilesPositions, ElementsAre(
TilePosition(-1, -1),
@ -78,7 +79,7 @@ namespace
{
mSettings.mBorderSize = 1;
getTilesPositions(osg::Vec3f(0, 0, 0), osg::Vec3f(31.5, 31.5, 1), mSettings, mCollect);
getTilesPositions(makeTilesPositionsRange(osg::Vec3f(0, 0, 0), osg::Vec3f(31.5, 31.5, 1), mSettings), mCollect);
EXPECT_THAT(mTilesPositions, ElementsAre(
TilePosition(-1, -1),
@ -97,7 +98,7 @@ namespace
{
mSettings.mRecastScaleFactor = 0.5;
getTilesPositions(osg::Vec3f(0, 0, 0), osg::Vec3f(32, 32, 1), mSettings, mCollect);
getTilesPositions(makeTilesPositionsRange(osg::Vec3f(0, 0, 0), osg::Vec3f(32, 32, 1), mSettings), mCollect);
EXPECT_THAT(mTilesPositions, ElementsAre(TilePosition(0, 0)));
}

View File

@ -208,6 +208,7 @@ add_component_dir(detournavigator
serialization
navmeshdbutils
recast
gettilespositions
)
add_component_dir(loadinglistener

View File

@ -0,0 +1,62 @@
#include "gettilespositions.hpp"
#include "settings.hpp"
#include "settingsutils.hpp"
#include "tileposition.hpp"
#include <components/misc/convert.hpp>
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
namespace DetourNavigator
{
TilesPositionsRange makeTilesPositionsRange(const osg::Vec3f& aabbMin, const osg::Vec3f& aabbMax,
const RecastSettings& settings)
{
osg::Vec3f min = toNavMeshCoordinates(settings, aabbMin);
osg::Vec3f max = toNavMeshCoordinates(settings, aabbMax);
const float border = getBorderSize(settings);
min -= osg::Vec3f(border, border, border);
max += osg::Vec3f(border, border, border);
TilePosition minTile = getTilePosition(settings, min);
TilePosition maxTile = getTilePosition(settings, max);
if (minTile.x() > maxTile.x())
std::swap(minTile.x(), maxTile.x());
if (minTile.y() > maxTile.y())
std::swap(minTile.y(), maxTile.y());
return {minTile, maxTile};
}
TilesPositionsRange makeTilesPositionsRange(const btCollisionShape& shape, const btTransform& transform,
const RecastSettings& settings)
{
btVector3 aabbMin;
btVector3 aabbMax;
shape.getAabb(transform, aabbMin, aabbMax);
return makeTilesPositionsRange(Misc::Convert::toOsg(aabbMin), Misc::Convert::toOsg(aabbMax), settings);
}
TilesPositionsRange makeTilesPositionsRange(const int cellSize, const btVector3& shift,
const RecastSettings& settings)
{
using Misc::Convert::toOsg;
const int halfCellSize = cellSize / 2;
const btTransform transform(btMatrix3x3::getIdentity(), shift);
btVector3 aabbMin = transform(btVector3(-halfCellSize, -halfCellSize, 0));
btVector3 aabbMax = transform(btVector3(halfCellSize, halfCellSize, 0));
aabbMin.setX(std::min(aabbMin.x(), aabbMax.x()));
aabbMin.setY(std::min(aabbMin.y(), aabbMax.y()));
aabbMax.setX(std::max(aabbMin.x(), aabbMax.x()));
aabbMax.setY(std::max(aabbMin.y(), aabbMax.y()));
return makeTilesPositionsRange(toOsg(aabbMin), toOsg(aabbMax), settings);
}
}

View File

@ -1,73 +1,43 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_GETTILESPOSITIONS_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_GETTILESPOSITIONS_H
#include "settings.hpp"
#include "settingsutils.hpp"
#include "tileposition.hpp"
#include <components/misc/convert.hpp>
class btVector3;
class btTransform;
class btCollisionShape;
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
#include <osg/Vec3f>
namespace osg
{
class Vec3f;
}
namespace DetourNavigator
{
template <class Callback>
void getTilesPositions(const osg::Vec3f& aabbMin, const osg::Vec3f& aabbMax,
const RecastSettings& settings, Callback&& callback)
struct RecastSettings;
struct TilesPositionsRange
{
auto min = toNavMeshCoordinates(settings, aabbMin);
auto max = toNavMeshCoordinates(settings, aabbMax);
TilePosition mMin;
TilePosition mMax;
};
const auto border = getBorderSize(settings);
min -= osg::Vec3f(border, border, border);
max += osg::Vec3f(border, border, border);
TilesPositionsRange makeTilesPositionsRange(const osg::Vec3f& aabbMin,
const osg::Vec3f& aabbMax, const RecastSettings& settings);
auto minTile = getTilePosition(settings, min);
auto maxTile = getTilePosition(settings, max);
TilesPositionsRange makeTilesPositionsRange(const btCollisionShape& shape,
const btTransform& transform, const RecastSettings& settings);
if (minTile.x() > maxTile.x())
std::swap(minTile.x(), maxTile.x());
TilesPositionsRange makeTilesPositionsRange(const int cellSize, const btVector3& shift,
const RecastSettings& settings);
if (minTile.y() > maxTile.y())
std::swap(minTile.y(), maxTile.y());
for (int tileX = minTile.x(); tileX <= maxTile.x(); ++tileX)
for (int tileY = minTile.y(); tileY <= maxTile.y(); ++tileY)
template <class Callback>
void getTilesPositions(const TilesPositionsRange& range, Callback&& callback)
{
for (int tileX = range.mMin.x(); tileX <= range.mMax.x(); ++tileX)
for (int tileY = range.mMin.y(); tileY <= range.mMax.y(); ++tileY)
callback(TilePosition {tileX, tileY});
}
template <class Callback>
void getTilesPositions(const btCollisionShape& shape, const btTransform& transform,
const RecastSettings& settings, Callback&& callback)
{
btVector3 aabbMin;
btVector3 aabbMax;
shape.getAabb(transform, aabbMin, aabbMax);
getTilesPositions(Misc::Convert::toOsg(aabbMin), Misc::Convert::toOsg(aabbMax), settings, std::forward<Callback>(callback));
}
template <class Callback>
void getTilesPositions(const int cellSize, const btVector3& shift,
const RecastSettings& settings, Callback&& callback)
{
using Misc::Convert::toOsg;
const auto halfCellSize = cellSize / 2;
const btTransform transform(btMatrix3x3::getIdentity(), shift);
auto aabbMin = transform(btVector3(-halfCellSize, -halfCellSize, 0));
auto aabbMax = transform(btVector3(halfCellSize, halfCellSize, 0));
aabbMin.setX(std::min(aabbMin.x(), aabbMax.x()));
aabbMin.setY(std::min(aabbMin.y(), aabbMax.y()));
aabbMax.setX(std::max(aabbMin.x(), aabbMax.x()));
aabbMax.setY(std::max(aabbMin.y(), aabbMax.y()));
getTilesPositions(toOsg(aabbMin), toOsg(aabbMax), settings, std::forward<Callback>(callback));
}
}
#endif

View File

@ -5,6 +5,7 @@
#include <components/debug/debuglog.hpp>
#include <components/esm/loadpgrd.hpp>
#include <components/misc/coordinateconverter.hpp>
#include <components/misc/convert.hpp>
namespace DetourNavigator
{

View File

@ -9,6 +9,7 @@
#include <components/debug/debuglog.hpp>
#include <components/bullethelpers/heightfield.hpp>
#include <components/misc/convert.hpp>
#include <DetourNavMesh.h>
@ -262,7 +263,7 @@ namespace DetourNavigator
void NavMeshManager::addChangedTiles(const btCollisionShape& shape, const btTransform& transform,
const ChangeType changeType)
{
getTilesPositions(shape, transform, mSettings.mRecast,
getTilesPositions(makeTilesPositionsRange(shape, transform, mSettings.mRecast),
[&] (const TilePosition& v) { addChangedTile(v, changeType); });
}
@ -272,7 +273,7 @@ namespace DetourNavigator
if (cellSize == std::numeric_limits<int>::max())
return;
getTilesPositions(cellSize, shift, mSettings.mRecast,
getTilesPositions(makeTilesPositionsRange(cellSize, shift, mSettings.mRecast),
[&] (const TilePosition& v) { addChangedTile(v, changeType); });
}

View File

@ -4,6 +4,7 @@
#include "settingsutils.hpp"
#include <components/debug/debuglog.hpp>
#include <components/misc/convert.hpp>
#include <algorithm>
#include <vector>
@ -35,7 +36,8 @@ namespace DetourNavigator
std::vector<TilePosition> tilesPositions;
{
const std::lock_guard lock(mMutex);
getTilesPositions(shape.getShape(), transform, mSettings, [&] (const TilePosition& tilePosition)
getTilesPositions(makeTilesPositionsRange(shape.getShape(), transform, mSettings),
[&] (const TilePosition& tilePosition)
{
if (addTile(id, shape, transform, areaType, tilePosition, mTiles))
tilesPositions.push_back(tilePosition);
@ -90,7 +92,8 @@ namespace DetourNavigator
else
{
const btVector3 shift = Misc::Convert::toBullet(getWaterShift3d(cellPosition, cellSize, level));
getTilesPositions(cellSize, shift, mSettings, [&] (const TilePosition& tilePosition)
getTilesPositions(makeTilesPositionsRange(cellSize, shift, mSettings),
[&] (const TilePosition& tilePosition)
{
const std::lock_guard lock(mMutex);
auto tile = mTiles.find(tilePosition);
@ -148,7 +151,8 @@ namespace DetourNavigator
bool result = false;
getTilesPositions(cellSize, shift, mSettings, [&] (const TilePosition& tilePosition)
getTilesPositions(makeTilesPositionsRange(cellSize, shift, mSettings),
[&] (const TilePosition& tilePosition)
{
const std::lock_guard lock(mMutex);
auto tile = mTiles.find(tilePosition);

View File

@ -57,7 +57,7 @@ namespace DetourNavigator
changed = true;
}
};
getTilesPositions(shape.getShape(), transform, mSettings, onTilePosition);
getTilesPositions(makeTilesPositionsRange(shape.getShape(), transform, mSettings), onTilePosition);
std::sort(newTiles.begin(), newTiles.end());
for (const auto& tile : currentTiles)
{