MyAvatar RigidBody ignores backfacing triangles

This commit is contained in:
Andrew Meadows 2018-07-27 17:20:37 -07:00
parent e9f23a43f6
commit 49a1d0a18a
2 changed files with 28 additions and 3 deletions

View file

@ -121,6 +121,8 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
_dynamicsWorld->addAction(this);
// restore gravity settings because adding an object to the world overwrites its gravity setting
_rigidBody->setGravity(_currentGravity * _currentUp);
// set flag to enable custom contactAddedCallback
_rigidBody->setCollisionFlags(btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
btCollisionShape* shape = _rigidBody->getCollisionShape();
assert(shape && shape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE);
_ghost.setCharacterShape(static_cast<btConvexHullShape*>(shape));
@ -294,14 +296,14 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar
// compute the angle we will resolve for this dt, but don't overshoot
float angle = 2.0f * acosf(qDot);
if ( dt < _followTimeRemaining) {
if (dt < _followTimeRemaining) {
angle *= dt / _followTimeRemaining;
}
// accumulate rotation
deltaRot = btQuaternion(axis, angle);
_followAngularDisplacement = (deltaRot * _followAngularDisplacement).normalize();
// in order to accumulate displacement of avatar position, we need to take _shapeLocalOffset into account.
btVector3 shapeLocalOffset = glmToBullet(_shapeLocalOffset);

View file

@ -18,6 +18,7 @@
#include <PerfStat.h>
#include <PhysicsCollisionGroups.h>
#include <Profile.h>
#include <BulletCollision/CollisionShapes/btTriangleShape.h>
#include "CharacterController.h"
#include "ObjectMotionState.h"
@ -26,6 +27,25 @@
#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),
_myAvatarController(nullptr) {
@ -68,6 +88,9 @@ void PhysicsEngine::init() {
// in order for its broadphase collision queries to work correctly. Look at how we use
// _activeStaticBodies to track and update the Aabb's of moved static objects.
_dynamicsWorld->setForceUpdateAllAabbs(false);
// register contact filter to help MyAvatar pass through backfacing triangles
gContactAddedCallback = flipNormalsMyAvatarVsBackfacingTriangles;
}
}