diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index a681c7945..98ccefe71 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -95,6 +95,11 @@ void Actor::updatePosition() mCollisionObject->setWorldTransform(tr); } +osg::Vec3f Actor::getPosition() const +{ + return toOsg(mCollisionObject->getWorldTransform().getOrigin()); +} + void Actor::updateRotation () { btTransform tr = mCollisionObject->getWorldTransform(); diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index a4afa48a1..bcbc256d0 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -70,6 +70,12 @@ namespace MWPhysics */ 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) * @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, diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 80a63bf1b..f4bf7a364 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -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) return physactor->getHalfExtents(); else 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) return physactor->getRenderingHalfExtents(); else 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 { public: @@ -1036,6 +1045,14 @@ namespace MWPhysics 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) { ObjectMap::iterator found = mObjects.find(ptr); diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 6f38653c8..7c5be0b6e 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -62,6 +62,7 @@ namespace MWPhysics void updatePtr (const MWWorld::Ptr& old, const MWWorld::Ptr& updated); Actor* getActor(const MWWorld::Ptr& ptr); + const Actor* getActor(const MWWorld::Ptr& ptr) const; // Object or Actor void remove (const MWWorld::Ptr& ptr); @@ -108,10 +109,14 @@ namespace MWPhysics bool isOnGround (const MWWorld::Ptr& 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 - 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 /// be overwritten. Valid until the next call to applyQueuedMovement. diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 45aa31065..0f8c5aa32 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -3259,8 +3259,7 @@ namespace MWWorld osg::Vec3f World::aimToTarget(const Ptr &actor, const MWWorld::Ptr& target) { osg::Vec3f weaponPos = getActorHeadPosition(actor, mRendering); - osg::Vec3f targetPos = target.getRefData().getPosition().asVec3(); - targetPos.z() += mPhysics->getHalfExtents(target).z(); + osg::Vec3f targetPos = mPhysics->getPosition(target); return (targetPos - weaponPos); } }