mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 15:15:31 +00:00
AI: Check angle between actor and door
This commit is contained in:
parent
37952c9a79
commit
10eb6ec75f
4 changed files with 32 additions and 30 deletions
|
@ -10,7 +10,6 @@
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
#include "../mwrender/rendermode.hpp"
|
#include "../mwrender/rendermode.hpp"
|
||||||
#include "../mwphysics/physicssystem.hpp"
|
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
|
@ -300,9 +299,6 @@ namespace MWBase
|
||||||
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2) = 0;
|
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2) = 0;
|
||||||
///< cast a Ray and return true if there is an object in the ray path.
|
///< cast a Ray and return true if there is an object in the ray path.
|
||||||
|
|
||||||
virtual MWPhysics::PhysicsSystem::RayResult castRayTest (float x1, float y1, float z1, float x2, float y2, float z2) = 0;
|
|
||||||
///< cast a rendering ray and return ray result.
|
|
||||||
|
|
||||||
virtual bool toggleCollisionMode() = 0;
|
virtual bool toggleCollisionMode() = 0;
|
||||||
///< Toggle collision mode for player. If disabled player object should ignore
|
///< Toggle collision mode for player. If disabled player object should ignore
|
||||||
/// collisions and gravity.
|
/// collisions and gravity.
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
#include "obstacle.hpp"
|
#include "obstacle.hpp"
|
||||||
|
|
||||||
#include <osg/Group>
|
|
||||||
|
|
||||||
#include <components/esm/loadcell.hpp>
|
#include <components/esm/loadcell.hpp>
|
||||||
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||||
|
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
|
||||||
|
@ -36,24 +34,39 @@ namespace MWMechanics
|
||||||
|
|
||||||
MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist)
|
MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist)
|
||||||
{
|
{
|
||||||
osg::Vec3f origin = MWBase::Environment::get().getWorld()->getActorHeadTransform(actor).getTrans();
|
MWWorld::CellStore *cell = actor.getCell();
|
||||||
|
|
||||||
osg::Quat orient = osg::Quat(actor.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0))
|
|
||||||
* osg::Quat(actor.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1));
|
|
||||||
|
|
||||||
osg::Vec3f direction = orient * osg::Vec3f(0,1,0);
|
|
||||||
osg::Vec3f dest = origin + direction * minDist;
|
|
||||||
|
|
||||||
|
// Check all the doors in this cell
|
||||||
|
const MWWorld::CellRefList<ESM::Door>& doors = cell->getReadOnlyDoors();
|
||||||
|
const MWWorld::CellRefList<ESM::Door>::List& refList = doors.mList;
|
||||||
|
MWWorld::CellRefList<ESM::Door>::List::const_iterator it = refList.begin();
|
||||||
osg::Vec3f pos(actor.getRefData().getPosition().asVec3());
|
osg::Vec3f pos(actor.getRefData().getPosition().asVec3());
|
||||||
MWPhysics::PhysicsSystem::RayResult result = MWBase::Environment::get().getWorld()->castRayTest(pos.x(), pos.y(), pos.z(), dest.x(), dest.y(), dest.z());
|
pos.z() = 0;
|
||||||
|
|
||||||
if (!result.mHit || result.mHitObject.isEmpty())
|
osg::Vec3f actorDir = (actor.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0));
|
||||||
return MWWorld::Ptr(); // none found
|
|
||||||
|
|
||||||
if (result.mHitObject.getClass().getTypeName() == typeid(ESM::Door).name() && !result.mHitObject.getCellRef().getTeleport())
|
for (; it != refList.end(); ++it)
|
||||||
return result.mHitObject;
|
{
|
||||||
|
const MWWorld::LiveCellRef<ESM::Door>& ref = *it;
|
||||||
|
|
||||||
return MWWorld::Ptr();
|
osg::Vec3f doorPos(ref.mData.getPosition().asVec3());
|
||||||
|
doorPos.z() = 0;
|
||||||
|
|
||||||
|
float angle = std::acos(actorDir * (doorPos - pos) / (actorDir.length() * (doorPos - pos).length()));
|
||||||
|
|
||||||
|
// Allow 60 degrees angle between actor and door
|
||||||
|
if (angle < -osg::PI / 3 || angle > osg::PI / 3)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Door is not close enough
|
||||||
|
if ((pos - doorPos).length2() > minDist*minDist)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// FIXME cast
|
||||||
|
return MWWorld::Ptr(&const_cast<MWWorld::LiveCellRef<ESM::Door> &>(ref), actor.getCell()); // found, stop searching
|
||||||
|
}
|
||||||
|
|
||||||
|
return MWWorld::Ptr(); // none found
|
||||||
}
|
}
|
||||||
|
|
||||||
ObstacleCheck::ObstacleCheck():
|
ObstacleCheck::ObstacleCheck():
|
||||||
|
|
|
@ -1451,16 +1451,12 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2)
|
bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2)
|
||||||
{
|
|
||||||
MWPhysics::PhysicsSystem::RayResult result = castRayTest(x1, y1, z1, x2, y2, z2);
|
|
||||||
return result.mHit;
|
|
||||||
}
|
|
||||||
|
|
||||||
MWPhysics::PhysicsSystem::RayResult World::castRayTest (float x1, float y1, float z1, float x2, float y2, float z2)
|
|
||||||
{
|
{
|
||||||
osg::Vec3f a(x1,y1,z1);
|
osg::Vec3f a(x1,y1,z1);
|
||||||
osg::Vec3f b(x2,y2,z2);
|
osg::Vec3f b(x2,y2,z2);
|
||||||
return mPhysics->castRay(a, b, MWWorld::Ptr(), std::vector<MWWorld::Ptr>(), MWPhysics::CollisionType_World|MWPhysics::CollisionType_Door);
|
|
||||||
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), std::vector<MWWorld::Ptr>(), MWPhysics::CollisionType_World|MWPhysics::CollisionType_Door);
|
||||||
|
return result.mHit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::processDoors(float duration)
|
void World::processDoors(float duration)
|
||||||
|
|
|
@ -407,9 +407,6 @@ namespace MWWorld
|
||||||
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2);
|
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2);
|
||||||
///< cast a Ray and return true if there is an object in the ray path.
|
///< cast a Ray and return true if there is an object in the ray path.
|
||||||
|
|
||||||
virtual MWPhysics::PhysicsSystem::RayResult castRayTest (float x1, float y1, float z1, float x2, float y2, float z2);
|
|
||||||
///< cast a rendering ray and return ray result.
|
|
||||||
|
|
||||||
virtual bool toggleCollisionMode();
|
virtual bool toggleCollisionMode();
|
||||||
///< Toggle collision mode for player. If disabled player object should ignore
|
///< Toggle collision mode for player. If disabled player object should ignore
|
||||||
/// collisions and gravity.
|
/// collisions and gravity.
|
||||||
|
|
Loading…
Reference in a new issue