IK fix for avatars exported from Blender

This should fix the issue with the hips moving erratically when arm IK
is enabled.  The main issue is that the IK system assumed that the "Hips"
joint was the root of the skeleton.  For Blender avatar this is not the case
as it inserts an "Armature" node at the root instead.
This commit is contained in:
Anthony J. Thibault 2015-11-05 12:03:45 -08:00
parent 669609d310
commit 20d95080f1

View file

@ -156,11 +156,11 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector<I
// cache tip absolute transform
int tipIndex = target.getIndex();
int pivotIndex = _skeleton->getParentIndex(tipIndex);
if (pivotIndex == -1) {
if (pivotIndex == -1 || pivotIndex == _hipsIndex) {
continue;
}
int pivotsParentIndex = _skeleton->getParentIndex(pivotIndex);
if (pivotsParentIndex == -1) {
if (pivotsParentIndex == -1 || pivotIndex == _hipsIndex) {
// TODO?: handle case where tip's parent is root?
continue;
}
@ -173,7 +173,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector<I
glm::quat tipParentRotation = absolutePoses[pivotIndex].rot;
// descend toward root, pivoting each joint to get tip closer to target
while (pivotsParentIndex != -1) {
while (pivotsParentIndex != _hipsIndex && pivotsParentIndex != -1) {
// compute the two lines that should be aligned
glm::vec3 jointPosition = absolutePoses[pivotIndex].trans;
glm::vec3 leverArm = tipPosition - jointPosition;
@ -285,7 +285,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector<I
// only update the absolutePoses that need it: those between lowestMovedIndex and _maxTargetIndex
for (int i = lowestMovedIndex; i <= _maxTargetIndex; ++i) {
int parentIndex = _skeleton->getParentIndex(i);
if (parentIndex != -1) {
if (parentIndex != -1 && parentIndex != _hipsIndex) {
absolutePoses[i] = absolutePoses[parentIndex] * _relativePoses[i];
}
}
@ -295,7 +295,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector<I
for (auto& target: targets) {
int tipIndex = target.getIndex();
int parentIndex = _skeleton->getParentIndex(tipIndex);
if (parentIndex != -1) {
if (parentIndex != -1 && parentIndex != _hipsIndex) {
const glm::quat& targetRotation = target.getRotation();
// compute tip's new parent-relative rotation
// Q = Qp * q --> q' = Qp^ * Q