mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 19:10:49 +02:00
Merge pull request #2651 from AndrewMeadows/avatar-interaction
protection against bad avatar-avatar collisions
This commit is contained in:
commit
e3eddadd10
2 changed files with 15 additions and 10 deletions
|
@ -62,6 +62,7 @@ MyAvatar::MyAvatar() :
|
||||||
_isThrustOn(false),
|
_isThrustOn(false),
|
||||||
_thrustMultiplier(1.0f),
|
_thrustMultiplier(1.0f),
|
||||||
_moveTarget(0,0,0),
|
_moveTarget(0,0,0),
|
||||||
|
_lastBodyPenetration(0.0f),
|
||||||
_moveTargetStepCounter(0),
|
_moveTargetStepCounter(0),
|
||||||
_lookAtTargetAvatar(),
|
_lookAtTargetAvatar(),
|
||||||
_shouldRender(true),
|
_shouldRender(true),
|
||||||
|
@ -681,7 +682,7 @@ void MyAvatar::updateThrust(float deltaTime) {
|
||||||
_thrust -= _driveKeys[DOWN] * _scale * THRUST_MAG_DOWN * _thrustMultiplier * deltaTime * up;
|
_thrust -= _driveKeys[DOWN] * _scale * THRUST_MAG_DOWN * _thrustMultiplier * deltaTime * up;
|
||||||
|
|
||||||
// attenuate thrust when in penetration
|
// 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();
|
const float MAX_BODY_PENETRATION_DEPTH = 0.6f * _skeletonModel.getBoundingShapeRadius();
|
||||||
float penetrationFactor = glm::min(1.0f, glm::length(_lastBodyPenetration) / MAX_BODY_PENETRATION_DEPTH);
|
float penetrationFactor = glm::min(1.0f, glm::length(_lastBodyPenetration) / MAX_BODY_PENETRATION_DEPTH);
|
||||||
glm::vec3 penetrationDirection = glm::normalize(_lastBodyPenetration);
|
glm::vec3 penetrationDirection = glm::normalize(_lastBodyPenetration);
|
||||||
|
@ -909,7 +910,7 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) {
|
||||||
updateShapePositions();
|
updateShapePositions();
|
||||||
float myBoundingRadius = getBoundingRadius();
|
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) {
|
foreach (const AvatarSharedPointer& avatarPointer, avatars) {
|
||||||
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
||||||
|
@ -932,7 +933,11 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) {
|
||||||
|
|
||||||
CollisionInfo collision;
|
CollisionInfo collision;
|
||||||
if (ShapeCollider::collideShapesCoarse(myShapes, theirShapes, 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);
|
setPosition(getPosition() - BODY_COLLISION_RESOLUTION_FACTOR * collision._penetration);
|
||||||
_lastBodyPenetration += collision._penetration;
|
_lastBodyPenetration += collision._penetration;
|
||||||
emit collisionWithAvatar(getSessionUUID(), avatar->getSessionUUID(), collision);
|
emit collisionWithAvatar(getSessionUUID(), avatar->getSessionUUID(), collision);
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
|
|
||||||
|
|
||||||
// default axis of CapsuleShape is Y-axis
|
// 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),
|
CapsuleShape::CapsuleShape(float radius, float halfHeight) : Shape(Shape::CAPSULE_SHAPE),
|
||||||
_radius(radius), _halfHeight(halfHeight) {
|
_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) :
|
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;
|
glm::vec3 axis = endPoint - startPoint;
|
||||||
float height = glm::length(axis);
|
float height = glm::length(axis);
|
||||||
if (height > EPSILON) {
|
if (height > EPSILON) {
|
||||||
_halfHeight = 0.5f * height;
|
_halfHeight = 0.5f * height;
|
||||||
axis /= 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);
|
float angle = glm::angle(axis, yAxis);
|
||||||
if (angle > EPSILON) {
|
if (angle > EPSILON) {
|
||||||
axis = glm::normalize(glm::cross(yAxis, axis));
|
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
|
/// \param[out] startPoint is the center of start cap
|
||||||
void CapsuleShape::getStartPoint(glm::vec3& startPoint) const {
|
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
|
/// \param[out] endPoint is the center of the end cap
|
||||||
void CapsuleShape::getEndPoint(glm::vec3& endPoint) const {
|
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 {
|
void CapsuleShape::computeNormalizedAxis(glm::vec3& axis) const {
|
||||||
// default axis of a capsule is along the yAxis
|
// 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) {
|
void CapsuleShape::setRadius(float radius) {
|
||||||
|
|
Loading…
Reference in a new issue