mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-22 13:09:41 +00:00
Merge branch 'fix_the_swimmer' into 'master'
Fix The Swimmer (#5914) See merge request OpenMW/openmw!686
This commit is contained in:
commit
bb9c4d5377
11 changed files with 55 additions and 6 deletions
|
@ -113,6 +113,7 @@
|
||||||
Bug #5902: NiZBufferProperty is unable to disable the depth test
|
Bug #5902: NiZBufferProperty is unable to disable the depth test
|
||||||
Bug #5906: Sunglare doesn't work with Mesa drivers and AMD GPUs
|
Bug #5906: Sunglare doesn't work with Mesa drivers and AMD GPUs
|
||||||
Bug #5912: ImprovedBound mod doesn't work
|
Bug #5912: ImprovedBound mod doesn't work
|
||||||
|
Bug #5914: BM: The Swimmer can't reach destination
|
||||||
Feature #390: 3rd person look "over the shoulder"
|
Feature #390: 3rd person look "over the shoulder"
|
||||||
Feature #832: OpenMW-CS: Handle deleted references
|
Feature #832: OpenMW-CS: Handle deleted references
|
||||||
Feature #1536: Show more information about level on menu
|
Feature #1536: Show more information about level on menu
|
||||||
|
|
|
@ -73,23 +73,25 @@ namespace MWMechanics
|
||||||
const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mTargetActorRefId, false);
|
const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mTargetActorRefId, false);
|
||||||
const osg::Vec3f leaderPos = actor.getRefData().getPosition().asVec3();
|
const osg::Vec3f leaderPos = actor.getRefData().getPosition().asVec3();
|
||||||
const osg::Vec3f followerPos = follower.getRefData().getPosition().asVec3();
|
const osg::Vec3f followerPos = follower.getRefData().getPosition().asVec3();
|
||||||
|
const osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(actor);
|
||||||
|
const float maxHalfExtent = std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z()));
|
||||||
|
|
||||||
if ((leaderPos - followerPos).length2() <= mMaxDist * mMaxDist)
|
if ((leaderPos - followerPos).length2() <= mMaxDist * mMaxDist)
|
||||||
{
|
{
|
||||||
const osg::Vec3f dest(mX, mY, mZ);
|
const osg::Vec3f dest(mX, mY, mZ);
|
||||||
if (pathTo(actor, dest, duration)) //Returns true on path complete
|
if (pathTo(actor, dest, duration, maxHalfExtent)) //Returns true on path complete
|
||||||
{
|
{
|
||||||
mRemainingDuration = mDuration;
|
mRemainingDuration = mDuration;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
mMaxDist = 450;
|
mMaxDist = maxHalfExtent + 450.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Stop moving if the player is too far away
|
// Stop moving if the player is too far away
|
||||||
MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1);
|
MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1);
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
||||||
mMaxDist = 250;
|
mMaxDist = maxHalfExtent + 250.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -114,7 +114,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
|
||||||
if (wasShortcutting || doesPathNeedRecalc(dest, actor)) // if need to rebuild path
|
if (wasShortcutting || doesPathNeedRecalc(dest, actor)) // if need to rebuild path
|
||||||
{
|
{
|
||||||
const auto pathfindingHalfExtents = world->getPathfindingHalfExtents(actor);
|
const auto pathfindingHalfExtents = world->getPathfindingHalfExtents(actor);
|
||||||
mPathFinder.buildPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()),
|
mPathFinder.buildLimitedPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()),
|
||||||
pathfindingHalfExtents, getNavigatorFlags(actor), getAreaCosts(actor));
|
pathfindingHalfExtents, getNavigatorFlags(actor), getAreaCosts(actor));
|
||||||
mRotateOnTheRunChecks = 3;
|
mRotateOnTheRunChecks = 3;
|
||||||
|
|
||||||
|
|
|
@ -442,4 +442,21 @@ namespace MWMechanics
|
||||||
|
|
||||||
std::copy(prePath.rbegin(), prePath.rend(), std::front_inserter(mPath));
|
std::copy(prePath.rbegin(), prePath.rend(), std::front_inserter(mPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PathFinder::buildLimitedPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint,
|
||||||
|
const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, const osg::Vec3f& halfExtents,
|
||||||
|
const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts)
|
||||||
|
{
|
||||||
|
const auto navigator = MWBase::Environment::get().getWorld()->getNavigator();
|
||||||
|
const auto maxDistance = std::min(
|
||||||
|
navigator->getMaxNavmeshAreaRealRadius(),
|
||||||
|
static_cast<float>(Constants::CellSizeInUnits)
|
||||||
|
);
|
||||||
|
const auto startToEnd = endPoint - startPoint;
|
||||||
|
const auto distance = startToEnd.length();
|
||||||
|
if (distance <= maxDistance)
|
||||||
|
return buildPath(actor, startPoint, endPoint, cell, pathgridGraph, halfExtents, flags, areaCosts);
|
||||||
|
const auto end = startPoint + startToEnd * maxDistance / distance;
|
||||||
|
buildPath(actor, startPoint, end, cell, pathgridGraph, halfExtents, flags, areaCosts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,10 @@ namespace MWMechanics
|
||||||
void buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
|
void buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
|
||||||
const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts);
|
const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts);
|
||||||
|
|
||||||
|
void buildLimitedPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint,
|
||||||
|
const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, const osg::Vec3f& halfExtents,
|
||||||
|
const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts);
|
||||||
|
|
||||||
/// Remove front point if exist and within tolerance
|
/// Remove front point if exist and within tolerance
|
||||||
void update(const osg::Vec3f& position, float pointTolerance, float destinationTolerance,
|
void update(const osg::Vec3f& position, float pointTolerance, float destinationTolerance,
|
||||||
bool shortenIfAlmostStraight, bool canMoveByZ);
|
bool shortenIfAlmostStraight, bool canMoveByZ);
|
||||||
|
|
|
@ -235,6 +235,8 @@ namespace DetourNavigator
|
||||||
const osg::Vec3f& end, const Flags includeFlags) const;
|
const osg::Vec3f& end, const Flags includeFlags) const;
|
||||||
|
|
||||||
virtual RecastMeshTiles getRecastMeshTiles() = 0;
|
virtual RecastMeshTiles getRecastMeshTiles() = 0;
|
||||||
|
|
||||||
|
virtual float getMaxNavmeshAreaRealRadius() const = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -213,4 +213,10 @@ namespace DetourNavigator
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float NavigatorImpl::getMaxNavmeshAreaRealRadius() const
|
||||||
|
{
|
||||||
|
const auto& settings = getSettings();
|
||||||
|
return getRealTileSize(settings) * getMaxNavmeshAreaRadius(settings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ namespace DetourNavigator
|
||||||
|
|
||||||
RecastMeshTiles getRecastMeshTiles() override;
|
RecastMeshTiles getRecastMeshTiles() override;
|
||||||
|
|
||||||
|
float getMaxNavmeshAreaRealRadius() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Settings mSettings;
|
Settings mSettings;
|
||||||
NavMeshManager mNavMeshManager;
|
NavMeshManager mNavMeshManager;
|
||||||
|
|
|
@ -92,6 +92,11 @@ namespace DetourNavigator
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getMaxNavmeshAreaRealRadius() const override
|
||||||
|
{
|
||||||
|
return std::numeric_limits<float>::max();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Settings mDefaultSettings {};
|
Settings mDefaultSettings {};
|
||||||
SharedNavMeshCacheItem mEmptyNavMeshCacheItem;
|
SharedNavMeshCacheItem mEmptyNavMeshCacheItem;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_SETTINGSUTILS_H
|
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_SETTINGSUTILS_H
|
||||||
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_SETTINGSUTILS_H
|
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_SETTINGSUTILS_H
|
||||||
|
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
@ -89,6 +89,16 @@ namespace DetourNavigator
|
||||||
transform.getOrigin() + btVector3(0, 0, getSwimLevel(settings, agentHalfExtentsZ) - agentHalfExtentsZ)
|
transform.getOrigin() + btVector3(0, 0, getSwimLevel(settings, agentHalfExtentsZ) - agentHalfExtentsZ)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float getRealTileSize(const Settings& settings)
|
||||||
|
{
|
||||||
|
return settings.mTileSize * settings.mCellSize / settings.mRecastScaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float getMaxNavmeshAreaRadius(const Settings& settings)
|
||||||
|
{
|
||||||
|
return std::floor(std::sqrt(settings.mMaxTilesNumber / osg::PI)) - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -305,7 +305,7 @@ tile size
|
||||||
|
|
||||||
:Type: integer
|
:Type: integer
|
||||||
:Range: > 0
|
:Range: > 0
|
||||||
:Default: 64
|
:Default: 128
|
||||||
|
|
||||||
The width and height of each tile.
|
The width and height of each tile.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue