From 66b6328687114ff429ac00b00f0103db316ac3ab Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 10 Apr 2014 16:58:52 -0700 Subject: [PATCH 1/3] protection against bad avatar-avatar collisions Also with logging if we encounter incorrectly large penetration depths --- interface/src/avatar/MyAvatar.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7a05c593db..6c69fd3e3a 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -62,6 +62,7 @@ MyAvatar::MyAvatar() : _isThrustOn(false), _thrustMultiplier(1.0f), _moveTarget(0,0,0), + _lastBodyPenetration(0.0f), _moveTargetStepCounter(0), _lookAtTargetAvatar(), _shouldRender(true), @@ -681,7 +682,7 @@ void MyAvatar::updateThrust(float deltaTime) { _thrust -= _driveKeys[DOWN] * _scale * THRUST_MAG_DOWN * _thrustMultiplier * deltaTime * up; // attenuate thrust when in penetration - if (glm::dot(_thrust, _lastBodyPenetration) > 0.0f) { + if (glm::dot(_thrust, _lastBodyPenetration) > EPSILON) { const float MAX_BODY_PENETRATION_DEPTH = 0.6f * _skeletonModel.getBoundingShapeRadius(); float penetrationFactor = glm::min(1.0f, glm::length(_lastBodyPenetration) / MAX_BODY_PENETRATION_DEPTH); glm::vec3 penetrationDirection = glm::normalize(_lastBodyPenetration); @@ -932,7 +933,11 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) { CollisionInfo collision; if (ShapeCollider::collideShapesCoarse(myShapes, theirShapes, collision)) { - if (glm::length2(collision._penetration) > EPSILON) { + float penetrationDepth = glm::length(collision._penetration); + if (penetrationDepth > myBoundingRadius) { + qDebug() << "WARNING: ignoring avatar-avatar penetration depth " << penetrationDepth; + } + else if (penetrationDepth > EPSILON) { setPosition(getPosition() - BODY_COLLISION_RESOLUTION_FACTOR * collision._penetration); _lastBodyPenetration += collision._penetration; emit collisionWithAvatar(getSessionUUID(), avatar->getSessionUUID(), collision); From f7862eb600056e6f9955af89137281c7aac95164 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 11 Apr 2014 08:58:26 -0700 Subject: [PATCH 2/3] check for bad deltaTime during avatar-avatar collisions --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6c69fd3e3a..a716d6f49a 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -910,7 +910,7 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) { updateShapePositions(); float myBoundingRadius = getBoundingRadius(); - const float BODY_COLLISION_RESOLUTION_FACTOR = deltaTime / BODY_COLLISION_RESOLUTION_TIMESCALE; + const float BODY_COLLISION_RESOLUTION_FACTOR = glm::max(1.0f, deltaTime / BODY_COLLISION_RESOLUTION_TIMESCALE); foreach (const AvatarSharedPointer& avatarPointer, avatars) { Avatar* avatar = static_cast(avatarPointer.data()); From 508d4f216df93ee608c481c3375de2836a4c7668 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 11 Apr 2014 15:55:18 -0700 Subject: [PATCH 3/3] fix #2656 avatar jumps very far away This was caused by a bad CapsuleShape::_radius when the default CapsuleShape was used to create a default bounding capsule. The penetration against such a shape could be arbitrarily large. --- libraries/shared/src/CapsuleShape.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/shared/src/CapsuleShape.cpp b/libraries/shared/src/CapsuleShape.cpp index be3a165082..5055b3636e 100644 --- a/libraries/shared/src/CapsuleShape.cpp +++ b/libraries/shared/src/CapsuleShape.cpp @@ -17,9 +17,9 @@ // default axis of CapsuleShape is Y-axis -const glm::vec3 localAxis(0.f, 1.f, 0.f); +const glm::vec3 localAxis(0.0f, 1.0f, 0.0f); -CapsuleShape::CapsuleShape() : Shape(Shape::CAPSULE_SHAPE) {} +CapsuleShape::CapsuleShape() : Shape(Shape::CAPSULE_SHAPE), _radius(0.0f), _halfHeight(0.0f) {} CapsuleShape::CapsuleShape(float radius, float halfHeight) : Shape(Shape::CAPSULE_SHAPE), _radius(radius), _halfHeight(halfHeight) { @@ -32,13 +32,13 @@ CapsuleShape::CapsuleShape(float radius, float halfHeight, const glm::vec3& posi } CapsuleShape::CapsuleShape(float radius, const glm::vec3& startPoint, const glm::vec3& endPoint) : - Shape(Shape::CAPSULE_SHAPE), _radius(radius), _halfHeight(0.f) { + Shape(Shape::CAPSULE_SHAPE), _radius(radius), _halfHeight(0.0f) { glm::vec3 axis = endPoint - startPoint; float height = glm::length(axis); if (height > EPSILON) { _halfHeight = 0.5f * height; axis /= height; - glm::vec3 yAxis(0.f, 1.f, 0.f); + glm::vec3 yAxis(0.0f, 1.0f, 0.0f); float angle = glm::angle(axis, yAxis); if (angle > EPSILON) { axis = glm::normalize(glm::cross(yAxis, axis)); @@ -50,17 +50,17 @@ CapsuleShape::CapsuleShape(float radius, const glm::vec3& startPoint, const glm: /// \param[out] startPoint is the center of start cap void CapsuleShape::getStartPoint(glm::vec3& startPoint) const { - startPoint = getPosition() - _rotation * glm::vec3(0.f, _halfHeight, 0.f); + startPoint = getPosition() - _rotation * glm::vec3(0.0f, _halfHeight, 0.0f); } /// \param[out] endPoint is the center of the end cap void CapsuleShape::getEndPoint(glm::vec3& endPoint) const { - endPoint = getPosition() + _rotation * glm::vec3(0.f, _halfHeight, 0.f); + endPoint = getPosition() + _rotation * glm::vec3(0.0f, _halfHeight, 0.0f); } void CapsuleShape::computeNormalizedAxis(glm::vec3& axis) const { // default axis of a capsule is along the yAxis - axis = _rotation * glm::vec3(0.f, 1.f, 0.f); + axis = _rotation * glm::vec3(0.0f, 1.0f, 0.0f); } void CapsuleShape::setRadius(float radius) {