mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 02:52:57 +02:00
prevent avatars from walking up vertical walls
This commit is contained in:
parent
06ff984f90
commit
819e1dc694
1 changed files with 20 additions and 9 deletions
|
@ -152,14 +152,16 @@ bool CharacterController::checkForSupport(btCollisionWorld* collisionWorld) {
|
||||||
bool hasFloor = false;
|
bool hasFloor = false;
|
||||||
const float COS_PI_OVER_THREE = cosf(PI / 3.0f);
|
const float COS_PI_OVER_THREE = cosf(PI / 3.0f);
|
||||||
|
|
||||||
btTransform transform = _rigidBody->getWorldTransform();
|
btTransform rotation = _rigidBody->getWorldTransform();
|
||||||
transform.setOrigin(btVector3(0.0f, 0.0f, 0.0f));
|
rotation.setOrigin(btVector3(0.0f, 0.0f, 0.0f)); // clear translation part
|
||||||
|
|
||||||
for (int i = 0; i < numManifolds; i++) {
|
for (int i = 0; i < numManifolds; i++) {
|
||||||
btPersistentManifold* contactManifold = dispatcher->getManifoldByIndexInternal(i);
|
btPersistentManifold* contactManifold = dispatcher->getManifoldByIndexInternal(i);
|
||||||
if (_rigidBody == contactManifold->getBody1() || _rigidBody == contactManifold->getBody0()) {
|
if (_rigidBody == contactManifold->getBody1() || _rigidBody == contactManifold->getBody0()) {
|
||||||
bool characterIsFirst = _rigidBody == contactManifold->getBody0();
|
bool characterIsFirst = _rigidBody == contactManifold->getBody0();
|
||||||
int numContacts = contactManifold->getNumContacts();
|
int numContacts = contactManifold->getNumContacts();
|
||||||
|
int stepContactIndex = -1;
|
||||||
|
float highestStep = _minStepHeight;
|
||||||
for (int j = 0; j < numContacts; j++) {
|
for (int j = 0; j < numContacts; j++) {
|
||||||
// check for "floor"
|
// check for "floor"
|
||||||
btManifoldPoint& contact = contactManifold->getContactPoint(j);
|
btManifoldPoint& contact = contactManifold->getContactPoint(j);
|
||||||
|
@ -170,12 +172,24 @@ bool CharacterController::checkForSupport(btCollisionWorld* collisionWorld) {
|
||||||
hasFloor = true;
|
hasFloor = true;
|
||||||
}
|
}
|
||||||
// remember highest step obstacle
|
// remember highest step obstacle
|
||||||
if (hitHeight > _stepHeight && hitHeight < _maxStepHeight && normal.dot(_targetVelocity) < 0.0f ) {
|
if (hitHeight > _maxStepHeight) {
|
||||||
_stepHeight = hitHeight;
|
// this manifold is invalidated by point that is too high
|
||||||
_stepPoint = transform * pointOnCharacter; // rotate into world-frame
|
stepContactIndex = -1;
|
||||||
_stepNormal = normal;
|
break;
|
||||||
|
} else if (hitHeight > highestStep && normal.dot(_targetVelocity) < 0.0f ) {
|
||||||
|
highestStep = hitHeight;
|
||||||
|
stepContactIndex = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (stepContactIndex > -1 && highestStep > _stepHeight) {
|
||||||
|
// remember step info for later
|
||||||
|
btManifoldPoint& contact = contactManifold->getContactPoint(stepContactIndex);
|
||||||
|
btVector3 pointOnCharacter = characterIsFirst ? contact.m_localPointA : contact.m_localPointB; // object-local-frame
|
||||||
|
btVector3 normal = characterIsFirst ? contact.m_normalWorldOnB : -contact.m_normalWorldOnB; // points toward character
|
||||||
|
_stepHeight = highestStep;
|
||||||
|
_stepPoint = rotation * pointOnCharacter; // rotate into world-frame
|
||||||
|
_stepNormal = normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hasFloor;
|
return hasFloor;
|
||||||
|
@ -758,9 +772,6 @@ float CharacterController::measureMaxHipsOffsetRadius(const glm::vec3& currentHi
|
||||||
startTransform.setOrigin(startPos);
|
startTransform.setOrigin(startPos);
|
||||||
btVector3 endPos = startPos + rotation * ((maxSweepDistance / hipsOffsetLength) * hipsOffset);
|
btVector3 endPos = startPos + rotation * ((maxSweepDistance / hipsOffsetLength) * hipsOffset);
|
||||||
|
|
||||||
// ensure sweep is horizontal.
|
|
||||||
startPos.setY(endPos.getY());
|
|
||||||
|
|
||||||
// sweep test a sphere
|
// sweep test a sphere
|
||||||
btSphereShape sphere(_radius);
|
btSphereShape sphere(_radius);
|
||||||
CharacterSweepResult result(&_ghost);
|
CharacterSweepResult result(&_ghost);
|
||||||
|
|
Loading…
Reference in a new issue