Use the actor's collision shape in findGround()

The cylinder base is no longer appropriate as of the change to capsules.

This also works around a bug when tracing a small cylinder/box shape apparently introduced with bullet 2.86.
This commit is contained in:
scrawl 2017-02-10 01:58:27 +01:00
parent 67e4a7e37b
commit b3d5c2bd7f
4 changed files with 7 additions and 8 deletions

View file

@ -35,6 +35,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr<const Resource::BulletShape>
} }
else else
mShape.reset(new btBoxShape(toBullet(mHalfExtents))); mShape.reset(new btBoxShape(toBullet(mHalfExtents)));
mConvexShape = static_cast<btConvexShape*>(mShape.get());
mCollisionObject.reset(new btCollisionObject); mCollisionObject.reset(new btCollisionObject);
mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);

View file

@ -12,6 +12,7 @@
class btCollisionWorld; class btCollisionWorld;
class btCollisionShape; class btCollisionShape;
class btCollisionObject; class btCollisionObject;
class btConvexShape;
namespace Resource namespace Resource
{ {
@ -61,6 +62,8 @@ namespace MWPhysics
return mInternalCollisionMode; return mInternalCollisionMode;
} }
btConvexShape* getConvexShape() const { return mConvexShape; }
/** /**
* Enables or disables the *external* collision body. If disabled, other actors will not collide with this actor. * Enables or disables the *external* collision body. If disabled, other actors will not collide with this actor.
*/ */
@ -153,6 +156,7 @@ namespace MWPhysics
bool mWalkingOnWater; bool mWalkingOnWater;
std::auto_ptr<btCollisionShape> mShape; std::auto_ptr<btCollisionShape> mShape;
btConvexShape* mConvexShape;
std::auto_ptr<btCollisionObject> mCollisionObject; std::auto_ptr<btCollisionObject> mCollisionObject;

View file

@ -239,7 +239,7 @@ namespace MWPhysics
public: public:
static osg::Vec3f traceDown(const MWWorld::Ptr &ptr, Actor* actor, btCollisionWorld* collisionWorld, float maxHeight) static osg::Vec3f traceDown(const MWWorld::Ptr &ptr, Actor* actor, btCollisionWorld* collisionWorld, float maxHeight)
{ {
osg::Vec3f position(ptr.getRefData().getPosition().asVec3()); osg::Vec3f position(actor->getCollisionObjectPosition());
ActorTracer tracer; ActorTracer tracer;
tracer.findGround(actor, position, position-osg::Vec3f(0,0,maxHeight), collisionWorld); tracer.findGround(actor, position, position-osg::Vec3f(0,0,maxHeight), collisionWorld);

View file

@ -4,7 +4,6 @@
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h> #include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
#include <BulletCollision/CollisionShapes/btConvexShape.h> #include <BulletCollision/CollisionShapes/btConvexShape.h>
#include <BulletCollision/CollisionShapes/btCylinderShape.h>
#include "collisiontype.hpp" #include "collisiontype.hpp"
#include "actor.hpp" #include "actor.hpp"
@ -106,12 +105,7 @@ void ActorTracer::findGround(const Actor* actor, const osg::Vec3f& start, const
newTraceCallback.m_collisionFilterMask = actor->getCollisionObject()->getBroadphaseHandle()->m_collisionFilterMask; newTraceCallback.m_collisionFilterMask = actor->getCollisionObject()->getBroadphaseHandle()->m_collisionFilterMask;
newTraceCallback.m_collisionFilterMask &= ~CollisionType_Actor; newTraceCallback.m_collisionFilterMask &= ~CollisionType_Actor;
btVector3 halfExtents = toBullet(actor->getHalfExtents()); world->convexSweepTest(actor->getConvexShape(), from, to, newTraceCallback);
halfExtents[2] = 1.0f;
btCylinderShapeZ base(halfExtents);
world->convexSweepTest(&base, from, to, newTraceCallback);
if(newTraceCallback.hasHit()) if(newTraceCallback.hasHit())
{ {
const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld; const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld;