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:
parent
d1d29a2452
commit
bba7beb0c5
@ -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();
|
||||
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -208,6 +208,7 @@ add_component_dir(detournavigator
|
||||
serialization
|
||||
navmeshdbutils
|
||||
recast
|
||||
gettilespositions
|
||||
)
|
||||
|
||||
add_component_dir(loadinglistener
|
||||
|
62
components/detournavigator/gettilespositions.cpp
Normal file
62
components/detournavigator/gettilespositions.cpp
Normal 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);
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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); });
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user