1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-30 07:21:12 +00:00

Port wareya's actor tracer consistency fixes

This commit is contained in:
Capostrophic 2020-03-30 21:23:41 +03:00
parent 4bb41a52bf
commit 1629791885

View File

@ -14,9 +14,9 @@ namespace MWPhysics
class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
{ {
public: public:
ClosestNotMeConvexResultCallback(const btCollisionObject *me, const btVector3 &up, btScalar minSlopeDot) ClosestNotMeConvexResultCallback(const btCollisionObject *me, const btVector3 &motion, btScalar minCollisionDot)
: btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)), : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)),
mMe(me), mUp(up), mMinSlopeDot(minSlopeDot) mMe(me), mMotion(motion), mMinCollisionDot(minCollisionDot)
{ {
} }
@ -34,8 +34,9 @@ public:
hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
} }
btScalar dotUp = mUp.dot(hitNormalWorld); // dot product of the motion vector against the collision contact normal
if(dotUp < mMinSlopeDot) btScalar dotCollision = mMotion.dot(hitNormalWorld);
if(dotCollision <= mMinCollisionDot)
return btScalar(1); return btScalar(1);
return ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace); return ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
@ -43,8 +44,8 @@ public:
protected: protected:
const btCollisionObject *mMe; const btCollisionObject *mMe;
const btVector3 mUp; const btVector3 mMotion;
const btScalar mMinSlopeDot; const btScalar mMinCollisionDot;
}; };
@ -59,22 +60,21 @@ void ActorTracer::doTrace(const btCollisionObject *actor, const osg::Vec3f& star
from.setOrigin(btstart); from.setOrigin(btstart);
to.setOrigin(btend); to.setOrigin(btend);
ClosestNotMeConvexResultCallback newTraceCallback(actor, btstart-btend, btScalar(0.0)); const btVector3 motion = btstart-btend;
ClosestNotMeConvexResultCallback newTraceCallback(actor, motion, btScalar(0.0));
// Inherit the actor's collision group and mask // Inherit the actor's collision group and mask
newTraceCallback.m_collisionFilterGroup = actor->getBroadphaseHandle()->m_collisionFilterGroup; newTraceCallback.m_collisionFilterGroup = actor->getBroadphaseHandle()->m_collisionFilterGroup;
newTraceCallback.m_collisionFilterMask = actor->getBroadphaseHandle()->m_collisionFilterMask; newTraceCallback.m_collisionFilterMask = actor->getBroadphaseHandle()->m_collisionFilterMask;
const btCollisionShape *shape = actor->getCollisionShape(); const btCollisionShape *shape = actor->getCollisionShape();
assert(shape->isConvex()); assert(shape->isConvex());
world->convexSweepTest(static_cast<const btConvexShape*>(shape), world->convexSweepTest(static_cast<const btConvexShape*>(shape), from, to, newTraceCallback);
from, to, newTraceCallback);
// Copy the hit data over to our trace results struct: // Copy the hit data over to our trace results struct:
if(newTraceCallback.hasHit()) if(newTraceCallback.hasHit())
{ {
const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld;
mFraction = newTraceCallback.m_closestHitFraction; mFraction = newTraceCallback.m_closestHitFraction;
mPlaneNormal = osg::Vec3f(tracehitnormal.x(), tracehitnormal.y(), tracehitnormal.z()); mPlaneNormal = Misc::Convert::toOsg(newTraceCallback.m_hitNormalWorld);
mEndPos = (end-start)*mFraction + start; mEndPos = (end-start)*mFraction + start;
mHitPoint = Misc::Convert::toOsg(newTraceCallback.m_hitPointWorld); mHitPoint = Misc::Convert::toOsg(newTraceCallback.m_hitPointWorld);
mHitObject = newTraceCallback.m_hitCollisionObject; mHitObject = newTraceCallback.m_hitCollisionObject;
@ -91,14 +91,15 @@ void ActorTracer::doTrace(const btCollisionObject *actor, const osg::Vec3f& star
void ActorTracer::findGround(const Actor* actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world) void ActorTracer::findGround(const Actor* actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world)
{ {
const btVector3 btstart(start.x(), start.y(), start.z()); const btVector3 btstart = Misc::Convert::toBullet(start);
const btVector3 btend(end.x(), end.y(), end.z()); const btVector3 btend = Misc::Convert::toBullet(end);
const btTransform &trans = actor->getCollisionObject()->getWorldTransform(); const btTransform &trans = actor->getCollisionObject()->getWorldTransform();
btTransform from(trans.getBasis(), btstart); btTransform from(trans.getBasis(), btstart);
btTransform to(trans.getBasis(), btend); btTransform to(trans.getBasis(), btend);
ClosestNotMeConvexResultCallback newTraceCallback(actor->getCollisionObject(), btstart-btend, btScalar(0.0)); const btVector3 motion = btstart-btend;
ClosestNotMeConvexResultCallback newTraceCallback(actor->getCollisionObject(), motion, btScalar(0.0));
// Inherit the actor's collision group and mask // Inherit the actor's collision group and mask
newTraceCallback.m_collisionFilterGroup = actor->getCollisionObject()->getBroadphaseHandle()->m_collisionFilterGroup; newTraceCallback.m_collisionFilterGroup = actor->getCollisionObject()->getBroadphaseHandle()->m_collisionFilterGroup;
newTraceCallback.m_collisionFilterMask = actor->getCollisionObject()->getBroadphaseHandle()->m_collisionFilterMask; newTraceCallback.m_collisionFilterMask = actor->getCollisionObject()->getBroadphaseHandle()->m_collisionFilterMask;
@ -107,9 +108,8 @@ void ActorTracer::findGround(const Actor* actor, const osg::Vec3f& start, const
world->convexSweepTest(actor->getConvexShape(), from, to, newTraceCallback); world->convexSweepTest(actor->getConvexShape(), from, to, newTraceCallback);
if(newTraceCallback.hasHit()) if(newTraceCallback.hasHit())
{ {
const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld;
mFraction = newTraceCallback.m_closestHitFraction; mFraction = newTraceCallback.m_closestHitFraction;
mPlaneNormal = osg::Vec3f(tracehitnormal.x(), tracehitnormal.y(), tracehitnormal.z()); mPlaneNormal = Misc::Convert::toOsg(newTraceCallback.m_hitNormalWorld);
mEndPos = (end-start)*mFraction + start; mEndPos = (end-start)*mFraction + start;
} }
else else