AnimController node now takes absolute rotation vars, instead of relative.

This commit is contained in:
Anthony J. Thibault 2015-09-09 12:24:32 -07:00
parent 146836452f
commit c1d7287652
4 changed files with 58 additions and 10 deletions

View file

@ -34,8 +34,22 @@ const AnimPoseVec& AnimController::evaluate(const AnimVariantMap& animVars, floa
jointVar.hasPerformedJointLookup = true;
}
if (jointVar.jointIndex >= 0) {
AnimPose pose(animVars.lookup(jointVar.var, glm::mat4()));
_poses[jointVar.jointIndex] = pose;
// jointVar is an absolute rotation, if it is not set we will use the bindPose as our default value
AnimPose defaultPose = _skeleton->getAbsoluteBindPose(jointVar.jointIndex);
glm::quat absRot = animVars.lookup(jointVar.var, defaultPose.rot);
// because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose
// here we use the bind pose
int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex);
glm::quat parentAbsRot;
if (parentIndex >= 0) {
parentAbsRot = _skeleton->getAbsoluteBindPose(parentIndex).rot;
}
// convert from absolute to relative
glm::quat relRot = glm::inverse(parentAbsRot) * absRot;
_poses[jointVar.jointIndex] = AnimPose(defaultPose.scale, relRot, defaultPose.trans);
}
}
@ -56,13 +70,39 @@ const AnimPoseVec& AnimController::overlay(const AnimVariantMap& animVars, float
}
if (jointVar.jointIndex >= 0) {
AnimPose pose;
AnimPose defaultPose;
glm::quat absRot;
glm::quat parentAbsRot;
if (jointVar.jointIndex <= (int)underPoses.size()) {
pose = AnimPose(animVars.lookup(jointVar.var, underPoses[jointVar.jointIndex]));
// jointVar is an absolute rotation, if it is not set we will use the underPose as our default value
defaultPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses);
absRot = animVars.lookup(jointVar.var, defaultPose.rot);
// because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose.
int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex);
if (parentIndex >= 0) {
parentAbsRot = _skeleton->getAbsolutePose(parentIndex, underPoses).rot;
}
} else {
pose = AnimPose(animVars.lookup(jointVar.var, AnimPose::identity));
// jointVar is an absolute rotation, if it is not set we will use the bindPose as our default value
defaultPose = _skeleton->getAbsoluteBindPose(jointVar.jointIndex);
absRot = animVars.lookup(jointVar.var, defaultPose.rot);
// because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose
// here we use the bind pose
int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex);
if (parentIndex >= 0) {
parentAbsRot = _skeleton->getAbsoluteBindPose(parentIndex).rot;
}
}
_poses[jointVar.jointIndex] = pose;
// convert from absolute to relative
glm::quat relRot = glm::inverse(parentAbsRot) * absRot;
_poses[jointVar.jointIndex] = AnimPose(defaultPose.scale, relRot, defaultPose.trans);
}
}

View file

@ -105,6 +105,14 @@ const QString& AnimSkeleton::getJointName(int jointIndex) const {
return _joints[jointIndex].name;
}
AnimPose AnimSkeleton::getAbsolutePose(int jointIndex, const AnimPoseVec& poses) const {
if (jointIndex < 0) {
return AnimPose::identity;
} else {
return getAbsolutePose(_joints[jointIndex].parentIndex, poses) * poses[jointIndex];
}
}
void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints, const AnimPose& geometryOffset) {
_joints = joints;

View file

@ -64,6 +64,8 @@ public:
int getParentIndex(int jointIndex) const;
AnimPose getAbsolutePose(int jointIndex, const AnimPoseVec& poses) const;
#ifndef NDEBUG
void dump() const;
void dump(const AnimPoseVec& poses) const;

View file

@ -956,12 +956,10 @@ void Rig::updateLeanJoint(int index, float leanSideways, float leanForward, floa
glm::vec3 xAxis(1.0f, 0.0f, 0.0f);
glm::vec3 yAxis(0.0f, 1.0f, 0.0f);
glm::vec3 zAxis(0.0f, 0.0f, 1.0f);
glm::quat rot = (glm::angleAxis(-RADIANS_PER_DEGREE * leanSideways, zAxis) *
glm::quat absRot = (glm::angleAxis(-RADIANS_PER_DEGREE * leanSideways, zAxis) *
glm::angleAxis(-RADIANS_PER_DEGREE * leanForward, xAxis) *
glm::angleAxis(RADIANS_PER_DEGREE * torsoTwist, yAxis));
AnimPose pose = _animSkeleton->getRelativeBindPose(index);
pose.rot = rot;
_animVars.set("lean", static_cast<glm::mat4>(pose));
_animVars.set("lean", absRot);
} else if (!_enableAnimGraph) {
auto& parentState = _jointStates[_jointStates[index].getParentIndex()];