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:
parent
0c92a567af
commit
85414e2353
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user