From f01847de14d87cf3f5f1b24e75893cad29c343c3 Mon Sep 17 00:00:00 2001 From: "U-GAPOS\\andrew" Date: Sat, 10 Oct 2015 19:23:21 -0700 Subject: [PATCH] experimental HMD hips tracking --- .../defaultAvatar_full/avatar-animation.json | 12 +++--- interface/src/avatar/MyAvatar.cpp | 4 +- .../animation/src/AnimInverseKinematics.cpp | 40 ++++++++++++++----- libraries/animation/src/IKTarget.cpp | 3 ++ libraries/animation/src/IKTarget.h | 1 + libraries/animation/src/Rig.cpp | 10 ++++- 6 files changed, 53 insertions(+), 17 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index e930f583f6..737a27be02 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -16,12 +16,14 @@ { "jointName": "RightHand", "positionVar": "rightHandPosition", - "rotationVar": "rightHandRotation" + "rotationVar": "rightHandRotation", + "typeVar": "rightHandType" }, { "jointName": "LeftHand", "positionVar": "leftHandPosition", - "rotationVar": "leftHandRotation" + "rotationVar": "leftHandRotation", + "typeVar": "leftHandType" }, { "jointName": "RightFoot", @@ -39,13 +41,13 @@ "jointName": "Neck", "positionVar": "neckPosition", "rotationVar": "neckRotation", - "typeVar": "headAndNeckType" + "typeVar": "neckType" }, { "jointName": "Head", "positionVar": "headPosition", "rotationVar": "headRotation", - "typeVar": "headAndNeckType" + "typeVar": "headType" } ] }, @@ -63,7 +65,7 @@ "id": "spineLean", "type": "manipulator", "data": { - "alpha": 1.0, + "alpha": 0.0, "joints": [ { "var": "lean", "jointName": "Spine" } ] diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 22816e9001..41e067c047 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -337,16 +337,18 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { const float STRAIGHTENING_LEAN_DURATION = 0.5f; // seconds // define a vertical capsule + static float adebug = 1.0f; // adebug const float STRAIGHTENING_LEAN_CAPSULE_RADIUS = 0.2f; // meters const float STRAIGHTENING_LEAN_CAPSULE_LENGTH = 0.05f; // length of the cylinder part of the capsule in meters. auto newBodySensorMatrix = deriveBodyFromHMDSensor(); glm::vec3 diff = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); - if (!_straighteningLean && (capsuleCheck(diff, STRAIGHTENING_LEAN_CAPSULE_LENGTH, STRAIGHTENING_LEAN_CAPSULE_RADIUS) || hmdIsAtRest)) { + if (!_straighteningLean && (capsuleCheck(diff, adebug * STRAIGHTENING_LEAN_CAPSULE_LENGTH, adebug * STRAIGHTENING_LEAN_CAPSULE_RADIUS) || hmdIsAtRest)) { // begin homing toward derived body position. _straighteningLean = true; _straighteningLeanAlpha = 0.0f; + adebug = 1000.0f; // adebug } else if (_straighteningLean) { diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 80c8152e3a..7e677abcba 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -98,8 +98,14 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: target.setType(animVars.lookup(targetVar.typeVar, (int)IKTarget::Type::RotationAndPosition)); if (target.getType() != IKTarget::Type::Unknown) { AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses); - target.setPose(animVars.lookup(targetVar.rotationVar, defaultPose.rot), - animVars.lookup(targetVar.positionVar, defaultPose.trans)); + glm::quat rotation = animVars.lookup(targetVar.rotationVar, defaultPose.rot); + glm::vec3 translation = animVars.lookup(targetVar.positionVar, defaultPose.trans); + if (target.getType() == IKTarget::Type::HipsRelativeRotationAndPosition) { + translation += _hipsOffset; + // HACK to test whether lifting idle hands will release the shoulders + translation.y += 0.10f; + } + target.setPose(rotation, translation); target.setIndex(targetVar.jointIndex); targets.push_back(target); if (targetVar.jointIndex > _maxTargetIndex) { @@ -125,6 +131,10 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: } } } + static int adebug = 0; ++adebug; bool verbose = (0 == (adebug % 100)); + if (verbose) { + std::cout << "adebug num targets = " << targets.size() << std::endl; // adebug + } } void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector& targets) { @@ -175,7 +185,8 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorgetAbsolutePose(_headIndex, underPoses).trans; - glm::vec3 over = under; if (target.getType() == IKTarget::Type::RotationOnly) { - over = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans; - } else if (target.getType() == IKTarget::Type::RotationAndPosition) { - over = target.getTranslation(); + // we want to shift the hips to bring the underpose closer + // to where the head happens to be (overpose) + glm::vec3 under = _skeleton->getAbsolutePose(_headIndex, underPoses).trans; + glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans; + const float HEAD_OFFSET_SLAVE_FACTOR = 0.65f; + newHipsOffset += HEAD_OFFSET_SLAVE_FACTOR * (actual - under); + } else if (target.getType() == IKTarget::Type::HmdHead) { + // we want to shift the hips to bring the head to its designated position + glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans; + hmdHipsOffset = _hipsOffset + target.getTranslation() - actual; } - const float HEAD_OFFSET_SLAVE_FACTOR = 0.65f; - newHipsOffset += HEAD_OFFSET_SLAVE_FACTOR * (over - under); } else if (target.getType() == IKTarget::Type::RotationAndPosition) { glm::vec3 actualPosition = _skeleton->getAbsolutePose(targetIndex, _relativePoses).trans; glm::vec3 targetPosition = target.getTranslation(); @@ -392,6 +408,10 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars // smooth transitions by relaxing _hipsOffset toward the new value const float HIPS_OFFSET_SLAVE_TIMESCALE = 0.15f; _hipsOffset += (newHipsOffset - _hipsOffset) * (dt / HIPS_OFFSET_SLAVE_TIMESCALE); + //_hipsOffset *= 0.0f; // adebug + if (glm::length2(hmdHipsOffset) < 100.0f) { + _hipsOffset = hmdHipsOffset; + } } } return _relativePoses; diff --git a/libraries/animation/src/IKTarget.cpp b/libraries/animation/src/IKTarget.cpp index a7e3296d35..b17f186b47 100644 --- a/libraries/animation/src/IKTarget.cpp +++ b/libraries/animation/src/IKTarget.cpp @@ -25,6 +25,9 @@ void IKTarget::setType(int type) { case (int)Type::HmdHead: _type = Type::HmdHead; break; + case (int)Type::HipsRelativeRotationAndPosition: + _type = Type::HipsRelativeRotationAndPosition; + break; default: _type = Type::Unknown; } diff --git a/libraries/animation/src/IKTarget.h b/libraries/animation/src/IKTarget.h index fa920d1511..983eafd9cb 100644 --- a/libraries/animation/src/IKTarget.h +++ b/libraries/animation/src/IKTarget.h @@ -18,6 +18,7 @@ public: RotationAndPosition, RotationOnly, HmdHead, + HipsRelativeRotationAndPosition, Unknown, }; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 3a1dafa10c..340c09060a 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1058,9 +1058,11 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { _animVars.set("headPosition", headPos); _animVars.set("headRotation", headRot); - _animVars.set("headAndNeckType", (int)IKTarget::Type::RotationAndPosition); + _animVars.set("headType", (int)IKTarget::Type::HmdHead); _animVars.set("neckPosition", neckPos); _animVars.set("neckRotation", neckRot); + //_animVars.set("neckType", (int)IKTarget::Type::RotationOnly); + _animVars.set("neckType", (int)IKTarget::Type::Unknown); // 'Unknown' disables the target } else { @@ -1072,8 +1074,10 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { _animVars.unset("headPosition"); _animVars.set("headRotation", realLocalHeadOrientation); _animVars.set("headAndNeckType", (int)IKTarget::Type::RotationOnly); + _animVars.set("headType", (int)IKTarget::Type::RotationOnly); _animVars.unset("neckPosition"); _animVars.unset("neckRotation"); + _animVars.set("neckType", (int)IKTarget::Type::RotationOnly); } } else if (!_enableAnimGraph) { @@ -1131,16 +1135,20 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) { if (params.isLeftEnabled) { _animVars.set("leftHandPosition", rootBindPose.trans + rootBindPose.rot * yFlipHACK * params.leftPosition); _animVars.set("leftHandRotation", rootBindPose.rot * yFlipHACK * params.leftOrientation); + _animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition); } else { _animVars.unset("leftHandPosition"); _animVars.unset("leftHandRotation"); + _animVars.set("leftHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition); } if (params.isRightEnabled) { _animVars.set("rightHandPosition", rootBindPose.trans + rootBindPose.rot * yFlipHACK * params.rightPosition); _animVars.set("rightHandRotation", rootBindPose.rot * yFlipHACK * params.rightOrientation); + _animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition); } else { _animVars.unset("rightHandPosition"); _animVars.unset("rightHandRotation"); + _animVars.set("rightHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition); } // set leftHand grab vars