diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index c77c4fdd78..e4c98215c2 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -144,6 +144,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } else { handParams.isRightEnabled = false; } + handParams.bodyCapsuleRadius = myAvatar->getCharacterController()->getCapsuleRadius(); _rig->updateFromHandParameters(handParams, deltaTime); diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index ff1dea3d48..48ad9b852d 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -670,7 +670,7 @@ void AnimInverseKinematics::initConstraints() { stConstraint->setTwistLimits(-MAX_SHOULDER_TWIST, MAX_SHOULDER_TWIST); std::vector minDots; - const float MAX_SHOULDER_SWING = PI / 20.0f; + const float MAX_SHOULDER_SWING = PI / 6.0f; minDots.push_back(cosf(MAX_SHOULDER_SWING)); stConstraint->setSwingLimits(minDots); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 817054a9f5..3952dc5b40 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1080,8 +1080,31 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm void Rig::updateFromHandParameters(const HandParameters& params, float dt) { if (_animSkeleton && _animNode) { + + const float HAND_RADIUS = 0.05f; + const float BODY_RADIUS = params.bodyCapsuleRadius; + const float MIN_LENGTH = 1.0e-4f; + + // project the hips onto the xz plane. + auto hipsTrans = _internalPoseSet._absolutePoses[_animSkeleton->nameToJointIndex("Hips")].trans; + const glm::vec2 bodyCircleCenter(hipsTrans.x, hipsTrans.z); + if (params.isLeftEnabled) { - _animVars.set("leftHandPosition", params.leftPosition); + + // project the hand position onto the xz plane. + glm::vec2 handCircleCenter(params.leftPosition.x, params.leftPosition.z); + + // check for 2d overlap of the hand and body circles. + auto circleToCircle = handCircleCenter - bodyCircleCenter; + const float circleToCircleLength = glm::length(circleToCircle); + const float penetrationDistance = HAND_RADIUS + BODY_RADIUS - circleToCircleLength; + if (penetrationDistance > 0.0f && circleToCircleLength > MIN_LENGTH) { + // push the hands out of the body + handCircleCenter += penetrationDistance * glm::normalize(circleToCircle); + } + + glm::vec3 handPosition(handCircleCenter.x, params.leftPosition.y, handCircleCenter.y); + _animVars.set("leftHandPosition", handPosition); _animVars.set("leftHandRotation", params.leftOrientation); _animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition); } else { @@ -1089,8 +1112,23 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) { _animVars.unset("leftHandRotation"); _animVars.set("leftHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition); } + if (params.isRightEnabled) { - _animVars.set("rightHandPosition", params.rightPosition); + + // project the hand position onto the xz plane. + glm::vec2 handCircleCenter(params.rightPosition.x, params.rightPosition.z); + + // check for 2d overlap of the hand and body circles. + auto circleToCircle = handCircleCenter - bodyCircleCenter; + const float circleToCircleLength = glm::length(circleToCircle); + const float penetrationDistance = HAND_RADIUS + BODY_RADIUS - circleToCircleLength; + if (penetrationDistance > 0.0f && circleToCircleLength > MIN_LENGTH) { + // push the hands out of the body + handCircleCenter += penetrationDistance * glm::normalize(circleToCircle); + } + + glm::vec3 handPosition(handCircleCenter.x, params.rightPosition.y, handCircleCenter.y); + _animVars.set("rightHandPosition", handPosition); _animVars.set("rightHandRotation", params.rightOrientation); _animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition); } else { diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index e4668d6c2a..9c5b014d55 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -67,6 +67,7 @@ public: struct HandParameters { bool isLeftEnabled; bool isRightEnabled; + float bodyCapsuleRadius; glm::vec3 leftPosition = glm::vec3(); // rig space glm::quat leftOrientation = glm::quat(); // rig space (z forward) glm::vec3 rightPosition = glm::vec3(); // rig space diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 5362ca52e4..a8543d6070 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -78,6 +78,8 @@ public: glm::vec3 getLinearVelocity() const; + float getCapsuleRadius() const { return _radius; } + enum class State { Ground = 0, Takeoff,