fixed relative wrist correction problem

This commit is contained in:
Angus Antley 2019-02-19 07:35:13 -08:00
parent 748368bfda
commit f2301e7dac
3 changed files with 45 additions and 56 deletions

View file

@ -117,13 +117,15 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim
if (axisLength > MIN_LENGTH && refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH &&
refVectorProjLength > MIN_LENGTH && poleVectorProjLength > MIN_LENGTH) {
float dot = glm::clamp(glm::dot(refVectorProj / refVectorProjLength, poleVectorProj / poleVectorProjLength), 0.0f, 1.0f);
float dot = glm::clamp(glm::dot(refVectorProj / refVectorProjLength, poleVectorProj / poleVectorProjLength), -1.0f, 1.0f);
float sideDot = glm::dot(poleVector, sideVector);
float theta = copysignf(1.0f, sideDot) * acosf(dot);
glm::quat deltaRot = glm::angleAxis(theta, unitAxis);
//qCDebug(animation) << "anim ik theta " << (theta/PI)*180.0f;
if (_tipJointName == "RightHand") {
qCDebug(animation) << "anim ik theta " << (theta / PI)*180.0f;
}
// transform result back into parent relative frame.
glm::quat relBaseRot = glm::inverse(baseParentPose.rot()) * deltaRot * basePose.rot();

View file

@ -1723,6 +1723,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
} else {
unitAxis = Vectors::UNIT_Y;
}
float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1];
float zFactor;
@ -1766,7 +1767,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
AnimPose updatedBase = shoulderPose * deltaRot;
AnimPose newAbsMid = updatedBase * relMid;
/*
// now we calculate the contribution of the hand rotation relative to the arm
// we are adding in the delta rotation so that we have the hand correction relative to the
// latest theta for hand position
@ -1850,12 +1851,10 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
_twistThetaRunningAverageRight = 0.5f * _twistThetaRunningAverageRight + 0.5f * trueTwistTheta;
}
if (!left) {
qCDebug(animation) << "flex ave: " << (_flexThetaRunningAverageRight / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageRight / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageRight / PI) * 180.0f;
}
const float FLEX_BOUNDARY = PI / 6.0f;
const float EXTEND_BOUNDARY = -PI / 4.0f;
float currentWristCoefficient = 0.0f;
const float FLEX_BOUNDARY = 0.0f; // PI / 6.0f;
const float EXTEND_BOUNDARY = 0.0f; //-PI / 4.0f;
float flexCorrection = 0.0f;
if (left) {
if (_flexThetaRunningAverageLeft > FLEX_BOUNDARY) {
@ -1863,23 +1862,22 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
} else if (_flexThetaRunningAverageLeft < EXTEND_BOUNDARY) {
flexCorrection = ((_flexThetaRunningAverageLeft - EXTEND_BOUNDARY) / PI) * 180.0f;
}
if (fabsf(flexCorrection) > 30.0f) {
flexCorrection = glm::sign(flexCorrection) * 30.0f;
if (fabsf(flexCorrection) > 175.0f) {
flexCorrection = glm::sign(flexCorrection) * 175.0f;
}
theta += flexCorrection;
currentWristCoefficient += flexCorrection;
} else {
if (_flexThetaRunningAverageRight > FLEX_BOUNDARY) {
flexCorrection = ((_flexThetaRunningAverageRight - FLEX_BOUNDARY) / PI) * 180.0f;
} else if (_flexThetaRunningAverageRight < EXTEND_BOUNDARY) {
flexCorrection = ((_flexThetaRunningAverageRight - EXTEND_BOUNDARY) / PI) * 180.0f;
}
if (fabsf(flexCorrection) > 30.0f) {
flexCorrection = glm::sign(flexCorrection) * 30.0f;
if (fabsf(flexCorrection) > 175.0f) {
flexCorrection = glm::sign(flexCorrection) * 175.0f;
}
theta -= flexCorrection;
currentWristCoefficient -= flexCorrection;
}
const float ULNAR_BOUNDARY_MINUS = -PI / 6.0f;
const float ULNAR_BOUNDARY_PLUS = PI / 4.0f;
float ulnarDiff = 0.0f;
@ -1901,18 +1899,11 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
} else {
ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient;
}
} else {
// right hand
if (_twistThetaRunningAverageLeft > 0.0f) {
ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient;
} else {
ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient;
}
}
if (fabsf(ulnarCorrection) > 20.0f) {
ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f;
}
theta += ulnarCorrection;
currentWristCoefficient += ulnarCorrection;
}
} else {
if (_ulnarRadialThetaRunningAverageRight > ULNAR_BOUNDARY_PLUS) {
@ -1931,22 +1922,14 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
} else {
ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient;
}
} else {
// right hand
if (_twistThetaRunningAverageRight > 0.0f) {
ulnarCorrection -= glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient;
} else {
ulnarCorrection += glm::sign(ulnarDiff) * (fabsf(ulnarDiff) / PI) * 80.0f * twistCoefficient;
}
}
if (fabsf(ulnarCorrection) > 20.0f) {
ulnarCorrection = glm::sign(ulnarCorrection) * 20.0f;
}
theta += ulnarCorrection;
currentWristCoefficient += ulnarCorrection;
}
}
const float TWIST_DEADZONE = (4 * PI) / 9.0f;
float twistCorrection = 0.0f;
if (left) {
@ -1960,11 +1943,24 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
}
// limit the twist correction
if (fabsf(twistCorrection) > 30.0f) {
theta += glm::sign(twistCorrection) * 30.0f;
currentWristCoefficient += glm::sign(twistCorrection) * 30.0f;
} else {
theta += twistCorrection;
currentWristCoefficient += twistCorrection;
}
if (left) {
_lastWristCoefficientLeft = _lastThetaLeft - theta;
_lastWristCoefficientLeft += currentWristCoefficient;
theta += _lastWristCoefficientLeft;
} else {
_lastWristCoefficientRight = _lastThetaRight - theta;
_lastWristCoefficientRight += currentWristCoefficient;
theta += _lastWristCoefficientRight;
}
if (left) {
qCDebug(animation) << "theta " << theta << "Last wrist" << _lastWristCoefficientLeft << " flex ave: " << (_flexThetaRunningAverageLeft / PI) * 180.0f << " twist ave: " << (_twistThetaRunningAverageLeft / PI) * 180.0f << " ulnar deviation ave: " << (_ulnarRadialThetaRunningAverageLeft / PI) * 180.0f;
}
*/
// global limiting
float thetaRadians = 0.0f;
@ -1972,11 +1968,9 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
// final global smoothing
_lastThetaLeft = 0.5f * _lastThetaLeft + 0.5f * theta;
if (fabsf(_lastThetaLeft) < 50.0f) {
if (fabsf(_lastThetaLeft) < 50.0f) {
_lastThetaLeft = glm::sign(_lastThetaLeft) * 50.0f;
}
}
if (fabsf(_lastThetaLeft) > 175.0f) {
_lastThetaLeft = glm::sign(_lastThetaLeft) * 175.0f;
}
@ -1986,10 +1980,9 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
// final global smoothing
_lastThetaRight = 0.5f * _lastThetaRight + 0.5f * theta;
if (fabsf(_lastThetaRight) < 50.0f) {
if (fabsf(_lastThetaRight) < 50.0f) {
_lastThetaRight = glm::sign(_lastThetaRight) * 50.0f;
}
if (fabsf(_lastThetaRight) < 10.0f) {
_lastThetaRight = glm::sign(_lastThetaRight) * 10.0f;
}
if (fabsf(_lastThetaRight) > 175.0f) {
_lastThetaRight = glm::sign(_lastThetaRight) * 175.0f;
@ -2011,14 +2004,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
AnimPose armAxisPose(glm::mat4(glm::vec4(-w, 0.0f), glm::vec4(v, 0.0f), glm::vec4(u, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f)));
poleVector = armAxisPose * thetaVector;
if (left) {
//qCDebug(animation) << "theta vector " << thetaVector;
//qCDebug(animation) << "fwd " << fwd;
//qCDebug(animation) << "the x is " << w;
//qCDebug(animation) << "the y is " << v;
//qCDebug(animation) << "the z is " << u;
}
return true;
}

View file

@ -428,6 +428,8 @@ protected:
float _ulnarRadialThetaRunningAverageRight { 0.0f };
float _lastThetaLeft { 0.0f };
float _lastThetaRight { 0.0f };
float _lastWristCoefficientRight { 0.0f };
float _lastWristCoefficientLeft { 0.0f };
AnimContext _lastContext;
AnimVariantMap _lastAnimVars;