From 55056e730a939a0a499adc7a99bd6ca3fae8e815 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 8 May 2017 17:02:37 -0700 Subject: [PATCH] guard slider and cone-twist constraints against zero-length axisq --- .../physics/src/ObjectConstraintConeTwist.cpp | 26 ++++++++++++++----- .../physics/src/ObjectConstraintSlider.cpp | 26 ++++++++++++++----- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/libraries/physics/src/ObjectConstraintConeTwist.cpp b/libraries/physics/src/ObjectConstraintConeTwist.cpp index 57950b4ce0..900e1b894a 100644 --- a/libraries/physics/src/ObjectConstraintConeTwist.cpp +++ b/libraries/physics/src/ObjectConstraintConeTwist.cpp @@ -17,12 +17,12 @@ const uint16_t ObjectConstraintConeTwist::constraintVersion = 1; - +const glm::vec3 DEFAULT_CONE_TWIST_AXIS(1.0f, 0.0f, 0.0f); ObjectConstraintConeTwist::ObjectConstraintConeTwist(const QUuid& id, EntityItemPointer ownerEntity) : ObjectConstraint(DYNAMIC_TYPE_CONE_TWIST, id, ownerEntity), - _pivotInA(glm::vec3(0.0f)), - _axisInA(glm::vec3(0.0f)) + _axisInA(DEFAULT_CONE_TWIST_AXIS), + _axisInB(DEFAULT_CONE_TWIST_AXIS) { #if WANT_DEBUG qCDebug(physics) << "ObjectConstraintConeTwist::ObjectConstraintConeTwist"; @@ -109,11 +109,25 @@ btTypedConstraint* ObjectConstraintConeTwist::getConstraint() { return nullptr; } + if (glm::length(axisInA) < FLT_EPSILON) { + qCWarning(physics) << "cone-twist axis cannot be a zero vector"; + axisInA = DEFAULT_CONE_TWIST_AXIS; + } else { + axisInA = glm::normalize(axisInA); + } + if (!otherEntityID.isNull()) { // This coneTwist is between two entities... find the other rigid body. - glm::quat rotA = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInA)); - glm::quat rotB = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInB)); + if (glm::length(axisInB) < FLT_EPSILON) { + qCWarning(physics) << "cone-twist axis cannot be a zero vector"; + axisInB = DEFAULT_CONE_TWIST_AXIS; + } else { + axisInB = glm::normalize(axisInB); + } + + glm::quat rotA = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), axisInA); + glm::quat rotB = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), axisInB); btTransform frameInA(glmToBullet(rotA), glmToBullet(pivotInA)); btTransform frameInB(glmToBullet(rotB), glmToBullet(pivotInB)); @@ -127,7 +141,7 @@ btTypedConstraint* ObjectConstraintConeTwist::getConstraint() { } else { // This coneTwist is between an entity and the world-frame. - glm::quat rot = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInA)); + glm::quat rot = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), axisInA); btTransform frameInA(glmToBullet(rot), glmToBullet(pivotInA)); diff --git a/libraries/physics/src/ObjectConstraintSlider.cpp b/libraries/physics/src/ObjectConstraintSlider.cpp index 6e092b40a0..d8f42a1cbe 100644 --- a/libraries/physics/src/ObjectConstraintSlider.cpp +++ b/libraries/physics/src/ObjectConstraintSlider.cpp @@ -17,12 +17,12 @@ const uint16_t ObjectConstraintSlider::constraintVersion = 1; - +const glm::vec3 DEFAULT_SLIDER_AXIS(1.0f, 0.0f, 0.0f); ObjectConstraintSlider::ObjectConstraintSlider(const QUuid& id, EntityItemPointer ownerEntity) : ObjectConstraint(DYNAMIC_TYPE_SLIDER, id, ownerEntity), - _pointInA(glm::vec3(0.0f)), - _axisInA(glm::vec3(0.0f)) + _axisInA(DEFAULT_SLIDER_AXIS), + _axisInB(DEFAULT_SLIDER_AXIS) { } @@ -91,11 +91,25 @@ btTypedConstraint* ObjectConstraintSlider::getConstraint() { return nullptr; } + if (glm::length(axisInA) < FLT_EPSILON) { + qCWarning(physics) << "slider axis cannot be a zero vector"; + axisInA = DEFAULT_SLIDER_AXIS; + } else { + axisInA = glm::normalize(axisInA); + } + if (!otherEntityID.isNull()) { // This slider is between two entities... find the other rigid body. - glm::quat rotA = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInA)); - glm::quat rotB = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInB)); + if (glm::length(axisInB) < FLT_EPSILON) { + qCWarning(physics) << "slider axis cannot be a zero vector"; + axisInB = DEFAULT_SLIDER_AXIS; + } else { + axisInB = glm::normalize(axisInB); + } + + glm::quat rotA = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), axisInA); + glm::quat rotB = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), axisInB); btTransform frameInA(glmToBullet(rotA), glmToBullet(pointInA)); btTransform frameInB(glmToBullet(rotB), glmToBullet(pointInB)); @@ -109,7 +123,7 @@ btTypedConstraint* ObjectConstraintSlider::getConstraint() { } else { // This slider is between an entity and the world-frame. - glm::quat rot = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInA)); + glm::quat rot = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), axisInA); btTransform frameInA(glmToBullet(rot), glmToBullet(pointInA));