Merge pull request #4544 from AndrewMeadows/inertia

fix for intermittent crash on Windows during login
This commit is contained in:
Philip Rosedale 2015-03-31 11:19:08 -07:00
commit 971108494a
3 changed files with 38 additions and 42 deletions

48
libraries/physics/src/CharacterController.cpp Normal file → Executable file
View file

@ -274,7 +274,6 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl
collisionWorld->getDispatcher()->dispatchAllCollisionPairs(_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher());
_currentPosition = _ghostObject->getWorldTransform().getOrigin();
btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS);
btVector3 currentPosition = _currentPosition;
@ -308,7 +307,7 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl
btVector3 normal = pt.m_normalWorldOnB;
normal *= directionSign; // always points from object to character
btScalar normalDotUp = normal.dot(up);
btScalar normalDotUp = normal.dot(_currentUp);
if (normalDotUp < _maxSlopeCosine) {
// this contact has a non-vertical normal... might need to ignored
btVector3 collisionPoint;
@ -319,9 +318,9 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl
}
// we do math in frame where character base is origin
btVector3 characterBase = currentPosition - (_radius + _halfHeight) * up;
btVector3 characterBase = currentPosition - (_radius + _halfHeight) * _currentUp;
collisionPoint -= characterBase;
btScalar collisionHeight = collisionPoint.dot(up);
btScalar collisionHeight = collisionPoint.dot(_currentUp);
if (collisionHeight < _lastStepUp) {
// This contact is below the lastStepUp, so we ignore it for penetration resolution,
@ -357,11 +356,10 @@ void CharacterController::scanDown(btCollisionWorld* world) {
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS);
btVector3 start = _currentPosition;
const btScalar MAX_SCAN_HEIGHT = 20.0f + _halfHeight + _radius; // closest possible floor for disabling hover
const btScalar MIN_HOVER_HEIGHT = 3.0f + _halfHeight + _radius; // distance to floor for enabling hover
btVector3 end = start - MAX_SCAN_HEIGHT * up;
btVector3 end = start - MAX_SCAN_HEIGHT * _currentUp;
world->rayTest(start, end, callback);
if (!callback.hasHit()) {
@ -377,15 +375,14 @@ void CharacterController::stepUp(btCollisionWorld* world) {
// compute start and end
btTransform start, end;
start.setIdentity();
btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS);
start.setOrigin(_currentPosition + up * (_convexShape->getMargin() + _addedMargin));
start.setOrigin(_currentPosition + _currentUp * (_convexShape->getMargin() + _addedMargin));
_targetPosition = _currentPosition + up * _stepUpHeight;
_targetPosition = _currentPosition + _currentUp * _stepUpHeight;
end.setIdentity();
end.setOrigin(_targetPosition);
// sweep up
btVector3 sweepDirNegative = - up;
btVector3 sweepDirNegative = - _currentUp;
btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.7071));
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
@ -397,7 +394,7 @@ void CharacterController::stepUp(btCollisionWorld* world) {
_verticalOffset = 0.0f;
// Only modify the position if the hit was a slope and not a wall or ceiling.
if (callback.m_hitNormalWorld.dot(up) > 0.0f) {
if (callback.m_hitNormalWorld.dot(_currentUp) > 0.0f) {
_lastStepUp = _stepUpHeight * callback.m_closestHitFraction;
_currentPosition.setInterpolate3(_currentPosition, _targetPosition, callback.m_closestHitFraction);
} else {
@ -469,8 +466,8 @@ void CharacterController::stepForward(btCollisionWorld* collisionWorld, const bt
// sweep forward
btVector3 sweepDirNegative(_currentPosition - _targetPosition);
btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.0));
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
callback.m_collisionFilterGroup = _ghostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = _ghostObject->getBroadphaseHandle()->m_collisionFilterMask;
_ghostObject->convexSweepTest(_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
if (callback.hasHit()) {
@ -502,17 +499,16 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt
// reach of the character's feet.
// first sweep for ledge
btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS);
btVector3 step = (_verticalVelocity * dt - _lastStepUp) * up;
btVector3 step = (_verticalVelocity * dt - _lastStepUp) * _currentUp;
StepDownConvexResultCallback callback(_ghostObject,
up,
_currentUp,
_currentPosition, step,
_walkDirection,
_maxSlopeCosine,
_radius, _halfHeight);
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
callback.m_collisionFilterGroup = _ghostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = _ghostObject->getBroadphaseHandle()->m_collisionFilterMask;
btTransform start, end;
start.setIdentity();
@ -532,16 +528,16 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt
_isOnGround = true;
} else if (!_isJumping) {
// sweep again for floor within downStep threshold
step = -_stepDownHeight * up;
step = -_stepDownHeight * _currentUp;
StepDownConvexResultCallback callback2 (_ghostObject,
up,
_currentUp,
_currentPosition, step,
_walkDirection,
_maxSlopeCosine,
_radius, _halfHeight);
callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
callback2.m_collisionFilterGroup = _ghostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback2.m_collisionFilterMask = _ghostObject->getBroadphaseHandle()->m_collisionFilterMask;
_currentPosition = _targetPosition;
_targetPosition = _currentPosition + step;
@ -617,10 +613,10 @@ void CharacterController::preStep(btCollisionWorld* collisionWorld) {
}
}
// the CharacterController algorithm can only change the position,
// so we don't bother to pull the rotation out of the transform
const btTransform& transform = _ghostObject->getWorldTransform();
_currentRotation = transform.getRotation();
_currentPosition = transform.getOrigin();
_targetPosition = _currentPosition;
}
void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar dt) {
@ -868,6 +864,7 @@ void CharacterController::updateShapeIfNecessary() {
void CharacterController::preSimulation(btScalar timeStep) {
if (_enabled && _dynamicsWorld) {
glm::quat rotation = _avatarData->getOrientation();
btVector3 _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS);
glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset;
btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity());
@ -895,8 +892,7 @@ void CharacterController::postSimulation() {
// cap the velocity of the step so that the character doesn't POP! so hard on steps
glm::vec3 finalStep = position - _lastPosition;
btVector3 finalVelocity = _walkDirection;
btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS);
finalVelocity += _verticalVelocity * up;
finalVelocity += _verticalVelocity * _currentUp;
const btScalar MAX_RESOLUTION_SPEED = 5.0f; // m/sec
btScalar maxStepLength = glm::max(MAX_RESOLUTION_SPEED, 2.0f * finalVelocity.length()) * _stepDt;
btScalar stepLength = glm::length(finalStep);

View file

@ -42,9 +42,22 @@ class btPairCachingGhostObject;
ATTRIBUTE_ALIGNED16(class) CharacterController : public btCharacterControllerInterface
{
protected:
///this is the desired walk direction, set by the user
btVector3 _walkDirection;
btVector3 _normalizedDirection;
//some internal variables
btVector3 _currentPosition;
btVector3 _currentUp;
btVector3 _targetPosition;
glm::vec3 _lastPosition;
btVector3 _floorNormal; // points from object to character
glm::vec3 _shapeLocalOffset;
glm::vec3 _boxScale; // used to compute capsule shape
AvatarData* _avatarData = NULL;
btPairCachingGhostObject* _ghostObject;
btPairCachingGhostObject* _ghostObject = NULL;
btConvexShape* _convexShape;//is also in _ghostObject, but it needs to be convex, so we store it here to avoid upcast
btScalar _radius;
@ -64,22 +77,12 @@ protected:
btScalar _addedMargin;//@todo: remove this and fix the code
///this is the desired walk direction, set by the user
btVector3 _walkDirection;
btVector3 _normalizedDirection;
//some internal variables
btVector3 _currentPosition;
btQuaternion _currentRotation;
btVector3 _targetPosition;
glm::vec3 _lastPosition;
btScalar _lastStepUp;
///keep track of the contact manifolds
btManifoldArray _manifoldArray;
bool _touchingContact;
btVector3 _floorNormal; // points from object to character
bool _enabled;
bool _isOnGround;
@ -90,9 +93,6 @@ protected:
btScalar _stepDt;
uint32_t _pendingFlags;
glm::vec3 _shapeLocalOffset;
glm::vec3 _boxScale; // used to compute capsule shape
btDynamicsWorld* _dynamicsWorld = NULL;
btVector3 computeReflectionDirection(const btVector3& direction, const btVector3& normal);

View file

@ -36,8 +36,8 @@ PhysicsEngine::~PhysicsEngine() {
delete _collisionDispatcher;
delete _broadphaseFilter;
delete _constraintSolver;
// delete _dynamicsWorld;
// delete _ghostPairCallback;
delete _dynamicsWorld;
delete _ghostPairCallback;
}
// begin EntitySimulation overrides