Bug fix centerLimit rot for LeftArm, also, lower arms in centerLimit pose

Lowering the arms in centerLimit poses will help keep the elbows relaxed on the side of the body.
This commit is contained in:
Anthony J. Thibault 2017-05-09 09:47:26 -07:00
parent 5a4b21c0a9
commit fe69f58174
3 changed files with 21 additions and 7 deletions

View file

@ -955,6 +955,19 @@ void AnimInverseKinematics::initLimitCenterPoses() {
}
_limitCenterPoses.push_back(pose);
}
// The limit center rotations for the LeftArm and RightArm form a t-pose.
// In order for the elbows to look more natural, we rotate them down by the avatar's sides
const float UPPER_ARM_THETA = 3.0f * PI / 8.0f; // 67.5 deg
int leftArmIndex = _skeleton->nameToJointIndex("LeftArm");
const glm::quat armRot = glm::angleAxis(UPPER_ARM_THETA, Vectors::UNIT_X);
if (leftArmIndex >= 0 && leftArmIndex < _limitCenterPoses.size()) {
_limitCenterPoses[leftArmIndex].rot() = _limitCenterPoses[leftArmIndex].rot() * armRot;
}
int rightArmIndex = _skeleton->nameToJointIndex("RightArm");
if (rightArmIndex >= 0 && rightArmIndex < _limitCenterPoses.size()) {
_limitCenterPoses[rightArmIndex].rot() = _limitCenterPoses[rightArmIndex].rot() * armRot;
}
}
void AnimInverseKinematics::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) {

View file

@ -1031,7 +1031,7 @@ void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) {
_animVars.set("notIsTalking", !params.isTalking);
if (params.hipsEnabled) {
_animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToCenterJointLimits);
_animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses);
_animVars.set("hipsType", (int)IKTarget::Type::RotationAndPosition);
_animVars.set("hipsPosition", extractTranslation(params.hipsMatrix));
_animVars.set("hipsRotation", glmExtractRotation(params.hipsMatrix));

View file

@ -433,15 +433,16 @@ void SwingTwistConstraint::clearHistory() {
}
glm::quat SwingTwistConstraint::computeCenterRotation() const {
const size_t NUM_TWIST_LIMITS = 2;
const size_t NUM_MIN_DOTS = getMinDots().size();
const size_t NUM_LIMITS = 2 * NUM_MIN_DOTS;
std::vector<glm::quat> swingLimits;
swingLimits.reserve(NUM_LIMITS);
swingLimits.reserve(NUM_MIN_DOTS);
glm::quat twistLimits[2];
glm::quat twistLimits[NUM_TWIST_LIMITS];
if (_minTwist != _maxTwist) {
twistLimits[0] = glm::angleAxis(_minTwist, _referenceRotation * Vectors::UNIT_Y);
twistLimits[1] = glm::angleAxis(_maxTwist, _referenceRotation * Vectors::UNIT_Y);
// to ensure that twists do not flip the center rotation, we devide twist angle by 2.
twistLimits[0] = glm::angleAxis(_minTwist / 2.0f, _referenceRotation * Vectors::UNIT_Y);
twistLimits[1] = glm::angleAxis(_maxTwist / 2.0f, _referenceRotation * Vectors::UNIT_Y);
}
const float D_THETA = TWO_PI / (NUM_MIN_DOTS - 1);
float theta = 0.0f;
@ -450,7 +451,7 @@ glm::quat SwingTwistConstraint::computeCenterRotation() const {
float phi = acos(getMinDots()[i]);
float cos_phi = getMinDots()[i];
float sin_phi = sinf(phi);
glm::vec3 swungAxis(sin_phi * cosf(theta), cos_phi, sin_phi * sinf(theta));
glm::vec3 swungAxis(sin_phi * cosf(theta), cos_phi, -sin_phi * sinf(theta));
// to ensure that swings > 90 degrees do not flip the center rotation, we devide phi / 2
glm::quat swing = glm::angleAxis(phi / 2, glm::normalize(glm::cross(Vectors::UNIT_Y, swungAxis)));