diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 2bc85e062..67eb0cd27 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -70,7 +70,8 @@ add_openmw_dir (mwworld ) add_openmw_dir (mwphysics - physicssystem trace collisiontype actor convert object heightfield + physicssystem trace collisiontype actor convert object heightfield closestnotmerayresultcallback + contacttestresultcallback deepestnotmecontacttestresultcallback ) add_openmw_dir (mwclass diff --git a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp new file mode 100644 index 000000000..be94128c1 --- /dev/null +++ b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp @@ -0,0 +1,45 @@ +#include "deepestnotmecontacttestresultcallback.hpp" + +#include + +#include "../mwworld/class.hpp" + +#include "ptrholder.hpp" + +namespace MWPhysics +{ + + DeepestNotMeContactTestResultCallback::DeepestNotMeContactTestResultCallback(const btCollisionObject* me, const std::vector& targets, const btVector3 &origin) + : mMe(me), mTargets(targets), mOrigin(origin), mLeastDistSqr(std::numeric_limits::max()) + { + } + + btScalar DeepestNotMeContactTestResultCallback::addSingleResult(btManifoldPoint& cp, + const btCollisionObjectWrapper* col0Wrap,int partId0,int index0, + const btCollisionObjectWrapper* col1Wrap,int partId1,int index1) + { + const btCollisionObject* collisionObject = col1Wrap->m_collisionObject; + if (collisionObject != mMe) + { + if (!mTargets.empty()) + { + if ((std::find(mTargets.begin(), mTargets.end(), collisionObject) == mTargets.end())) + { + PtrHolder* holder = static_cast(collisionObject->getUserPointer()); + if (holder && !holder->getPtr().isEmpty() && holder->getPtr().getClass().isActor()) + return 0.f; + } + } + + btScalar distsqr = mOrigin.distance2(cp.getPositionWorldOnA()); + if(!mObject || distsqr < mLeastDistSqr) + { + mObject = collisionObject; + mLeastDistSqr = distsqr; + mContactPoint = cp.getPositionWorldOnA(); + } + } + + return 0.f; + } +} diff --git a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp new file mode 100644 index 000000000..2fcef66db --- /dev/null +++ b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp @@ -0,0 +1,32 @@ +#ifndef OPENMW_MWPHYSICS_DEEPESTNOTMECONTACTTESTRESULTCALLBACK_H +#define OPENMW_MWPHYSICS_DEEPESTNOTMECONTACTTESTRESULTCALLBACK_H + +#include + +#include +#include + +namespace MWPhysics +{ + class DeepestNotMeContactTestResultCallback : public btCollisionWorld::ContactResultCallback + { + const btCollisionObject* mMe; + const std::vector mTargets; + + // Store the real origin, since the shape's origin is its center + btVector3 mOrigin; + + public: + const btCollisionObject *mObject{nullptr}; + btVector3 mContactPoint{0,0,0}; + btScalar mLeastDistSqr; + + DeepestNotMeContactTestResultCallback(const btCollisionObject* me, const std::vector& targets, const btVector3 &origin); + + virtual btScalar addSingleResult(btManifoldPoint& cp, + const btCollisionObjectWrapper* col0Wrap,int partId0,int index0, + const btCollisionObjectWrapper* col1Wrap,int partId1,int index1); + }; +} + +#endif diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 69177d95d..0ff433aa4 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -46,6 +46,7 @@ #include "object.hpp" #include "heightfield.hpp" #include "hasspherecollisioncallback.hpp" +#include "deepestnotmecontacttestresultcallback.hpp" namespace MWPhysics { @@ -646,54 +647,6 @@ namespace MWPhysics return true; } - class DeepestNotMeContactTestResultCallback : public btCollisionWorld::ContactResultCallback - { - const btCollisionObject* mMe; - const std::vector mTargets; - - // Store the real origin, since the shape's origin is its center - btVector3 mOrigin; - - public: - const btCollisionObject *mObject; - btVector3 mContactPoint; - btScalar mLeastDistSqr; - - DeepestNotMeContactTestResultCallback(const btCollisionObject* me, const std::vector& targets, const btVector3 &origin) - : mMe(me), mTargets(targets), mOrigin(origin), mObject(nullptr), mContactPoint(0,0,0), - mLeastDistSqr(std::numeric_limits::max()) - { } - - virtual btScalar addSingleResult(btManifoldPoint& cp, - const btCollisionObjectWrapper* col0Wrap,int partId0,int index0, - const btCollisionObjectWrapper* col1Wrap,int partId1,int index1) - { - const btCollisionObject* collisionObject = col1Wrap->m_collisionObject; - if (collisionObject != mMe) - { - if (!mTargets.empty()) - { - if ((std::find(mTargets.begin(), mTargets.end(), collisionObject) == mTargets.end())) - { - PtrHolder* holder = static_cast(collisionObject->getUserPointer()); - if (holder && !holder->getPtr().isEmpty() && holder->getPtr().getClass().isActor()) - return 0.f; - } - } - - btScalar distsqr = mOrigin.distance2(cp.getPositionWorldOnA()); - if(!mObject || distsqr < mLeastDistSqr) - { - mObject = collisionObject; - mLeastDistSqr = distsqr; - mContactPoint = cp.getPositionWorldOnA(); - } - } - - return 0.f; - } - }; - std::pair PhysicsSystem::getHitContact(const MWWorld::ConstPtr& actor, const osg::Vec3f &origin, const osg::Quat &orient,