guard slider and cone-twist constraints against zero-length axisq

This commit is contained in:
Seth Alves 2017-05-08 17:02:37 -07:00
parent f8cab08b19
commit 55056e730a
2 changed files with 40 additions and 12 deletions

View file

@ -17,12 +17,12 @@
const uint16_t ObjectConstraintConeTwist::constraintVersion = 1; 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) : ObjectConstraintConeTwist::ObjectConstraintConeTwist(const QUuid& id, EntityItemPointer ownerEntity) :
ObjectConstraint(DYNAMIC_TYPE_CONE_TWIST, id, ownerEntity), ObjectConstraint(DYNAMIC_TYPE_CONE_TWIST, id, ownerEntity),
_pivotInA(glm::vec3(0.0f)), _axisInA(DEFAULT_CONE_TWIST_AXIS),
_axisInA(glm::vec3(0.0f)) _axisInB(DEFAULT_CONE_TWIST_AXIS)
{ {
#if WANT_DEBUG #if WANT_DEBUG
qCDebug(physics) << "ObjectConstraintConeTwist::ObjectConstraintConeTwist"; qCDebug(physics) << "ObjectConstraintConeTwist::ObjectConstraintConeTwist";
@ -109,11 +109,25 @@ btTypedConstraint* ObjectConstraintConeTwist::getConstraint() {
return nullptr; 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()) { if (!otherEntityID.isNull()) {
// This coneTwist is between two entities... find the other rigid body. // 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)); if (glm::length(axisInB) < FLT_EPSILON) {
glm::quat rotB = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInB)); 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 frameInA(glmToBullet(rotA), glmToBullet(pivotInA));
btTransform frameInB(glmToBullet(rotB), glmToBullet(pivotInB)); btTransform frameInB(glmToBullet(rotB), glmToBullet(pivotInB));
@ -127,7 +141,7 @@ btTypedConstraint* ObjectConstraintConeTwist::getConstraint() {
} else { } else {
// This coneTwist is between an entity and the world-frame. // 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)); btTransform frameInA(glmToBullet(rot), glmToBullet(pivotInA));

View file

@ -17,12 +17,12 @@
const uint16_t ObjectConstraintSlider::constraintVersion = 1; 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) : ObjectConstraintSlider::ObjectConstraintSlider(const QUuid& id, EntityItemPointer ownerEntity) :
ObjectConstraint(DYNAMIC_TYPE_SLIDER, id, ownerEntity), ObjectConstraint(DYNAMIC_TYPE_SLIDER, id, ownerEntity),
_pointInA(glm::vec3(0.0f)), _axisInA(DEFAULT_SLIDER_AXIS),
_axisInA(glm::vec3(0.0f)) _axisInB(DEFAULT_SLIDER_AXIS)
{ {
} }
@ -91,11 +91,25 @@ btTypedConstraint* ObjectConstraintSlider::getConstraint() {
return nullptr; 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()) { if (!otherEntityID.isNull()) {
// This slider is between two entities... find the other rigid body. // 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)); if (glm::length(axisInB) < FLT_EPSILON) {
glm::quat rotB = glm::rotation(glm::vec3(1.0f, 0.0f, 0.0f), glm::normalize(axisInB)); 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 frameInA(glmToBullet(rotA), glmToBullet(pointInA));
btTransform frameInB(glmToBullet(rotB), glmToBullet(pointInB)); btTransform frameInB(glmToBullet(rotB), glmToBullet(pointInB));
@ -109,7 +123,7 @@ btTypedConstraint* ObjectConstraintSlider::getConstraint() {
} else { } else {
// This slider is between an entity and the world-frame. // 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)); btTransform frameInA(glmToBullet(rot), glmToBullet(pointInA));