disable bf triangle collisions for flying MyAvatar

This commit is contained in:
Andrew Meadows 2019-01-29 11:00:18 -08:00
parent faeb5b36dc
commit fb5ef95a5b
3 changed files with 31 additions and 0 deletions

View file

@ -6289,6 +6289,8 @@ void Application::update(float deltaTime) {
avatarManager->handleProcessedPhysicsTransaction(transaction);
myAvatar->prepareForPhysicsSimulation();
_physicsEngine->enableGlobalContactAddedCallback(myAvatar->isFlying());
_physicsEngine->forEachDynamic([&](EntityDynamicPointer dynamic) {
dynamic->prepareForPhysicsSimulation();
});

View file

@ -27,6 +27,23 @@
#include "ThreadSafeDynamicsWorld.h"
#include "PhysicsLogging.h"
static bool flipNormalsMyAvatarVsBackfacingTriangles(btManifoldPoint& cp,
const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0,
const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1) {
if (colObj1Wrap->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE) {
auto triShape = static_cast<const btTriangleShape*>(colObj1Wrap->getCollisionShape());
const btVector3* v = triShape->m_vertices1;
btVector3 faceNormal = colObj1Wrap->getWorldTransform().getBasis() * btCross(v[1] - v[0], v[2] - v[0]);
float nDotF = btDot(faceNormal, cp.m_normalWorldOnB);
if (nDotF <= 0.0f) {
faceNormal.normalize();
// flip the contact normal to be aligned with the face normal
cp.m_normalWorldOnB += -2.0f * nDotF * faceNormal;
}
}
// return value is currently ignored but to be future-proof: return false when not modifying friction
return false;
}
PhysicsEngine::PhysicsEngine(const glm::vec3& offset) :
_originOffset(offset),
@ -904,6 +921,16 @@ void PhysicsEngine::setShowBulletConstraintLimits(bool value) {
}
}
void PhysicsEngine::enableGlobalContactAddedCallback(bool enabled) {
if (enabled) {
// register contact filter to help MyAvatar pass through backfacing triangles
gContactAddedCallback = flipNormalsMyAvatarVsBackfacingTriangles;
} else {
// deregister contact filter
gContactAddedCallback = nullptr;
}
}
struct AllContactsCallback : public btCollisionWorld::ContactResultCallback {
AllContactsCallback(int32_t mask, int32_t group, const ShapeInfo& shapeInfo, const Transform& transform, btCollisionObject* myAvatarCollisionObject, float threshold) :
btCollisionWorld::ContactResultCallback(),

View file

@ -148,6 +148,8 @@ public:
// See PhysicsCollisionGroups.h for mask flags.
std::vector<ContactTestResult> contactTest(uint16_t mask, const ShapeInfo& regionShapeInfo, const Transform& regionTransform, uint16_t group = USER_COLLISION_GROUP_DYNAMIC, float threshold = 0.0f) const;
void enableGlobalContactAddedCallback(bool enabled);
private:
QList<EntityDynamicPointer> removeDynamicsForBody(btRigidBody* body);
void addObjectToDynamicsWorld(ObjectMotionState* motionState);