1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-24 13:43:43 +00:00

Check for line of sight for wander destination

This commit is contained in:
elsid 2020-02-02 20:02:25 +01:00
parent 0c92a567af
commit 85414e2353
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40
5 changed files with 30 additions and 12 deletions

View File

@ -313,6 +313,8 @@ namespace MWBase
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2) = 0;
virtual bool castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask, const MWWorld::ConstPtr& ignore) = 0;
virtual void setActorCollisionMode(const MWWorld::Ptr& ptr, bool internal, bool external) = 0;
virtual bool isActorCollisionEnabled(const MWWorld::Ptr& ptr) = 0;

View File

@ -61,6 +61,26 @@ namespace MWMechanics
rotation.makeRotate(randomDirection, osg::Vec3f(0.0, 0.0, 1.0));
return position + osg::Vec3f(distance, 0.0, 0.0) * rotation;
}
bool isDestinationHidden(const MWWorld::ConstPtr &actor, const osg::Vec3f& destination)
{
const auto position = actor.getRefData().getPosition().asVec3();
const bool isWaterCreature = actor.getClass().isPureWaterCreature(actor);
const bool isFlyingCreature = actor.getClass().isPureFlyingCreature(actor);
const osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getPathfindingHalfExtents(actor);
osg::Vec3f direction = destination - position;
direction.normalize();
const auto visibleDestination = (
isWaterCreature || isFlyingCreature
? destination
: destination + osg::Vec3f(0, 0, halfExtents.z())
) + direction * std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z()));
const int mask = MWPhysics::CollisionType_World
| MWPhysics::CollisionType_HeightMap
| MWPhysics::CollisionType_Door
| MWPhysics::CollisionType_Actor;
return MWBase::Environment::get().getWorld()->castRay(position, visibleDestination, mask, actor);
}
}
AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector<unsigned char>& idle, bool repeat):
@ -328,7 +348,7 @@ namespace MWMechanics
if (!isWaterCreature && destinationIsAtWater(actor, mDestination))
continue;
if ((isWaterCreature || isFlyingCreature) && destinationThroughGround(currentPosition, mDestination))
if (isDestinationHidden(actor, mDestination))
continue;
if (isWaterCreature || isFlyingCreature)
@ -357,16 +377,6 @@ namespace MWMechanics
return MWBase::Environment::get().getWorld()->isUnderwater(actor.getCell(), positionBelowSurface);
}
/*
* Returns true if the start to end point travels through a collision point (land).
*/
bool AiWander::destinationThroughGround(const osg::Vec3f& startPoint, const osg::Vec3f& destination) {
const int mask = MWPhysics::CollisionType_World | MWPhysics::CollisionType_HeightMap | MWPhysics::CollisionType_Door;
return MWBase::Environment::get().getWorld()->castRay(startPoint.x(), startPoint.y(), startPoint.z(),
destination.x(), destination.y(), destination.z(),
mask);
}
void AiWander::completeManualWalking(const MWWorld::Ptr &actor, AiWanderStorage &storage) {
stopWalking(actor, storage);
mObstacleCheck.clear();

View File

@ -126,7 +126,6 @@ namespace MWMechanics
bool isPackageCompleted(const MWWorld::Ptr& actor, AiWanderStorage& storage);
void wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance);
bool destinationIsAtWater(const MWWorld::Ptr &actor, const osg::Vec3f& destination);
bool destinationThroughGround(const osg::Vec3f& startPoint, const osg::Vec3f& destination);
void completeManualWalking(const MWWorld::Ptr &actor, AiWanderStorage &storage);
int mDistance; // how far the actor can wander from the spawn point

View File

@ -1640,6 +1640,11 @@ namespace MWWorld
return result.mHit;
}
bool World::castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask, const MWWorld::ConstPtr& ignore)
{
return mPhysics->castRay(from, to, ignore, std::vector<MWWorld::Ptr>(), mask).mHit;
}
bool World::rotateDoor(const Ptr door, MWWorld::DoorState state, float duration)
{
const ESM::Position& objPos = door.getRefData().getPosition();

View File

@ -426,6 +426,8 @@ namespace MWWorld
bool castRay (float x1, float y1, float z1, float x2, float y2, float z2) override;
bool castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask, const MWWorld::ConstPtr& ignore) override;
void setActorCollisionMode(const Ptr& ptr, bool internal, bool external) override;
bool isActorCollisionEnabled(const Ptr& ptr) override;