mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 12:28:02 +02:00
Merge pull request #6936 from hyperlogic/tony/prevent-hover-over-cracks
CharacterController: Improve ground support detection
This commit is contained in:
commit
e2e7a60c0f
2 changed files with 29 additions and 2 deletions
|
@ -60,6 +60,7 @@ CharacterController::CharacterController() {
|
||||||
_followTime = 0.0f;
|
_followTime = 0.0f;
|
||||||
_followLinearDisplacement = btVector3(0, 0, 0);
|
_followLinearDisplacement = btVector3(0, 0, 0);
|
||||||
_followAngularDisplacement = btQuaternion::getIdentity();
|
_followAngularDisplacement = btQuaternion::getIdentity();
|
||||||
|
_hasSupport = false;
|
||||||
|
|
||||||
_pendingFlags = PENDING_FLAG_UPDATE_SHAPE;
|
_pendingFlags = PENDING_FLAG_UPDATE_SHAPE;
|
||||||
|
|
||||||
|
@ -106,6 +107,28 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CharacterController::checkForSupport(btCollisionWorld* collisionWorld) const {
|
||||||
|
int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
|
||||||
|
for (int i = 0; i < numManifolds; i++) {
|
||||||
|
btPersistentManifold* contactManifold = collisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
|
||||||
|
const btCollisionObject* obA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
|
||||||
|
const btCollisionObject* obB = static_cast<const btCollisionObject*>(contactManifold->getBody1());
|
||||||
|
if (obA == _rigidBody || obB == _rigidBody) {
|
||||||
|
int numContacts = contactManifold->getNumContacts();
|
||||||
|
for (int j = 0; j < numContacts; j++) {
|
||||||
|
btManifoldPoint& pt = contactManifold->getContactPoint(j);
|
||||||
|
|
||||||
|
// check to see if contact point is touching the bottom sphere of the capsule.
|
||||||
|
float contactPointY = (obA == _rigidBody) ? pt.m_localPointA.getY() : pt.m_localPointB.getY();
|
||||||
|
if (contactPointY < -_halfHeight) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void CharacterController::preStep(btCollisionWorld* collisionWorld) {
|
void CharacterController::preStep(btCollisionWorld* collisionWorld) {
|
||||||
// trace a ray straight down to see if we're standing on the ground
|
// trace a ray straight down to see if we're standing on the ground
|
||||||
const btTransform& xform = _rigidBody->getWorldTransform();
|
const btTransform& xform = _rigidBody->getWorldTransform();
|
||||||
|
@ -125,6 +148,8 @@ void CharacterController::preStep(btCollisionWorld* collisionWorld) {
|
||||||
if (rayCallback.hasHit()) {
|
if (rayCallback.hasHit()) {
|
||||||
_floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
|
_floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hasSupport = checkForSupport(collisionWorld);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
|
void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
|
||||||
|
@ -248,7 +273,7 @@ void CharacterController::jump() {
|
||||||
|
|
||||||
bool CharacterController::onGround() const {
|
bool CharacterController::onGround() const {
|
||||||
const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius;
|
const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius;
|
||||||
return _floorDistance < FLOOR_PROXIMITY_THRESHOLD;
|
return _floorDistance < FLOOR_PROXIMITY_THRESHOLD || _hasSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::setHovering(bool hover) {
|
void CharacterController::setHovering(bool hover) {
|
||||||
|
@ -400,7 +425,7 @@ void CharacterController::preSimulation() {
|
||||||
if (_floorDistance < JUMP_PROXIMITY_THRESHOLD) {
|
if (_floorDistance < JUMP_PROXIMITY_THRESHOLD) {
|
||||||
_isJumping = false;
|
_isJumping = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!_hasSupport) {
|
||||||
_floorDistance = FLT_MAX;
|
_floorDistance = FLT_MAX;
|
||||||
setHovering(true);
|
setHovering(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateUpAxis(const glm::quat& rotation);
|
void updateUpAxis(const glm::quat& rotation);
|
||||||
|
bool checkForSupport(btCollisionWorld* collisionWorld) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
btVector3 _currentUp;
|
btVector3 _currentUp;
|
||||||
|
@ -104,6 +105,7 @@ protected:
|
||||||
btScalar _radius;
|
btScalar _radius;
|
||||||
|
|
||||||
btScalar _floorDistance;
|
btScalar _floorDistance;
|
||||||
|
bool _hasSupport;
|
||||||
|
|
||||||
btScalar _gravity;
|
btScalar _gravity;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue