changed back to regular 2 bone Ik for arms in json and cleaned up rig.cpp and polevector constraint

This commit is contained in:
Angus Antley 2019-02-15 07:06:43 -08:00
parent f8554d10a8
commit 382a03929e
4 changed files with 46 additions and 133 deletions

View file

@ -129,7 +129,7 @@
"children": [ "children": [
{ {
"id": "rightHandIK", "id": "rightHandIK",
"type": "armIK", "type": "twoBoneIK",
"data": { "data": {
"alpha": 1.0, "alpha": 1.0,
"enabled": false, "enabled": false,
@ -159,7 +159,7 @@
"children": [ "children": [
{ {
"id": "leftHandIK", "id": "leftHandIK",
"type": "armIK", "type": "twoBoneIK",
"data": { "data": {
"alpha": 1.0, "alpha": 1.0,
"enabled": false, "enabled": false,

View file

@ -34,64 +34,6 @@ AnimPoleVectorConstraint::~AnimPoleVectorConstraint() {
} }
float AnimPoleVectorConstraint::findThetaNewWay(const glm::vec3& hand, const glm::vec3& shoulder, bool left) const {
// get the default poses for the upper and lower arm
// then use this length to judge how far the hand is away from the shoulder.
// then create weights that make the elbow angle less when the x value is large in either direction.
// make the angle less when z is small.
// lower y with x center lower angle
// lower y with x out higher angle
AnimPose shoulderPose = _skeleton->getAbsoluteDefaultPose(_skeleton->nameToJointIndex("RightShoulder"));
AnimPose handPose = _skeleton->getAbsoluteDefaultPose(_skeleton->nameToJointIndex("RightHand"));
// subtract 10 centimeters from the arm length for some reason actual arm position is clamped to length - 10cm.
float defaultArmLength = glm::length( handPose.trans() - shoulderPose.trans() ) - 10.0f;
// qCDebug(animation) << "default arm length " << defaultArmLength;
// phi_0 is the lowest angle we can have
const float phi_0 = 15.0f;
const float zStart = 0.6f;
const float xStart = 0.1f;
// biases
//const glm::vec3 biases(30.0f, 120.0f, -30.0f);
const glm::vec3 biases(0.0f, 135.0f, 0.0f);
// weights
const float zWeightBottom = -100.0f;
//const glm::vec3 weights(-30.0f, 30.0f, 210.0f);
const glm::vec3 weights(-50.0f, 60.0f, 260.0f);
glm::vec3 armToHand = hand - shoulder;
// qCDebug(animation) << "current arm length " << glm::length(armToHand);
float initial_valuesY = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1];
float initial_valuesZ;
if (armToHand[1] > 0.0f) {
initial_valuesZ = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength);
} else {
initial_valuesZ = zWeightBottom * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength);
}
//1.0f + armToHand[1]/defaultArmLength
float initial_valuesX;
if (left) {
initial_valuesX = weights[0] * glm::max(-1.0f * (armToHand[0] / defaultArmLength) + xStart, 0.0f);
} else {
initial_valuesX = weights[0] * (((armToHand[0] / defaultArmLength) + xStart) - (0.3f) * ((1.0f + (armToHand[1] / defaultArmLength))/2.0f));
}
float theta = initial_valuesX + initial_valuesY + initial_valuesZ;
if (theta < 13.0f) {
theta = 13.0f;
}
if (theta > 175.0f) {
theta = 175.0f;
}
if (!left) {
//qCDebug(animation) << "relative hand x " << initial_valuesX << " y " << initial_valuesY << " z " << initial_valuesZ << "theta value for pole vector is " << theta;
}
return theta;
}
const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
assert(_children.size() == 1); assert(_children.size() == 1);
@ -114,13 +56,9 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim
_poses = underPoses; _poses = underPoses;
} }
// Look up poleVector from animVars, make sure to convert into geom space. // Look up poleVector from animVars, make sure to convert into geom space.
glm::vec3 poleVector = animVars.lookupRigToGeometryVector(_poleVectorVar, Vectors::UNIT_Z); glm::vec3 poleVector = animVars.lookupRigToGeometryVector(_poleVectorVar, Vectors::UNIT_Z);
if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) {
//float thetaFromRig = animVars.lookup("thetaRight", 0.0f); //float thetaFromRig = animVars.lookup("thetaRight", 0.0f);
//qCDebug(animation) << " anim pole vector theta from rig " << thetaFromRig; //qCDebug(animation) << " anim pole vector theta from rig " << thetaFromRig;
} }
@ -164,11 +102,6 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim
glm::vec3 refVector = midPose.xformVectorFast(_referenceVector); glm::vec3 refVector = midPose.xformVectorFast(_referenceVector);
float refVectorLength = glm::length(refVector); float refVectorLength = glm::length(refVector);
if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) {
//qCDebug(animation) << "mid pose anim " << midPose;
//qCDebug(animation) << "ref vector anim " << refVector;
}
glm::vec3 axis = basePose.trans() - tipPose.trans(); glm::vec3 axis = basePose.trans() - tipPose.trans();
float axisLength = glm::length(axis); float axisLength = glm::length(axis);
glm::vec3 unitAxis = axis / axisLength; glm::vec3 unitAxis = axis / axisLength;
@ -180,22 +113,6 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim
glm::vec3 refVectorProj = refVector - glm::dot(refVector, unitAxis) * unitAxis; glm::vec3 refVectorProj = refVector - glm::dot(refVector, unitAxis) * unitAxis;
float refVectorProjLength = glm::length(refVectorProj); float refVectorProjLength = glm::length(refVectorProj);
float lastDot;
if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) {
//fake pole vector computation.
lastDot = cosf(((180.0f - _lastTheta) / 180.0f)*PI);
float lastSideDot = sqrt(1.0f - (lastDot*lastDot));
glm::vec3 pretendPoleVector;
if (refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH) {
poleVector = lastDot * (refVectorProj / refVectorProjLength) + glm::sign(_lastTheta) * lastSideDot * (sideVector / sideVectorLength);
if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) {
//qCDebug(animation) << "pole vector anim: " << poleVector;
}
} else {
poleVector = glm::vec3(1.0f, 0.0f, 0.0f);
}
}
// project poleVector on plane formed by axis. // project poleVector on plane formed by axis.
glm::vec3 poleVectorProj = poleVector - glm::dot(poleVector, unitAxis) * unitAxis; glm::vec3 poleVectorProj = poleVector - glm::dot(poleVector, unitAxis) * unitAxis;
float poleVectorProjLength = glm::length(poleVectorProj); float poleVectorProjLength = glm::length(poleVectorProj);
@ -208,45 +125,16 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim
float sideDot = glm::dot(poleVector, sideVector); float sideDot = glm::dot(poleVector, sideVector);
float theta = copysignf(1.0f, sideDot) * acosf(dot); float theta = copysignf(1.0f, sideDot) * acosf(dot);
float fred; // overwrite theta if we are using optimized code
if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) { if ((_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) || (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex)) {
//qCDebug(animation) << "theta from the old code " << theta;
bool isLeft = false;
if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) { if (_skeleton->nameToJointIndex("LeftHand") == _tipJointIndex) {
isLeft = true; theta = animVars.lookup("thetaLeftElbow", 0.0f);
} else if (_skeleton->nameToJointIndex("RightHand") == _tipJointIndex) {
theta = animVars.lookup("thetaRightElbow", 0.0f);
} }
//qCDebug(animation) << "hand pose anim pole vector: " << isLeft << " isLeft " << tipPose;
//fred = findThetaNewWay(tipPose.trans(), basePose.trans(), isLeft);
if (isLeft) {
float thetaFromRig = animVars.lookup("thetaLeft", 0.0f);
//qCDebug(animation) << " anim pole vector theta from rig left" << thetaFromRig;
fred = thetaFromRig;
} else {
float thetaFromRig = animVars.lookup("thetaRight", 0.0f);
//qCDebug(animation) << " anim pole vector theta from rig right" << thetaFromRig;
fred = thetaFromRig;
}
_lastTheta = 0.5f * _lastTheta + 0.5f * fred;
//qCDebug(animation) << "twist correction: " << twistCorrection << " flex correction: " << flexCorrection << " ulnar correction " << ulnarCorrection;
if (fabsf(_lastTheta) < 50.0f) {
if (fabsf(_lastTheta) < 50.0f) {
_lastTheta = glm::sign(_lastTheta) * 50.0f;
}
}
if (fabsf(_lastTheta) > 175.0f) {
_lastTheta = glm::sign(_lastTheta) * 175.0f;
}
float poleVectorTheta = theta;
theta = ((180.0f - _lastTheta) / 180.0f)*PI;
} }
//glm::quat deltaRot = glm::angleAxis(theta, unitAxis);
glm::quat deltaRot = glm::angleAxis(theta, unitAxis); glm::quat deltaRot = glm::angleAxis(theta, unitAxis);
// transform result back into parent relative frame. // transform result back into parent relative frame.
@ -334,8 +222,6 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim
return _poses; return _poses;
} }
// for AnimDebugDraw rendering // for AnimDebugDraw rendering
const AnimPoseVec& AnimPoleVectorConstraint::getPosesInternal() const { const AnimPoseVec& AnimPoleVectorConstraint::getPosesInternal() const {
return _poses; return _poses;

View file

@ -1692,7 +1692,7 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
// get the default poses for the upper and lower arm // get the default poses for the upper and lower arm
// then use this length to judge how far the hand is away from the shoulder. // then use this length to judge how far the hand is away from the shoulder.
// then create weights that make the elbow angle less when the x value is large in either direction. // then create weights that make the elbow angle less when the x value is large in either direction.
// make the angle less when z is small. // make the angle less when z is small.
// lower y with x center lower angle // lower y with x center lower angle
// lower y with x out higher angle // lower y with x out higher angle
@ -1744,14 +1744,13 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
const float zStart = 0.6f; const float zStart = 0.6f;
const float xStart = 0.1f; const float xStart = 0.1f;
// biases // biases
//const glm::vec3 biases(30.0f, 120.0f, -30.0f);
const glm::vec3 biases(0.0f, 135.0f, 0.0f); const glm::vec3 biases(0.0f, 135.0f, 0.0f);
// weights // weights
const float zWeightBottom = -100.0f; const float zWeightBottom = -100.0f;
const glm::vec3 weights(-50.0f, 60.0f, 260.0f); const glm::vec3 weights(-50.0f, 60.0f, 260.0f);
glm::vec3 armToHand = handPose.trans() - shoulderPose.trans(); glm::vec3 armToHand = handPose.trans() - shoulderPose.trans();
float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1]; float yFactor = (fabsf(armToHand[1] / defaultArmLength) * weights[1]) + biases[1];
float zFactor; float zFactor;
if (armToHand[1] > 0.0f) { if (armToHand[1] > 0.0f) {
zFactor = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength); zFactor = weights[2] * glm::max(zStart - (armToHand[2] / defaultArmLength), 0.0f) * fabs(armToHand[1] / defaultArmLength);
@ -1888,7 +1887,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
} }
theta -= flexCorrection; theta -= flexCorrection;
} }
qCDebug(animation) << "flexCorrection rig" << flexCorrection;
const float TWIST_ULNAR_DEADZONE = 0.0f; const float TWIST_ULNAR_DEADZONE = 0.0f;
const float ULNAR_BOUNDARY_MINUS = -PI / 12.0f; const float ULNAR_BOUNDARY_MINUS = -PI / 12.0f;
@ -1960,7 +1958,6 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
} }
} }
} }
qCDebug(animation) << "ulnarCorrection rig" << ulnarCorrection;
// remember direction of travel. // remember direction of travel.
const float TWIST_DEADZONE = (4 * PI) / 9.0f; const float TWIST_DEADZONE = (4 * PI) / 9.0f;
@ -1969,26 +1966,55 @@ bool Rig::calculateElbowPoleVectorOptimized(int handIndex, int elbowIndex, int s
if (left) { if (left) {
if (fabsf(_twistThetaRunningAverageLeft) > TWIST_DEADZONE) { if (fabsf(_twistThetaRunningAverageLeft) > TWIST_DEADZONE) {
twistCorrection = glm::sign(_twistThetaRunningAverageLeft) * ((fabsf(_twistThetaRunningAverageLeft) - TWIST_DEADZONE) / PI) * 80.0f; twistCorrection = glm::sign(_twistThetaRunningAverageLeft) * ((fabsf(_twistThetaRunningAverageLeft) - TWIST_DEADZONE) / PI) * 80.0f;
} }
} else { } else {
if (fabsf(_twistThetaRunningAverageRight) > TWIST_DEADZONE) { if (fabsf(_twistThetaRunningAverageRight) > TWIST_DEADZONE) {
twistCorrection = glm::sign(_twistThetaRunningAverageRight) * ((fabsf(_twistThetaRunningAverageRight) - TWIST_DEADZONE) / PI) * 80.0f; twistCorrection = glm::sign(_twistThetaRunningAverageRight) * ((fabsf(_twistThetaRunningAverageRight) - TWIST_DEADZONE) / PI) * 80.0f;
} }
} }
if (fabsf(twistCorrection) > 30.0f) { if (fabsf(twistCorrection) > 30.0f) {
theta += glm::sign(twistCorrection) * 30.0f; theta += glm::sign(twistCorrection) * 30.0f;
} else { } else {
theta += twistCorrection; theta += twistCorrection;
} }
qCDebug(animation) << "twistCorrection rig" << twistCorrection;
// put final global limiter here....... //qCDebug(animation) << "twist correction: " << twistCorrection << " flex correction: " << flexCorrection << " ulnar correction " << ulnarCorrection;
// global limiting
if (left) { if (left) {
_animVars.set("thetaLeft", theta); // 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;
}
// convert to radians and make 180 0 to match pole vector theta
float thetaRadians = ((180.0f - _lastThetaLeft) / 180.0f)*PI;
_animVars.set("thetaLeftElbow", thetaRadians);
} else { } else {
_animVars.set("thetaRight", theta); // 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) > 175.0f) {
_lastThetaRight = glm::sign(_lastThetaRight) * 175.0f;
}
// convert to radians and make 180 0 to match pole vector theta
float thetaRadians = ((180.0f - _lastThetaRight) / 180.0f)*PI;
_animVars.set("thetaRightElbow", thetaRadians);
} }
// remove this if inaccurate
// convert theta back to pole vector // convert theta back to pole vector
float lastDot = cosf(((180.0f - theta) / 180.0f)*PI); float lastDot = cosf(((180.0f - theta) / 180.0f)*PI);
float lastSideDot = sqrt(1.0f - (lastDot*lastDot)); float lastSideDot = sqrt(1.0f - (lastDot*lastDot));

View file

@ -432,7 +432,8 @@ protected:
float _twistThetaRunningAverageRight{ 0.0f }; float _twistThetaRunningAverageRight{ 0.0f };
float _flexThetaRunningAverageRight { 0.0f }; float _flexThetaRunningAverageRight { 0.0f };
float _ulnarRadialThetaRunningAverageRight { 0.0f }; float _ulnarRadialThetaRunningAverageRight { 0.0f };
float _lastTheta { 0.0f }; float _lastThetaLeft { 0.0f };
float _lastThetaRight { 0.0f };
AnimContext _lastContext; AnimContext _lastContext;
AnimVariantMap _lastAnimVars; AnimVariantMap _lastAnimVars;