aimToTarget: Fix the collision box translation not being taken into account

This commit is contained in:
scrawl 2015-11-03 18:15:47 +01:00
parent de97a8a3da
commit a5f8ffb83d
5 changed files with 40 additions and 8 deletions

View file

@ -95,6 +95,11 @@ void Actor::updatePosition()
mCollisionObject->setWorldTransform(tr); mCollisionObject->setWorldTransform(tr);
} }
osg::Vec3f Actor::getPosition() const
{
return toOsg(mCollisionObject->getWorldTransform().getOrigin());
}
void Actor::updateRotation () void Actor::updateRotation ()
{ {
btTransform tr = mCollisionObject->getWorldTransform(); btTransform tr = mCollisionObject->getWorldTransform();

View file

@ -70,6 +70,12 @@ namespace MWPhysics
*/ */
osg::Vec3f getHalfExtents() const; osg::Vec3f getHalfExtents() const;
/**
* Returns the position of the collision body
* @note The collision shape's origin is in its center, so the position returned can be described as center of the actor collision box in world space.
*/
osg::Vec3f getPosition() const;
/** /**
* Returns the half extents of the collision body (scaled according to rendering scale) * Returns the half extents of the collision body (scaled according to rendering scale)
* @note The reason we need this extra method is because of an inconsistency in MW - NPC race scales aren't applied to the collision shape, * @note The reason we need this extra method is because of an inconsistency in MW - NPC race scales aren't applied to the collision shape,

View file

@ -869,24 +869,33 @@ namespace MWPhysics
} }
} }
osg::Vec3f PhysicsSystem::getHalfExtents(const MWWorld::Ptr &actor) osg::Vec3f PhysicsSystem::getHalfExtents(const MWWorld::Ptr &actor) const
{ {
Actor* physactor = getActor(actor); const Actor* physactor = getActor(actor);
if (physactor) if (physactor)
return physactor->getHalfExtents(); return physactor->getHalfExtents();
else else
return osg::Vec3f(); return osg::Vec3f();
} }
osg::Vec3f PhysicsSystem::getRenderingHalfExtents(const MWWorld::Ptr &actor) osg::Vec3f PhysicsSystem::getRenderingHalfExtents(const MWWorld::Ptr &actor) const
{ {
Actor* physactor = getActor(actor); const Actor* physactor = getActor(actor);
if (physactor) if (physactor)
return physactor->getRenderingHalfExtents(); return physactor->getRenderingHalfExtents();
else else
return osg::Vec3f(); return osg::Vec3f();
} }
osg::Vec3f PhysicsSystem::getPosition(const MWWorld::Ptr &actor) const
{
const Actor* physactor = getActor(actor);
if (physactor)
return physactor->getPosition();
else
return osg::Vec3f();
}
class ContactTestResultCallback : public btCollisionWorld::ContactResultCallback class ContactTestResultCallback : public btCollisionWorld::ContactResultCallback
{ {
public: public:
@ -1036,6 +1045,14 @@ namespace MWPhysics
return NULL; return NULL;
} }
const Actor *PhysicsSystem::getActor(const MWWorld::Ptr &ptr) const
{
ActorMap::const_iterator found = mActors.find(ptr);
if (found != mActors.end())
return found->second;
return NULL;
}
void PhysicsSystem::updateScale(const MWWorld::Ptr &ptr) void PhysicsSystem::updateScale(const MWWorld::Ptr &ptr)
{ {
ObjectMap::iterator found = mObjects.find(ptr); ObjectMap::iterator found = mObjects.find(ptr);

View file

@ -62,6 +62,7 @@ namespace MWPhysics
void updatePtr (const MWWorld::Ptr& old, const MWWorld::Ptr& updated); void updatePtr (const MWWorld::Ptr& old, const MWWorld::Ptr& updated);
Actor* getActor(const MWWorld::Ptr& ptr); Actor* getActor(const MWWorld::Ptr& ptr);
const Actor* getActor(const MWWorld::Ptr& ptr) const;
// Object or Actor // Object or Actor
void remove (const MWWorld::Ptr& ptr); void remove (const MWWorld::Ptr& ptr);
@ -108,10 +109,14 @@ namespace MWPhysics
bool isOnGround (const MWWorld::Ptr& actor); bool isOnGround (const MWWorld::Ptr& actor);
/// Get physical half extents (scaled) of the given actor. /// Get physical half extents (scaled) of the given actor.
osg::Vec3f getHalfExtents(const MWWorld::Ptr& actor); osg::Vec3f getHalfExtents(const MWWorld::Ptr& actor) const;
/// @see MWPhysics::Actor::getRenderingHalfExtents /// @see MWPhysics::Actor::getRenderingHalfExtents
osg::Vec3f getRenderingHalfExtents(const MWWorld::Ptr& actor); osg::Vec3f getRenderingHalfExtents(const MWWorld::Ptr& actor) const;
/// Get the position of the collision shape for the actor. Use together with getHalfExtents() to get the collision bounds in world space.
/// @note The collision shape's origin is in its center, so the position returned can be described as center of the actor collision box in world space.
osg::Vec3f getPosition(const MWWorld::Ptr& actor) const;
/// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will /// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will
/// be overwritten. Valid until the next call to applyQueuedMovement. /// be overwritten. Valid until the next call to applyQueuedMovement.

View file

@ -3259,8 +3259,7 @@ namespace MWWorld
osg::Vec3f World::aimToTarget(const Ptr &actor, const MWWorld::Ptr& target) osg::Vec3f World::aimToTarget(const Ptr &actor, const MWWorld::Ptr& target)
{ {
osg::Vec3f weaponPos = getActorHeadPosition(actor, mRendering); osg::Vec3f weaponPos = getActorHeadPosition(actor, mRendering);
osg::Vec3f targetPos = target.getRefData().getPosition().asVec3(); osg::Vec3f targetPos = mPhysics->getPosition(target);
targetPos.z() += mPhysics->getHalfExtents(target).z();
return (targetPos - weaponPos); return (targetPos - weaponPos);
} }
} }