mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 19:59:28 +02:00
Merge pull request #14795 from AndrewMeadows/myAvatar-vs-backfacing-triangles-2
case 17773: reduce likelihood MyAvatar will get stuck in mesh geometry when flying around
This commit is contained in:
commit
6fd480e51d
4 changed files with 42 additions and 0 deletions
|
@ -6329,6 +6329,8 @@ void Application::update(float deltaTime) {
|
||||||
_physicsEngine->processTransaction(transaction);
|
_physicsEngine->processTransaction(transaction);
|
||||||
myAvatar->getCharacterController()->handleProcessedPhysicsTransaction(transaction);
|
myAvatar->getCharacterController()->handleProcessedPhysicsTransaction(transaction);
|
||||||
myAvatar->prepareForPhysicsSimulation();
|
myAvatar->prepareForPhysicsSimulation();
|
||||||
|
_physicsEngine->enableGlobalContactAddedCallback(myAvatar->isFlying());
|
||||||
|
|
||||||
_physicsEngine->forEachDynamic([&](EntityDynamicPointer dynamic) {
|
_physicsEngine->forEachDynamic([&](EntityDynamicPointer dynamic) {
|
||||||
dynamic->prepareForPhysicsSimulation();
|
dynamic->prepareForPhysicsSimulation();
|
||||||
});
|
});
|
||||||
|
|
|
@ -124,6 +124,11 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
|
||||||
_rigidBody->setGravity(_currentGravity * _currentUp);
|
_rigidBody->setGravity(_currentGravity * _currentUp);
|
||||||
// set flag to enable custom contactAddedCallback
|
// set flag to enable custom contactAddedCallback
|
||||||
_rigidBody->setCollisionFlags(btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
_rigidBody->setCollisionFlags(btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
||||||
|
|
||||||
|
// enable CCD
|
||||||
|
_rigidBody->setCcdSweptSphereRadius(_radius);
|
||||||
|
_rigidBody->setCcdMotionThreshold(_radius);
|
||||||
|
|
||||||
btCollisionShape* shape = _rigidBody->getCollisionShape();
|
btCollisionShape* shape = _rigidBody->getCollisionShape();
|
||||||
assert(shape && shape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE);
|
assert(shape && shape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE);
|
||||||
_ghost.setCharacterShape(static_cast<btConvexHullShape*>(shape));
|
_ghost.setCharacterShape(static_cast<btConvexHullShape*>(shape));
|
||||||
|
@ -455,6 +460,12 @@ void CharacterController::setLocalBoundingBox(const glm::vec3& minCorner, const
|
||||||
|
|
||||||
// it's ok to change offset immediately -- there are no thread safety issues here
|
// it's ok to change offset immediately -- there are no thread safety issues here
|
||||||
_shapeLocalOffset = minCorner + 0.5f * scale;
|
_shapeLocalOffset = minCorner + 0.5f * scale;
|
||||||
|
|
||||||
|
if (_rigidBody) {
|
||||||
|
// update CCD with new _radius
|
||||||
|
_rigidBody->setCcdSweptSphereRadius(_radius);
|
||||||
|
_rigidBody->setCcdMotionThreshold(_radius);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::setCollisionless(bool collisionless) {
|
void CharacterController::setCollisionless(bool collisionless) {
|
||||||
|
|
|
@ -27,6 +27,23 @@
|
||||||
#include "ThreadSafeDynamicsWorld.h"
|
#include "ThreadSafeDynamicsWorld.h"
|
||||||
#include "PhysicsLogging.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) :
|
PhysicsEngine::PhysicsEngine(const glm::vec3& offset) :
|
||||||
_originOffset(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 {
|
struct AllContactsCallback : public btCollisionWorld::ContactResultCallback {
|
||||||
AllContactsCallback(int32_t mask, int32_t group, const ShapeInfo& shapeInfo, const Transform& transform, btCollisionObject* myAvatarCollisionObject, float threshold) :
|
AllContactsCallback(int32_t mask, int32_t group, const ShapeInfo& shapeInfo, const Transform& transform, btCollisionObject* myAvatarCollisionObject, float threshold) :
|
||||||
btCollisionWorld::ContactResultCallback(),
|
btCollisionWorld::ContactResultCallback(),
|
||||||
|
|
|
@ -148,6 +148,8 @@ public:
|
||||||
// See PhysicsCollisionGroups.h for mask flags.
|
// 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;
|
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:
|
private:
|
||||||
QList<EntityDynamicPointer> removeDynamicsForBody(btRigidBody* body);
|
QList<EntityDynamicPointer> removeDynamicsForBody(btRigidBody* body);
|
||||||
void addObjectToDynamicsWorld(ObjectMotionState* motionState);
|
void addObjectToDynamicsWorld(ObjectMotionState* motionState);
|
||||||
|
|
Loading…
Reference in a new issue