mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-27 03:35:27 +00:00
Merge branch 'navigator_check_agent_bounds' into 'master'
Check agent bounds on adding agent to navigator See merge request OpenMW/openmw!2629
This commit is contained in:
commit
fbeacc1e0f
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/detournavigator/agentbounds.hpp>
|
#include <components/detournavigator/agentbounds.hpp>
|
||||||
|
#include <components/detournavigator/debug.hpp>
|
||||||
#include <components/detournavigator/heightfieldshape.hpp>
|
#include <components/detournavigator/heightfieldshape.hpp>
|
||||||
#include <components/detournavigator/navigator.hpp>
|
#include <components/detournavigator/navigator.hpp>
|
||||||
#include <components/detournavigator/navigatorimpl.hpp>
|
#include <components/detournavigator/navigatorimpl.hpp>
|
||||||
@ -184,7 +185,9 @@ namespace
|
|||||||
}
|
}
|
||||||
else if (physics.getActor(ptr))
|
else if (physics.getActor(ptr))
|
||||||
{
|
{
|
||||||
navigator.addAgent(world.getPathfindingAgentBounds(ptr));
|
const DetourNavigator::AgentBounds agentBounds = world.getPathfindingAgentBounds(ptr);
|
||||||
|
if (!navigator.addAgent(agentBounds))
|
||||||
|
Log(Debug::Warning) << "Agent bounds are not supported by navigator: " << agentBounds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <components/sceneutil/workqueue.hpp>
|
#include <components/sceneutil/workqueue.hpp>
|
||||||
|
|
||||||
#include <components/detournavigator/agentbounds.hpp>
|
#include <components/detournavigator/agentbounds.hpp>
|
||||||
|
#include <components/detournavigator/debug.hpp>
|
||||||
#include <components/detournavigator/navigator.hpp>
|
#include <components/detournavigator/navigator.hpp>
|
||||||
#include <components/detournavigator/navigatorimpl.hpp>
|
#include <components/detournavigator/navigatorimpl.hpp>
|
||||||
#include <components/detournavigator/settings.hpp>
|
#include <components/detournavigator/settings.hpp>
|
||||||
@ -1269,7 +1270,11 @@ namespace MWWorld
|
|||||||
mWorldScene->updateObjectScale(ptr);
|
mWorldScene->updateObjectScale(ptr);
|
||||||
|
|
||||||
if (mPhysics->getActor(ptr))
|
if (mPhysics->getActor(ptr))
|
||||||
mNavigator->addAgent(getPathfindingAgentBounds(ptr));
|
{
|
||||||
|
const DetourNavigator::AgentBounds agentBounds = getPathfindingAgentBounds(ptr);
|
||||||
|
if (!mNavigator->addAgent(agentBounds))
|
||||||
|
Log(Debug::Warning) << "Scaled agent bounds are not supported by navigator: " << agentBounds;
|
||||||
|
}
|
||||||
else if (const auto object = mPhysics->getObject(ptr))
|
else if (const auto object = mPhysics->getObject(ptr))
|
||||||
updateNavigatorObject(*object);
|
updateNavigatorObject(*object);
|
||||||
}
|
}
|
||||||
@ -2435,7 +2440,9 @@ namespace MWWorld
|
|||||||
|
|
||||||
applyLoopingParticles(player);
|
applyLoopingParticles(player);
|
||||||
|
|
||||||
mNavigator->addAgent(getPathfindingAgentBounds(getPlayerConstPtr()));
|
const DetourNavigator::AgentBounds agentBounds = getPathfindingAgentBounds(getPlayerConstPtr());
|
||||||
|
if (!mNavigator->addAgent(agentBounds))
|
||||||
|
Log(Debug::Warning) << "Player agent bounds are not supported by navigator: " << agentBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
World::RestPermitted World::canRest() const
|
World::RestPermitted World::canRest() const
|
||||||
|
@ -135,7 +135,7 @@ namespace
|
|||||||
|
|
||||||
TEST_F(DetourNavigatorNavigatorTest, find_path_for_existing_agent_with_no_navmesh_should_throw_exception)
|
TEST_F(DetourNavigatorNavigatorTest, find_path_for_existing_agent_with_no_navmesh_should_throw_exception)
|
||||||
{
|
{
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
findPath(*mNavigator, mAgentBounds, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
findPath(*mNavigator, mAgentBounds, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
||||||
Status::StartPolygonNotFound);
|
Status::StartPolygonNotFound);
|
||||||
@ -143,8 +143,8 @@ namespace
|
|||||||
|
|
||||||
TEST_F(DetourNavigatorNavigatorTest, add_agent_should_count_each_agent)
|
TEST_F(DetourNavigatorNavigatorTest, add_agent_should_count_each_agent)
|
||||||
{
|
{
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->removeAgent(mAgentBounds);
|
mNavigator->removeAgent(mAgentBounds);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
findPath(*mNavigator, mAgentBounds, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
findPath(*mNavigator, mAgentBounds, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
||||||
@ -163,7 +163,7 @@ namespace
|
|||||||
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
auto updateGuard = mNavigator->makeUpdateGuard();
|
auto updateGuard = mNavigator->makeUpdateGuard();
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, updateGuard.get());
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, updateGuard.get());
|
||||||
mNavigator->update(mPlayerPosition, updateGuard.get());
|
mNavigator->update(mPlayerPosition, updateGuard.get());
|
||||||
@ -220,7 +220,7 @@ namespace
|
|||||||
compound.shape().addChildShape(
|
compound.shape().addChildShape(
|
||||||
btTransform(btMatrix3x3::getIdentity(), btVector3(0, 0, 0)), new btBoxShape(btVector3(20, 20, 100)));
|
btTransform(btMatrix3x3::getIdentity(), btVector3(0, 0, 0)), new btBoxShape(btVector3(20, 20, 100)));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
@ -311,7 +311,7 @@ namespace
|
|||||||
compound.shape().addChildShape(
|
compound.shape().addChildShape(
|
||||||
btTransform(btMatrix3x3::getIdentity(), btVector3(0, 0, 0)), new btBoxShape(btVector3(20, 20, 100)));
|
btTransform(btMatrix3x3::getIdentity(), btVector3(0, 0, 0)), new btBoxShape(btVector3(20, 20, 100)));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->addObject(
|
mNavigator->addObject(
|
||||||
ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform, nullptr);
|
ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform, nullptr);
|
||||||
@ -409,7 +409,7 @@ namespace
|
|||||||
CollisionShapeInstance heightfield2(makeSquareHeightfieldTerrainShape(heightfieldData2));
|
CollisionShapeInstance heightfield2(makeSquareHeightfieldTerrainShape(heightfieldData2));
|
||||||
heightfield2.shape().setLocalScaling(btVector3(128, 128, 1));
|
heightfield2.shape().setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addObject(ObjectId(&heightfield1.shape()), ObjectShapes(heightfield1.instance(), mObjectTransform),
|
mNavigator->addObject(ObjectId(&heightfield1.shape()), ObjectShapes(heightfield1.instance(), mObjectTransform),
|
||||||
mTransform, nullptr);
|
mTransform, nullptr);
|
||||||
mNavigator->addObject(ObjectId(&heightfield2.shape()), ObjectShapes(heightfield2.instance(), mObjectTransform),
|
mNavigator->addObject(ObjectId(&heightfield2.shape()), ObjectShapes(heightfield2.instance(), mObjectTransform),
|
||||||
@ -469,7 +469,7 @@ namespace
|
|||||||
const HeightfieldSurface surface2 = makeSquareHeightfieldSurface(heightfieldData2);
|
const HeightfieldSurface surface2 = makeSquareHeightfieldSurface(heightfieldData2);
|
||||||
const int cellSize2 = mHeightfieldTileSize * (surface2.mSize - 1);
|
const int cellSize2 = mHeightfieldTileSize * (surface2.mSize - 1);
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize1, surface1, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize1, surface1, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
@ -512,7 +512,7 @@ namespace
|
|||||||
|
|
||||||
osg::ref_ptr<const Resource::BulletShapeInstance> instance(new Resource::BulletShapeInstance(bulletShape));
|
osg::ref_ptr<const Resource::BulletShapeInstance> instance(new Resource::BulletShapeInstance(bulletShape));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addObject(
|
mNavigator->addObject(
|
||||||
ObjectId(instance->mCollisionShape.get()), ObjectShapes(instance, mObjectTransform), mTransform, nullptr);
|
ObjectId(instance->mCollisionShape.get()), ObjectShapes(instance, mObjectTransform), mTransform, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
@ -561,7 +561,7 @@ namespace
|
|||||||
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addWater(mCellPosition, cellSize, 300, nullptr);
|
mNavigator->addWater(mCellPosition, cellSize, 300, nullptr);
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
@ -605,7 +605,7 @@ namespace
|
|||||||
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addWater(mCellPosition, cellSize, -25, nullptr);
|
mNavigator->addWater(mCellPosition, cellSize, -25, nullptr);
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
@ -648,7 +648,7 @@ namespace
|
|||||||
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->addWater(mCellPosition, std::numeric_limits<int>::max(), -25, nullptr);
|
mNavigator->addWater(mCellPosition, std::numeric_limits<int>::max(), -25, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
@ -690,7 +690,7 @@ namespace
|
|||||||
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addWater(mCellPosition, cellSize, -25, nullptr);
|
mNavigator->addWater(mCellPosition, cellSize, -25, nullptr);
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
@ -730,7 +730,7 @@ namespace
|
|||||||
CollisionShapeInstance heightfield(makeSquareHeightfieldTerrainShape(heightfieldData));
|
CollisionShapeInstance heightfield(makeSquareHeightfieldTerrainShape(heightfieldData));
|
||||||
heightfield.shape().setLocalScaling(btVector3(128, 128, 1));
|
heightfield.shape().setLocalScaling(btVector3(128, 128, 1));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addObject(ObjectId(&heightfield.shape()), ObjectShapes(heightfield.instance(), mObjectTransform),
|
mNavigator->addObject(ObjectId(&heightfield.shape()), ObjectShapes(heightfield.instance(), mObjectTransform),
|
||||||
mTransform, nullptr);
|
mTransform, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
@ -787,7 +787,7 @@ namespace
|
|||||||
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
@ -843,7 +843,7 @@ namespace
|
|||||||
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
@ -882,7 +882,7 @@ namespace
|
|||||||
std::generate_n(
|
std::generate_n(
|
||||||
std::back_inserter(boxes), 100, [] { return std::make_unique<btBoxShape>(btVector3(20, 20, 100)); });
|
std::back_inserter(boxes), 100, [] { return std::make_unique<btBoxShape>(btVector3(20, 20, 100)); });
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
|
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
|
|
||||||
@ -944,7 +944,7 @@ namespace
|
|||||||
std::generate_n(
|
std::generate_n(
|
||||||
std::back_inserter(shapes), 100, [] { return std::make_unique<btBoxShape>(btVector3(64, 64, 64)); });
|
std::back_inserter(shapes), 100, [] { return std::make_unique<btBoxShape>(btVector3(64, 64, 64)); });
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
|
|
||||||
for (std::size_t i = 0; i < shapes.size(); ++i)
|
for (std::size_t i = 0; i < shapes.size(); ++i)
|
||||||
{
|
{
|
||||||
@ -992,7 +992,7 @@ namespace
|
|||||||
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
@ -1022,7 +1022,7 @@ namespace
|
|||||||
const btVector3 oscillatingBoxShapePosition(288, 288, 400);
|
const btVector3 oscillatingBoxShapePosition(288, 288, 400);
|
||||||
CollisionShapeInstance borderBox(std::make_unique<btBoxShape>(btVector3(50, 50, 50)));
|
CollisionShapeInstance borderBox(std::make_unique<btBoxShape>(btVector3(50, 50, 50)));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->addObject(ObjectId(&oscillatingBox.shape()),
|
mNavigator->addObject(ObjectId(&oscillatingBox.shape()),
|
||||||
ObjectShapes(oscillatingBox.instance(), mObjectTransform),
|
ObjectShapes(oscillatingBox.instance(), mObjectTransform),
|
||||||
@ -1058,7 +1058,7 @@ namespace
|
|||||||
const HeightfieldPlane plane{ 100 };
|
const HeightfieldPlane plane{ 100 };
|
||||||
const int cellSize = mHeightfieldTileSize * 4;
|
const int cellSize = mHeightfieldTileSize * 4;
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, plane, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, plane, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
|
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
|
||||||
@ -1109,7 +1109,7 @@ namespace
|
|||||||
compound.shape().addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(204, -204, 0)),
|
compound.shape().addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(204, -204, 0)),
|
||||||
new btBoxShape(btVector3(200, 200, 1000)));
|
new btBoxShape(btVector3(200, 200, 1000)));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->addObject(
|
mNavigator->addObject(
|
||||||
ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform, nullptr);
|
ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform, nullptr);
|
||||||
@ -1150,7 +1150,7 @@ namespace
|
|||||||
compound.shape().addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(204, -204, 0)),
|
compound.shape().addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(204, -204, 0)),
|
||||||
new btBoxShape(btVector3(100, 100, 1000)));
|
new btBoxShape(btVector3(100, 100, 1000)));
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
mNavigator->addObject(
|
mNavigator->addObject(
|
||||||
ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform, nullptr);
|
ObjectId(&compound.shape()), ObjectShapes(compound.instance(), mObjectTransform), mTransform, nullptr);
|
||||||
@ -1192,7 +1192,7 @@ namespace
|
|||||||
const int cellSize2 = 200;
|
const int cellSize2 = 200;
|
||||||
const float level2 = 2;
|
const float level2 = 2;
|
||||||
|
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addWater(mCellPosition, cellSize1, level1, nullptr);
|
mNavigator->addWater(mCellPosition, cellSize1, level1, nullptr);
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
@ -1206,31 +1206,6 @@ namespace
|
|||||||
EXPECT_EQ(mNavigator->getNavMesh(mAgentBounds)->lockConst()->getVersion(), version);
|
EXPECT_EQ(mNavigator->getNavMesh(mAgentBounds)->lockConst()->getVersion(), version);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DetourNavigatorNavigatorTest, add_agent_with_zero_coordinate_should_not_have_nav_mesh)
|
|
||||||
{
|
|
||||||
constexpr std::array<float, 5 * 5> heightfieldData{ {
|
|
||||||
0, 0, 0, 0, 0, // row 0
|
|
||||||
0, -25, -25, -25, -25, // row 1
|
|
||||||
0, -25, -100, -100, -100, // row 2
|
|
||||||
0, -25, -100, -100, -100, // row 3
|
|
||||||
0, -25, -100, -100, -100, // row 4
|
|
||||||
} };
|
|
||||||
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
|
||||||
const int cellSize = mHeightfieldTileSize * (surface.mSize - 1);
|
|
||||||
|
|
||||||
const AgentBounds agentBounds{ CollisionShapeType::RotatingBox, { 0, 1, 1 } };
|
|
||||||
mNavigator->addAgent(agentBounds);
|
|
||||||
auto updateGuard = mNavigator->makeUpdateGuard();
|
|
||||||
mNavigator->addHeightfield(mCellPosition, cellSize, surface, updateGuard.get());
|
|
||||||
mNavigator->update(mPlayerPosition, updateGuard.get());
|
|
||||||
updateGuard.reset();
|
|
||||||
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
|
|
||||||
|
|
||||||
EXPECT_EQ(
|
|
||||||
findPath(*mNavigator, agentBounds, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
|
||||||
Status::NavMeshNotFound);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(DetourNavigatorNavigatorTest, update_for_very_big_object_should_be_limited)
|
TEST_F(DetourNavigatorNavigatorTest, update_for_very_big_object_should_be_limited)
|
||||||
{
|
{
|
||||||
const float size = static_cast<float>(2 * static_cast<std::int64_t>(std::numeric_limits<int>::max()) - 1);
|
const float size = static_cast<float>(2 * static_cast<std::int64_t>(std::numeric_limits<int>::max()) - 1);
|
||||||
@ -1241,7 +1216,7 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
mNavigator->updateBounds(mPlayerPosition, nullptr);
|
mNavigator->updateBounds(mPlayerPosition, nullptr);
|
||||||
mNavigator->addAgent(mAgentBounds);
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->addObject(ObjectId(&bigBox.shape()), ObjectShapes(bigBox.instance(), objectTransform),
|
mNavigator->addObject(ObjectId(&bigBox.shape()), ObjectShapes(bigBox.instance(), objectTransform),
|
||||||
btTransform::getIdentity(), nullptr);
|
btTransform::getIdentity(), nullptr);
|
||||||
|
|
||||||
@ -1275,4 +1250,36 @@ namespace
|
|||||||
navMesh->lockConst()->forEachUsedTile([&](const auto&...) { ++usedNavMeshTiles; });
|
navMesh->lockConst()->forEachUsedTile([&](const auto&...) { ++usedNavMeshTiles; });
|
||||||
EXPECT_EQ(usedNavMeshTiles, 509);
|
EXPECT_EQ(usedNavMeshTiles, 509);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DetourNavigatorNavigatorNotSupportedAgentBoundsTest : TestWithParam<AgentBounds>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(DetourNavigatorNavigatorNotSupportedAgentBoundsTest, on_add_agent)
|
||||||
|
{
|
||||||
|
const Settings settings = makeSettings();
|
||||||
|
NavigatorImpl navigator(settings, nullptr);
|
||||||
|
EXPECT_FALSE(navigator.addAgent(GetParam()));
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::array notSupportedAgentBounds = {
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::Aabb, .mHalfExtents = osg::Vec3f(0, 0, 0) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::RotatingBox, .mHalfExtents = osg::Vec3f(0, 0, 0) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::Cylinder, .mHalfExtents = osg::Vec3f(0, 0, 0) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::Aabb, .mHalfExtents = osg::Vec3f(0, 0, 11.34f) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::RotatingBox, .mHalfExtents = osg::Vec3f(0, 11.34f, 11.34f) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::Cylinder, .mHalfExtents = osg::Vec3f(0, 0, 11.34f) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::Aabb, .mHalfExtents = osg::Vec3f(1, 1, 0) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::RotatingBox, .mHalfExtents = osg::Vec3f(1, 1, 0) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::Cylinder, .mHalfExtents = osg::Vec3f(1, 1, 0) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::Aabb, .mHalfExtents = osg::Vec3f(1, 1, 11.33f) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::RotatingBox, .mHalfExtents = osg::Vec3f(1, 1, 11.33f) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::Cylinder, .mHalfExtents = osg::Vec3f(1, 1, 11.33f) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::Aabb, .mHalfExtents = osg::Vec3f(2043.54f, 2043.54f, 11.34f) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::RotatingBox, .mHalfExtents = osg::Vec3f(2890, 1, 11.34f) },
|
||||||
|
AgentBounds{ .mShapeType = CollisionShapeType::Cylinder, .mHalfExtents = osg::Vec3f(2890, 2890, 11.34f) },
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(NotSupportedAgentBounds, DetourNavigatorNavigatorNotSupportedAgentBoundsTest,
|
||||||
|
ValuesIn(notSupportedAgentBounds));
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,8 @@ namespace DetourNavigator
|
|||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
constexpr int walkableRadiusUpperLimit = 255;
|
||||||
|
|
||||||
struct Rectangle
|
struct Rectangle
|
||||||
{
|
{
|
||||||
TileBounds mBounds;
|
TileBounds mBounds;
|
||||||
@ -114,6 +116,16 @@ namespace DetourNavigator
|
|||||||
return waterLevel - settings.mSwimHeightScale * agentHalfExtentsZ - agentHalfExtentsZ;
|
return waterLevel - settings.mSwimHeightScale * agentHalfExtentsZ - agentHalfExtentsZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getWalkableHeight(const RecastSettings& settings, const AgentBounds& agentBounds)
|
||||||
|
{
|
||||||
|
return static_cast<int>(std::ceil(getHeight(settings, agentBounds) / settings.mCellHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
int getWalkableRadius(const RecastSettings& settings, const AgentBounds& agentBounds)
|
||||||
|
{
|
||||||
|
return static_cast<int>(std::ceil(getRadius(settings, agentBounds) / settings.mCellSize));
|
||||||
|
}
|
||||||
|
|
||||||
struct RecastParams
|
struct RecastParams
|
||||||
{
|
{
|
||||||
float mSampleDist = 0;
|
float mSampleDist = 0;
|
||||||
@ -128,10 +140,9 @@ namespace DetourNavigator
|
|||||||
{
|
{
|
||||||
RecastParams result;
|
RecastParams result;
|
||||||
|
|
||||||
result.mWalkableHeight
|
result.mWalkableHeight = getWalkableHeight(settings, agentBounds);
|
||||||
= static_cast<int>(std::ceil(getHeight(settings, agentBounds) / settings.mCellHeight));
|
|
||||||
result.mWalkableClimb = static_cast<int>(std::floor(getMaxClimb(settings) / settings.mCellHeight));
|
result.mWalkableClimb = static_cast<int>(std::floor(getMaxClimb(settings) / settings.mCellHeight));
|
||||||
result.mWalkableRadius = static_cast<int>(std::ceil(getRadius(settings, agentBounds) / settings.mCellSize));
|
result.mWalkableRadius = getWalkableRadius(settings, agentBounds);
|
||||||
result.mMaxEdgeLen
|
result.mMaxEdgeLen
|
||||||
= static_cast<int>(std::round(static_cast<float>(settings.mMaxEdgeLen) / settings.mCellSize));
|
= static_cast<int>(std::round(static_cast<float>(settings.mMaxEdgeLen) / settings.mCellSize));
|
||||||
result.mSampleDist
|
result.mSampleDist
|
||||||
@ -288,10 +299,15 @@ namespace DetourNavigator
|
|||||||
context, realTileBounds, recastMesh.getFlatHeightfields(), settings, params, solid);
|
context, realTileBounds, recastMesh.getFlatHeightfields(), settings, params, solid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isValidWalkableHeight(int value)
|
||||||
|
{
|
||||||
|
return value >= 3;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool buildCompactHeightfield(RecastContext& context, const int walkableHeight,
|
[[nodiscard]] bool buildCompactHeightfield(RecastContext& context, const int walkableHeight,
|
||||||
const int walkableClimb, rcHeightfield& solid, rcCompactHeightfield& compact)
|
const int walkableClimb, rcHeightfield& solid, rcCompactHeightfield& compact)
|
||||||
{
|
{
|
||||||
if (walkableHeight < 3)
|
if (!isValidWalkableHeight(walkableHeight))
|
||||||
{
|
{
|
||||||
Log(Debug::Warning) << context.getPrefix()
|
Log(Debug::Warning) << context.getPrefix()
|
||||||
<< "Invalid walkableHeight to build compact heightfield: " << walkableHeight;
|
<< "Invalid walkableHeight to build compact heightfield: " << walkableHeight;
|
||||||
@ -308,9 +324,14 @@ namespace DetourNavigator
|
|||||||
return rcBuildCompactHeightfield(&context, walkableHeight, walkableClimb, solid, compact);
|
return rcBuildCompactHeightfield(&context, walkableHeight, walkableClimb, solid, compact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isValidWalkableRadius(int value)
|
||||||
|
{
|
||||||
|
return 0 < value && value < walkableRadiusUpperLimit;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool erodeWalkableArea(RecastContext& context, int walkableRadius, rcCompactHeightfield& compact)
|
[[nodiscard]] bool erodeWalkableArea(RecastContext& context, int walkableRadius, rcCompactHeightfield& compact)
|
||||||
{
|
{
|
||||||
if (walkableRadius <= 0 || 255 <= walkableRadius)
|
if (!isValidWalkableRadius(walkableRadius))
|
||||||
{
|
{
|
||||||
Log(Debug::Warning) << context.getPrefix()
|
Log(Debug::Warning) << context.getPrefix()
|
||||||
<< "Invalid walkableRadius to erode walkable area: " << walkableRadius;
|
<< "Invalid walkableRadius to erode walkable area: " << walkableRadius;
|
||||||
@ -614,4 +635,10 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
return navMesh;
|
return navMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isSupportedAgentBounds(const RecastSettings& settings, const AgentBounds& agentBounds)
|
||||||
|
{
|
||||||
|
return isValidWalkableHeight(getWalkableHeight(settings, agentBounds))
|
||||||
|
&& isValidWalkableRadius(getWalkableRadius(settings, agentBounds));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,8 @@ namespace DetourNavigator
|
|||||||
const TilePosition& tile, const RecastSettings& settings);
|
const TilePosition& tile, const RecastSettings& settings);
|
||||||
|
|
||||||
NavMeshPtr makeEmptyNavMesh(const Settings& settings);
|
NavMeshPtr makeEmptyNavMesh(const Settings& settings);
|
||||||
|
|
||||||
|
bool isSupportedAgentBounds(const RecastSettings& settings, const AgentBounds& agentBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -77,8 +77,9 @@ namespace DetourNavigator
|
|||||||
* @brief addAgent should be called for each agent even if all of them has same half extents.
|
* @brief addAgent should be called for each agent even if all of them has same half extents.
|
||||||
* @param agentBounds allows to setup bounding cylinder for each agent, for each different half extents
|
* @param agentBounds allows to setup bounding cylinder for each agent, for each different half extents
|
||||||
* there is different navmesh.
|
* there is different navmesh.
|
||||||
|
* @return true if agent is successfully added or false if agent bounds are not supported.
|
||||||
*/
|
*/
|
||||||
virtual void addAgent(const AgentBounds& agentBounds) = 0;
|
virtual bool addAgent(const AgentBounds& agentBounds) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief removeAgent should be called for each agent even if all of them has same half extents
|
* @brief removeAgent should be called for each agent even if all of them has same half extents
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "navigatorimpl.hpp"
|
#include "navigatorimpl.hpp"
|
||||||
|
#include "makenavmesh.hpp"
|
||||||
#include "settingsutils.hpp"
|
#include "settingsutils.hpp"
|
||||||
#include "stats.hpp"
|
#include "stats.hpp"
|
||||||
|
|
||||||
@ -15,13 +16,13 @@ namespace DetourNavigator
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigatorImpl::addAgent(const AgentBounds& agentBounds)
|
bool NavigatorImpl::addAgent(const AgentBounds& agentBounds)
|
||||||
{
|
{
|
||||||
if (agentBounds.mHalfExtents.x() == 0.f || agentBounds.mHalfExtents.y() == 0.f
|
if (!isSupportedAgentBounds(mSettings.mRecast, agentBounds))
|
||||||
|| agentBounds.mHalfExtents.z() == 0.f)
|
return false;
|
||||||
return;
|
|
||||||
++mAgents[agentBounds];
|
++mAgents[agentBounds];
|
||||||
mNavMeshManager.addAgent(agentBounds);
|
mNavMeshManager.addAgent(agentBounds);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigatorImpl::removeAgent(const AgentBounds& agentBounds)
|
void NavigatorImpl::removeAgent(const AgentBounds& agentBounds)
|
||||||
|
@ -23,7 +23,7 @@ namespace DetourNavigator
|
|||||||
return std::make_unique<const UpdateGuard>(*this);
|
return std::make_unique<const UpdateGuard>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addAgent(const AgentBounds& agentBounds) override;
|
bool addAgent(const AgentBounds& agentBounds) override;
|
||||||
|
|
||||||
void removeAgent(const AgentBounds& agentBounds) override;
|
void removeAgent(const AgentBounds& agentBounds) override;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
std::unique_ptr<const UpdateGuard> makeUpdateGuard() override { return nullptr; }
|
std::unique_ptr<const UpdateGuard> makeUpdateGuard() override { return nullptr; }
|
||||||
|
|
||||||
void addAgent(const AgentBounds& /*agentBounds*/) override {}
|
bool addAgent(const AgentBounds& /*agentBounds*/) override { return true; }
|
||||||
|
|
||||||
void removeAgent(const AgentBounds& /*agentBounds*/) override {}
|
void removeAgent(const AgentBounds& /*agentBounds*/) override {}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user