2015-05-12 01:02:15 +00:00
|
|
|
#include "trace.h"
|
|
|
|
|
2019-02-28 20:03:42 +00:00
|
|
|
#include <components/misc/convert.hpp>
|
|
|
|
|
2015-05-27 21:09:38 +00:00
|
|
|
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
2015-05-27 20:32:11 +00:00
|
|
|
#include <BulletCollision/CollisionShapes/btConvexShape.h>
|
2015-05-12 01:02:15 +00:00
|
|
|
|
|
|
|
#include "collisiontype.hpp"
|
|
|
|
#include "actor.hpp"
|
|
|
|
|
|
|
|
namespace MWPhysics
|
|
|
|
{
|
|
|
|
|
|
|
|
class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
|
|
|
|
{
|
|
|
|
public:
|
2020-03-30 18:23:41 +00:00
|
|
|
ClosestNotMeConvexResultCallback(const btCollisionObject *me, const btVector3 &motion, btScalar minCollisionDot)
|
2015-05-12 01:02:15 +00:00
|
|
|
: btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)),
|
2020-03-30 18:23:41 +00:00
|
|
|
mMe(me), mMotion(motion), mMinCollisionDot(minCollisionDot)
|
2015-05-12 01:02:15 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
|
|
|
|
{
|
|
|
|
if(convexResult.m_hitCollisionObject == mMe)
|
|
|
|
return btScalar( 1 );
|
|
|
|
|
|
|
|
btVector3 hitNormalWorld;
|
|
|
|
if(normalInWorldSpace)
|
|
|
|
hitNormalWorld = convexResult.m_hitNormalLocal;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
///need to transform normal into worldspace
|
|
|
|
hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
|
|
|
|
}
|
|
|
|
|
2020-03-30 18:23:41 +00:00
|
|
|
// dot product of the motion vector against the collision contact normal
|
|
|
|
btScalar dotCollision = mMotion.dot(hitNormalWorld);
|
|
|
|
if(dotCollision <= mMinCollisionDot)
|
2015-05-12 01:02:15 +00:00
|
|
|
return btScalar(1);
|
|
|
|
|
|
|
|
return ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2016-03-05 15:09:56 +00:00
|
|
|
const btCollisionObject *mMe;
|
2020-03-30 18:23:41 +00:00
|
|
|
const btVector3 mMotion;
|
|
|
|
const btScalar mMinCollisionDot;
|
2015-05-12 01:02:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-03-05 15:09:56 +00:00
|
|
|
void ActorTracer::doTrace(const btCollisionObject *actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world)
|
2015-05-12 01:02:15 +00:00
|
|
|
{
|
2019-02-28 20:03:42 +00:00
|
|
|
const btVector3 btstart = Misc::Convert::toBullet(start);
|
|
|
|
const btVector3 btend = Misc::Convert::toBullet(end);
|
2015-05-12 01:02:15 +00:00
|
|
|
|
|
|
|
const btTransform &trans = actor->getWorldTransform();
|
|
|
|
btTransform from(trans);
|
|
|
|
btTransform to(trans);
|
|
|
|
from.setOrigin(btstart);
|
|
|
|
to.setOrigin(btend);
|
|
|
|
|
2020-03-30 18:23:41 +00:00
|
|
|
const btVector3 motion = btstart-btend;
|
|
|
|
ClosestNotMeConvexResultCallback newTraceCallback(actor, motion, btScalar(0.0));
|
2015-05-12 01:02:15 +00:00
|
|
|
// Inherit the actor's collision group and mask
|
|
|
|
newTraceCallback.m_collisionFilterGroup = actor->getBroadphaseHandle()->m_collisionFilterGroup;
|
|
|
|
newTraceCallback.m_collisionFilterMask = actor->getBroadphaseHandle()->m_collisionFilterMask;
|
|
|
|
|
2016-03-05 15:09:56 +00:00
|
|
|
const btCollisionShape *shape = actor->getCollisionShape();
|
2015-05-12 01:02:15 +00:00
|
|
|
assert(shape->isConvex());
|
2020-03-30 18:23:41 +00:00
|
|
|
world->convexSweepTest(static_cast<const btConvexShape*>(shape), from, to, newTraceCallback);
|
2015-05-12 01:02:15 +00:00
|
|
|
|
|
|
|
// Copy the hit data over to our trace results struct:
|
|
|
|
if(newTraceCallback.hasHit())
|
|
|
|
{
|
|
|
|
mFraction = newTraceCallback.m_closestHitFraction;
|
2020-03-30 18:23:41 +00:00
|
|
|
mPlaneNormal = Misc::Convert::toOsg(newTraceCallback.m_hitNormalWorld);
|
2015-05-12 01:02:15 +00:00
|
|
|
mEndPos = (end-start)*mFraction + start;
|
2019-02-28 20:03:42 +00:00
|
|
|
mHitPoint = Misc::Convert::toOsg(newTraceCallback.m_hitPointWorld);
|
2015-05-12 01:02:15 +00:00
|
|
|
mHitObject = newTraceCallback.m_hitCollisionObject;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mEndPos = end;
|
|
|
|
mPlaneNormal = osg::Vec3f(0.0f, 0.0f, 1.0f);
|
|
|
|
mFraction = 1.0f;
|
2016-12-24 22:07:44 +00:00
|
|
|
mHitPoint = end;
|
2018-10-09 06:21:12 +00:00
|
|
|
mHitObject = nullptr;
|
2015-05-12 01:02:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-05 15:09:56 +00:00
|
|
|
void ActorTracer::findGround(const Actor* actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world)
|
2015-05-12 01:02:15 +00:00
|
|
|
{
|
2020-03-30 18:23:41 +00:00
|
|
|
const btVector3 btstart = Misc::Convert::toBullet(start);
|
|
|
|
const btVector3 btend = Misc::Convert::toBullet(end);
|
2015-05-12 01:02:15 +00:00
|
|
|
|
|
|
|
const btTransform &trans = actor->getCollisionObject()->getWorldTransform();
|
|
|
|
btTransform from(trans.getBasis(), btstart);
|
|
|
|
btTransform to(trans.getBasis(), btend);
|
|
|
|
|
2020-03-30 18:23:41 +00:00
|
|
|
const btVector3 motion = btstart-btend;
|
|
|
|
ClosestNotMeConvexResultCallback newTraceCallback(actor->getCollisionObject(), motion, btScalar(0.0));
|
2015-05-12 01:02:15 +00:00
|
|
|
// Inherit the actor's collision group and mask
|
|
|
|
newTraceCallback.m_collisionFilterGroup = actor->getCollisionObject()->getBroadphaseHandle()->m_collisionFilterGroup;
|
|
|
|
newTraceCallback.m_collisionFilterMask = actor->getCollisionObject()->getBroadphaseHandle()->m_collisionFilterMask;
|
|
|
|
newTraceCallback.m_collisionFilterMask &= ~CollisionType_Actor;
|
|
|
|
|
2017-02-10 00:58:27 +00:00
|
|
|
world->convexSweepTest(actor->getConvexShape(), from, to, newTraceCallback);
|
2015-05-12 01:02:15 +00:00
|
|
|
if(newTraceCallback.hasHit())
|
|
|
|
{
|
|
|
|
mFraction = newTraceCallback.m_closestHitFraction;
|
2020-03-30 18:23:41 +00:00
|
|
|
mPlaneNormal = Misc::Convert::toOsg(newTraceCallback.m_hitNormalWorld);
|
2015-05-12 01:02:15 +00:00
|
|
|
mEndPos = (end-start)*mFraction + start;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mEndPos = end;
|
|
|
|
mPlaneNormal = osg::Vec3f(0.0f, 0.0f, 1.0f);
|
|
|
|
mFraction = 1.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|