mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-29 22:22:54 +02:00
Merge pull request #7129 from hyperlogic/tony/no-hands-in-body
Prevent avatar's wrists from entering torso
This commit is contained in:
commit
c53e583bf4
5 changed files with 45 additions and 3 deletions
|
@ -144,6 +144,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||||
} else {
|
} else {
|
||||||
handParams.isRightEnabled = false;
|
handParams.isRightEnabled = false;
|
||||||
}
|
}
|
||||||
|
handParams.bodyCapsuleRadius = myAvatar->getCharacterController()->getCapsuleRadius();
|
||||||
|
|
||||||
_rig->updateFromHandParameters(handParams, deltaTime);
|
_rig->updateFromHandParameters(handParams, deltaTime);
|
||||||
|
|
||||||
|
|
|
@ -670,7 +670,7 @@ void AnimInverseKinematics::initConstraints() {
|
||||||
stConstraint->setTwistLimits(-MAX_SHOULDER_TWIST, MAX_SHOULDER_TWIST);
|
stConstraint->setTwistLimits(-MAX_SHOULDER_TWIST, MAX_SHOULDER_TWIST);
|
||||||
|
|
||||||
std::vector<float> minDots;
|
std::vector<float> minDots;
|
||||||
const float MAX_SHOULDER_SWING = PI / 20.0f;
|
const float MAX_SHOULDER_SWING = PI / 6.0f;
|
||||||
minDots.push_back(cosf(MAX_SHOULDER_SWING));
|
minDots.push_back(cosf(MAX_SHOULDER_SWING));
|
||||||
stConstraint->setSwingLimits(minDots);
|
stConstraint->setSwingLimits(minDots);
|
||||||
|
|
||||||
|
|
|
@ -1080,8 +1080,31 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm
|
||||||
|
|
||||||
void Rig::updateFromHandParameters(const HandParameters& params, float dt) {
|
void Rig::updateFromHandParameters(const HandParameters& params, float dt) {
|
||||||
if (_animSkeleton && _animNode) {
|
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) {
|
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("leftHandRotation", params.leftOrientation);
|
||||||
_animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition);
|
_animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1089,8 +1112,23 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) {
|
||||||
_animVars.unset("leftHandRotation");
|
_animVars.unset("leftHandRotation");
|
||||||
_animVars.set("leftHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition);
|
_animVars.set("leftHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.isRightEnabled) {
|
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("rightHandRotation", params.rightOrientation);
|
||||||
_animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition);
|
_animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -67,6 +67,7 @@ public:
|
||||||
struct HandParameters {
|
struct HandParameters {
|
||||||
bool isLeftEnabled;
|
bool isLeftEnabled;
|
||||||
bool isRightEnabled;
|
bool isRightEnabled;
|
||||||
|
float bodyCapsuleRadius;
|
||||||
glm::vec3 leftPosition = glm::vec3(); // rig space
|
glm::vec3 leftPosition = glm::vec3(); // rig space
|
||||||
glm::quat leftOrientation = glm::quat(); // rig space (z forward)
|
glm::quat leftOrientation = glm::quat(); // rig space (z forward)
|
||||||
glm::vec3 rightPosition = glm::vec3(); // rig space
|
glm::vec3 rightPosition = glm::vec3(); // rig space
|
||||||
|
|
|
@ -78,6 +78,8 @@ public:
|
||||||
|
|
||||||
glm::vec3 getLinearVelocity() const;
|
glm::vec3 getLinearVelocity() const;
|
||||||
|
|
||||||
|
float getCapsuleRadius() const { return _radius; }
|
||||||
|
|
||||||
enum class State {
|
enum class State {
|
||||||
Ground = 0,
|
Ground = 0,
|
||||||
Takeoff,
|
Takeoff,
|
||||||
|
|
Loading…
Reference in a new issue