Bug fix to prevent wrists entering the avatar's torso.

This was inadvertently disabled in PR #11978.

(cherry picked from commit ae997928c1)
This commit is contained in:
Anthony J. Thibault 2018-01-10 11:51:44 -08:00
parent b1790cccbe
commit 250e4032b0
3 changed files with 33 additions and 26 deletions

View file

@ -106,7 +106,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
if (avatarHeadPose.isValid()) { if (avatarHeadPose.isValid()) {
AnimPose pose(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); AnimPose pose(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation());
params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = avatarToRigPose * pose; params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = avatarToRigPose * pose;
params.primaryControllerActiveFlags[Rig::PrimaryControllerType_Head] = true; params.primaryControllerFlags[Rig::PrimaryControllerType_Head] = (uint8_t)Rig::ControllerFlags::Enabled;
} else { } else {
// even though full head IK is disabled, the rig still needs the head orientation to rotate the head up and // even though full head IK is disabled, the rig still needs the head orientation to rotate the head up and
// down in desktop mode. // down in desktop mode.
@ -114,7 +114,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
// postMult 180 is necessary to convert head from -z forward to z forward. // postMult 180 is necessary to convert head from -z forward to z forward.
glm::quat headRot = Quaternions::Y_180 * head->getFinalOrientationInLocalFrame() * Quaternions::Y_180; glm::quat headRot = Quaternions::Y_180 * head->getFinalOrientationInLocalFrame() * Quaternions::Y_180;
params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = AnimPose(glm::vec3(1.0f), headRot, glm::vec3(0.0f)); params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = AnimPose(glm::vec3(1.0f), headRot, glm::vec3(0.0f));
params.primaryControllerActiveFlags[Rig::PrimaryControllerType_Head] = false; params.primaryControllerFlags[Rig::PrimaryControllerType_Head] = 0;
} }
// //
@ -135,10 +135,10 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
if (controllerPose.isValid()) { if (controllerPose.isValid()) {
AnimPose pose(controllerPose.getRotation(), controllerPose.getTranslation()); AnimPose pose(controllerPose.getRotation(), controllerPose.getTranslation());
params.primaryControllerPoses[pair.second] = avatarToRigPose * pose; params.primaryControllerPoses[pair.second] = avatarToRigPose * pose;
params.primaryControllerActiveFlags[pair.second] = true; params.primaryControllerFlags[pair.second] = (uint8_t)Rig::ControllerFlags::Enabled;
} else { } else {
params.primaryControllerPoses[pair.second] = AnimPose::identity; params.primaryControllerPoses[pair.second] = AnimPose::identity;
params.primaryControllerActiveFlags[pair.second] = false; params.primaryControllerFlags[pair.second] = 0;
} }
} }
@ -166,15 +166,15 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
if (controllerPose.isValid()) { if (controllerPose.isValid()) {
AnimPose pose(controllerPose.getRotation(), controllerPose.getTranslation()); AnimPose pose(controllerPose.getRotation(), controllerPose.getTranslation());
params.secondaryControllerPoses[pair.second] = avatarToRigPose * pose; params.secondaryControllerPoses[pair.second] = avatarToRigPose * pose;
params.secondaryControllerActiveFlags[pair.second] = true; params.secondaryControllerFlags[pair.second] = (uint8_t)Rig::ControllerFlags::Enabled;
} else { } else {
params.secondaryControllerPoses[pair.second] = AnimPose::identity; params.secondaryControllerPoses[pair.second] = AnimPose::identity;
params.secondaryControllerActiveFlags[pair.second] = false; params.secondaryControllerFlags[pair.second] = 0;
} }
} }
// if hips are not under direct control, estimate the hips position. // if hips are not under direct control, estimate the hips position.
if (avatarHeadPose.isValid() && !params.primaryControllerActiveFlags[Rig::PrimaryControllerType_Hips]) { if (avatarHeadPose.isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] & (uint8_t)Rig::ControllerFlags::Enabled)) {
bool isFlying = (myAvatar->getCharacterController()->getState() == CharacterController::State::Hover || myAvatar->getCharacterController()->computeCollisionGroup() == BULLET_COLLISION_GROUP_COLLISIONLESS); bool isFlying = (myAvatar->getCharacterController()->getState() == CharacterController::State::Hover || myAvatar->getCharacterController()->computeCollisionGroup() == BULLET_COLLISION_GROUP_COLLISIONLESS);
if (!_prevHipsValid) { if (!_prevHipsValid) {
@ -200,7 +200,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
AnimPose sensorToRigPose(invRigMat * myAvatar->getSensorToWorldMatrix()); AnimPose sensorToRigPose(invRigMat * myAvatar->getSensorToWorldMatrix());
params.primaryControllerPoses[Rig::PrimaryControllerType_Hips] = sensorToRigPose * hips; params.primaryControllerPoses[Rig::PrimaryControllerType_Hips] = sensorToRigPose * hips;
params.primaryControllerActiveFlags[Rig::PrimaryControllerType_Hips] = true; params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated;
} else { } else {
_prevHipsValid = false; _prevHipsValid = false;

View file

@ -1265,7 +1265,8 @@ glm::vec3 Rig::deflectHandFromTorso(const glm::vec3& handPosition, const FBXJoin
return position; return position;
} }
void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool leftArmEnabled, bool rightArmEnabled, float dt, void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated,
bool leftArmEnabled, bool rightArmEnabled, float dt,
const AnimPose& leftHandPose, const AnimPose& rightHandPose, const AnimPose& leftHandPose, const AnimPose& rightHandPose,
const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo, const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo,
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo) { const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo) {
@ -1279,7 +1280,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
glm::vec3 handPosition = leftHandPose.trans(); glm::vec3 handPosition = leftHandPose.trans();
glm::quat handRotation = leftHandPose.rot(); glm::quat handRotation = leftHandPose.rot();
if (!hipsEnabled) { if (!hipsEnabled || hipsEstimated) {
// prevent the hand IK targets from intersecting the torso // prevent the hand IK targets from intersecting the torso
handPosition = deflectHandFromTorso(handPosition, hipsShapeInfo, spineShapeInfo, spine1ShapeInfo, spine2ShapeInfo); handPosition = deflectHandFromTorso(handPosition, hipsShapeInfo, spineShapeInfo, spine1ShapeInfo, spine2ShapeInfo);
} }
@ -1326,7 +1327,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
glm::vec3 handPosition = rightHandPose.trans(); glm::vec3 handPosition = rightHandPose.trans();
glm::quat handRotation = rightHandPose.rot(); glm::quat handRotation = rightHandPose.rot();
if (!hipsEnabled) { if (!hipsEnabled || hipsEstimated) {
// prevent the hand IK targets from intersecting the torso // prevent the hand IK targets from intersecting the torso
handPosition = deflectHandFromTorso(handPosition, hipsShapeInfo, spineShapeInfo, spine1ShapeInfo, spine2ShapeInfo); handPosition = deflectHandFromTorso(handPosition, hipsShapeInfo, spineShapeInfo, spine1ShapeInfo, spine2ShapeInfo);
} }
@ -1550,20 +1551,20 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
_animVars.set("isTalking", params.isTalking); _animVars.set("isTalking", params.isTalking);
_animVars.set("notIsTalking", !params.isTalking); _animVars.set("notIsTalking", !params.isTalking);
bool headEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_Head]; bool headEnabled = params.primaryControllerFlags[PrimaryControllerType_Head] & (uint8_t)ControllerFlags::Enabled;
bool leftHandEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_LeftHand]; bool leftHandEnabled = params.primaryControllerFlags[PrimaryControllerType_LeftHand] & (uint8_t)ControllerFlags::Enabled;
bool rightHandEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_RightHand]; bool rightHandEnabled = params.primaryControllerFlags[PrimaryControllerType_RightHand] & (uint8_t)ControllerFlags::Enabled;
bool hipsEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_Hips]; bool hipsEnabled = params.primaryControllerFlags[PrimaryControllerType_Hips] & (uint8_t)ControllerFlags::Enabled;
bool leftFootEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_LeftFoot]; bool hipsEstimated = params.primaryControllerFlags[PrimaryControllerType_Hips] & (uint8_t)ControllerFlags::Estimated;
bool rightFootEnabled = params.primaryControllerActiveFlags[PrimaryControllerType_RightFoot]; bool leftFootEnabled = params.primaryControllerFlags[PrimaryControllerType_LeftFoot] & (uint8_t)ControllerFlags::Enabled;
bool spine2Enabled = params.primaryControllerActiveFlags[PrimaryControllerType_Spine2]; bool rightFootEnabled = params.primaryControllerFlags[PrimaryControllerType_RightFoot] & (uint8_t)ControllerFlags::Enabled;
bool spine2Enabled = params.primaryControllerFlags[PrimaryControllerType_Spine2] & (uint8_t)ControllerFlags::Enabled;
bool leftArmEnabled = params.secondaryControllerActiveFlags[SecondaryControllerType_LeftArm]; bool leftArmEnabled = params.secondaryControllerFlags[SecondaryControllerType_LeftArm] & (uint8_t)ControllerFlags::Enabled;
bool rightArmEnabled = params.secondaryControllerActiveFlags[SecondaryControllerType_RightArm]; bool rightArmEnabled = params.secondaryControllerFlags[SecondaryControllerType_RightArm] & (uint8_t)ControllerFlags::Enabled;
updateHead(headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]); updateHead(headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]);
updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, leftArmEnabled, rightArmEnabled, dt, updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, dt,
params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand],
params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo); params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo);
@ -1623,7 +1624,7 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
for (int i = 0; i < (int)NumSecondaryControllerTypes; i++) { for (int i = 0; i < (int)NumSecondaryControllerTypes; i++) {
int index = indexOfJoint(secondaryControllerJointNames[i]); int index = indexOfJoint(secondaryControllerJointNames[i]);
if (index >= 0) { if (index >= 0) {
if (params.secondaryControllerActiveFlags[i]) { if (params.secondaryControllerFlags[i] & (uint8_t)ControllerFlags::Enabled) {
ikNode->setSecondaryTargetInRigFrame(index, params.secondaryControllerPoses[i]); ikNode->setSecondaryTargetInRigFrame(index, params.secondaryControllerPoses[i]);
} else { } else {
ikNode->clearSecondaryTarget(index); ikNode->clearSecondaryTarget(index);

View file

@ -69,11 +69,16 @@ public:
NumSecondaryControllerTypes NumSecondaryControllerTypes
}; };
enum class ControllerFlags : uint8_t {
Enabled = 0x01,
Estimated = 0x02
};
struct ControllerParameters { struct ControllerParameters {
AnimPose primaryControllerPoses[NumPrimaryControllerTypes]; // rig space AnimPose primaryControllerPoses[NumPrimaryControllerTypes]; // rig space
bool primaryControllerActiveFlags[NumPrimaryControllerTypes]; uint8_t primaryControllerFlags[NumPrimaryControllerTypes];
AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space
bool secondaryControllerActiveFlags[NumSecondaryControllerTypes]; uint8_t secondaryControllerFlags[NumSecondaryControllerTypes];
bool isTalking; bool isTalking;
FBXJointShapeInfo hipsShapeInfo; FBXJointShapeInfo hipsShapeInfo;
FBXJointShapeInfo spineShapeInfo; FBXJointShapeInfo spineShapeInfo;
@ -251,7 +256,8 @@ protected:
void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut); void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut);
void updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headMatrix); void updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headMatrix);
void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool leftArmEnabled, bool rightArmEnabled, float dt, void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated,
bool leftArmEnabled, bool rightArmEnabled, float dt,
const AnimPose& leftHandPose, const AnimPose& rightHandPose, const AnimPose& leftHandPose, const AnimPose& rightHandPose,
const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo, const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo,
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo); const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo);