From 83ec346cc55c59444b5ddc4ea33af052121299d9 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 17 Oct 2018 16:42:29 -0700 Subject: [PATCH 1/6] changed the hand azimuth computation to be in spine2 space. this stops you from having a reversed direction when you sit down with hmd lean off and the hands are behind the origin in the z direction. --- interface/src/avatar/MyAvatar.cpp | 91 +++++++++++++++++++++++-------- interface/src/avatar/MyAvatar.h | 2 +- 2 files changed, 70 insertions(+), 23 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b347963cf1..e7d09b79a2 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -475,16 +475,33 @@ void MyAvatar::update(float deltaTime) { // put the average hand azimuth into sensor space. // then mix it with head facing direction to determine rotation recenter if (getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid()) { - glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); - glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); - glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat); - glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, handHipAzimuthWorldSpace); - glm::vec2 normedHandHipAzimuthSensorSpace(0.0f, 1.0f); - if (glm::length(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)) > 0.0f) { - normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); + int spine2Index = _skeletonModel->getRig().indexOfJoint("Spine2"); + if (!(spine2Index < 0)) { + // use the spine for the azimuth origin. + glm::quat spine2Rot = getAbsoluteJointRotationInObjectFrame(spine2Index); + glm::vec3 handHipAzimuthAvatarSpace = spine2Rot * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); + glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), handHipAzimuthAvatarSpace); + glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); + glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat); + glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, handHipAzimuthWorldSpace); + glm::vec2 normedHandHipAzimuthSensorSpace(0.0f, 1.0f); + if (glm::length(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)) > 0.0f) { + normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); + } + glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH); + _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); + } else { + glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); + glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); + glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat); + glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, handHipAzimuthWorldSpace); + glm::vec2 normedHandHipAzimuthSensorSpace(0.0f, 1.0f); + if (glm::length(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)) > 0.0f) { + normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); + } + glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH); + _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); } - glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH); - _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); } else { _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, _headControllerFacing, tau); } @@ -854,6 +871,20 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { glm::vec2 MyAvatar::computeHandAzimuth() const { controller::Pose leftHandPoseAvatarSpace = getLeftHandPose(); controller::Pose rightHandPoseAvatarSpace = getRightHandPose(); + + int spine2Index = _skeletonModel->getRig().indexOfJoint("Spine2"); + glm::vec3 spine2Position(0.0f,0.0f,0.0f); + glm::quat spine2Rotation(0.0f, 0.0f, 0.0f, 1.0f); + if (!(spine2Index < 0)) { + // use the spine for the azimuth origin. + spine2Position = getAbsoluteJointTranslationInObjectFrame(spine2Index); + glm::quat spine2Rotation = getAbsoluteJointRotationInObjectFrame(spine2Index); + } + glm::vec3 rightHandOffset = rightHandPoseAvatarSpace.translation - spine2Position; + glm::vec3 leftHandOffset = leftHandPoseAvatarSpace.translation - spine2Position; + glm::vec3 rightHandSpine2Space = glm::inverse(spine2Rotation) * rightHandOffset; + glm::vec3 leftHandSpine2Space = glm::inverse(spine2Rotation) * leftHandOffset; + controller::Pose headPoseAvatarSpace = getControllerPoseInAvatarFrame(controller::Action::HEAD); const float HALFWAY = 0.50f; glm::vec2 latestHipToHandController = _hipToHandController; @@ -862,23 +893,25 @@ glm::vec2 MyAvatar::computeHandAzimuth() const { // we need the old azimuth reading to prevent flipping the facing direction 180 // in the case where the hands go from being slightly less than 180 apart to slightly more than 180 apart. glm::vec2 oldAzimuthReading = _hipToHandController; - if ((glm::length(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)) > 0.0f) && (glm::length(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)) > 0.0f)) { - latestHipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), HALFWAY); + if ((glm::length(glm::vec2(rightHandSpine2Space.x, rightHandSpine2Space.z)) > 0.0f) && (glm::length(glm::vec2(leftHandSpine2Space.x, leftHandSpine2Space.z)) > 0.0f)) { + latestHipToHandController = lerp(glm::normalize(glm::vec2(rightHandSpine2Space.x, rightHandSpine2Space.z)), glm::normalize(glm::vec2(leftHandSpine2Space.x, leftHandSpine2Space.z)), HALFWAY); } else { - latestHipToHandController = glm::vec2(0.0f, -1.0f); + latestHipToHandController = glm::vec2(0.0f, 1.0f); } glm::vec3 headLookAtAvatarSpace = transformVectorFast(headPoseAvatarSpace.getMatrix(), glm::vec3(0.0f, 0.0f, 1.0f)); - glm::vec2 headAzimuthAvatarSpace = glm::vec2(headLookAtAvatarSpace.x, headLookAtAvatarSpace.z); - if (glm::length(headAzimuthAvatarSpace) > 0.0f) { - headAzimuthAvatarSpace = glm::normalize(headAzimuthAvatarSpace); + glm::vec3 headLookAtSpine2Space = glm::inverse(spine2Rotation) * headLookAtAvatarSpace; + + glm::vec2 headAzimuthSpine2Space = glm::vec2(headLookAtSpine2Space.x, headLookAtSpine2Space.z); + if (glm::length(headAzimuthSpine2Space) > 0.0f) { + headAzimuthSpine2Space = glm::normalize(headAzimuthSpine2Space); } else { - headAzimuthAvatarSpace = -latestHipToHandController; + headAzimuthSpine2Space = -latestHipToHandController; } // check the angular distance from forward and back float cosForwardAngle = glm::dot(latestHipToHandController, oldAzimuthReading); - float cosHeadShoulder = glm::dot(-latestHipToHandController, headAzimuthAvatarSpace); + float cosHeadShoulder = glm::dot(-latestHipToHandController, headAzimuthSpine2Space); // if we are now closer to the 180 flip of the previous chest forward // then we negate our computed latestHipToHandController to keep the chest from flipping. // also check the head to shoulder azimuth difference if we negate. @@ -3392,19 +3425,33 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { } glm::mat4 MyAvatar::getSpine2RotationRigSpace() const { + int spine2Index = _skeletonModel->getRig().indexOfJoint("Spine2"); + glm::quat spine2Rot = Quaternions::IDENTITY; + if (!(spine2Index < 0)) { + // use the spine for the azimuth origin. + spine2Rot = getAbsoluteJointRotationInObjectFrame(spine2Index); + } + glm::vec3 spine2UpAvatarSpace = spine2Rot * glm::vec3(0.0f, 1.0f, 0.0f); + glm::vec3 spine2FwdAvatarSpace = spine2Rot * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); // static const glm::quat RIG_CHANGE_OF_BASIS = Quaternions::Y_180; // RIG_CHANGE_OF_BASIS * AVATAR_TO_RIG_ROTATION * inverse(RIG_CHANGE_OF_BASIS) = Quaternions::Y_180; //avatar Space; const glm::quat AVATAR_TO_RIG_ROTATION = Quaternions::Y_180; - glm::vec3 hipToHandRigSpace = AVATAR_TO_RIG_ROTATION * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); + glm::vec3 spine2UpRigSpace = AVATAR_TO_RIG_ROTATION * spine2UpAvatarSpace; + glm::vec3 spine2FwdRigSpace = AVATAR_TO_RIG_ROTATION * spine2FwdAvatarSpace; glm::vec3 u, v, w; - if (glm::length(hipToHandRigSpace) > 0.0f) { - hipToHandRigSpace = glm::normalize(hipToHandRigSpace); + if (glm::length(spine2FwdRigSpace) > 0.0f) { + spine2FwdRigSpace = glm::normalize(spine2FwdRigSpace); } else { - hipToHandRigSpace = glm::vec3(0.0f, 0.0f, 1.0f); + spine2FwdRigSpace = glm::vec3(0.0f, 0.0f, 1.0f); } - generateBasisVectors(glm::vec3(0.0f,1.0f,0.0f), hipToHandRigSpace, u, v, w); + if (glm::length(spine2UpRigSpace) > 0.0f) { + spine2UpRigSpace = glm::normalize(spine2UpRigSpace); + } else { + spine2UpRigSpace = glm::vec3(0.0f, 1.0f, 0.0f); + } + generateBasisVectors(spine2UpRigSpace, spine2FwdRigSpace, u, v, w); glm::mat4 spine2RigSpace(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f)); return spine2RigSpace; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 16b765711a..85d6bea018 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1688,7 +1688,7 @@ private: glm::vec2 _headControllerFacingMovingAverage { 0.0f, 0.0f }; // facing vector in xz plane (sensor space) glm::quat _averageHeadRotation { 0.0f, 0.0f, 0.0f, 1.0f }; - glm::vec2 _hipToHandController { 0.0f, -1.0f }; // spine2 facing vector in xz plane (avatar space) + glm::vec2 _hipToHandController { 0.0f, 1.0f }; // spine2 facing vector in xz plane (spine2 space) float _currentStandingHeight { 0.0f }; bool _resetMode { true }; From 8f4fafe4d0480a88d0e19ad4044df32ad69b7433 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 18 Oct 2018 08:44:01 -0700 Subject: [PATCH 2/6] put some smoothing on the spine2 rotation in myskeletonmodel.cpp --- interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/avatar/MySkeletonModel.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e7d09b79a2..a5bb08658d 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -878,7 +878,7 @@ glm::vec2 MyAvatar::computeHandAzimuth() const { if (!(spine2Index < 0)) { // use the spine for the azimuth origin. spine2Position = getAbsoluteJointTranslationInObjectFrame(spine2Index); - glm::quat spine2Rotation = getAbsoluteJointRotationInObjectFrame(spine2Index); + spine2Rotation = getAbsoluteJointRotationInObjectFrame(spine2Index); } glm::vec3 rightHandOffset = rightHandPoseAvatarSpace.translation - spine2Position; glm::vec3 leftHandOffset = leftHandPoseAvatarSpace.translation - spine2Position; diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 3084542472..900d532c88 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -261,7 +261,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } generateBasisVectors(up, fwd, u, v, w); AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); - currentSpine2Pose.rot() = newSpinePose.rot(); + currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), 0.5f); params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; } From 12b03b0e07e3d69d727e44b401cfea953ddcde3f Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 18 Oct 2018 10:52:13 -0700 Subject: [PATCH 3/6] tinkering with lerping the spine2 position in avatar space --- interface/src/avatar/MyAvatar.cpp | 3 ++- interface/src/avatar/MyAvatar.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index a5bb08658d..e8d87d30af 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -877,7 +877,8 @@ glm::vec2 MyAvatar::computeHandAzimuth() const { glm::quat spine2Rotation(0.0f, 0.0f, 0.0f, 1.0f); if (!(spine2Index < 0)) { // use the spine for the azimuth origin. - spine2Position = getAbsoluteJointTranslationInObjectFrame(spine2Index); + spine2Position = getAbsoluteJointTranslationInObjectFrame(spine2Index); + _spine2PositionAvatarSpace = _spine2PositionAvatarSpace + ((0.05f) * (spine2Position - _spine2PositionAvatarSpace)); spine2Rotation = getAbsoluteJointRotationInObjectFrame(spine2Index); } glm::vec3 rightHandOffset = rightHandPoseAvatarSpace.translation - spine2Position; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 85d6bea018..f40f7e3023 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1689,6 +1689,7 @@ private: glm::quat _averageHeadRotation { 0.0f, 0.0f, 0.0f, 1.0f }; glm::vec2 _hipToHandController { 0.0f, 1.0f }; // spine2 facing vector in xz plane (spine2 space) + glm::vec3 _spine2PositionAvatarSpace { 0.0f, 0.0f, 0.0f }; float _currentStandingHeight { 0.0f }; bool _resetMode { true }; From 5063d0b527fc6f7b4d0a0721860ec5be9a78cbb2 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 23 Oct 2018 16:51:56 -0700 Subject: [PATCH 4/6] changed handAzimuth to non const function --- interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/avatar/MyAvatar.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f75f3fbdfc..ac919d4420 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -997,7 +997,7 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { // Find the vector halfway between the hip to hand azimuth vectors // This midpoint hand azimuth is in Avatar space -glm::vec2 MyAvatar::computeHandAzimuth() const { +glm::vec2 MyAvatar::computeHandAzimuth() { controller::Pose leftHandPoseAvatarSpace = getLeftHandPose(); controller::Pose rightHandPoseAvatarSpace = getRightHandPose(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 6783cb8995..1be07a244e 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -337,7 +337,7 @@ public: void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix); // compute the hip to hand average azimuth. - glm::vec2 computeHandAzimuth() const; + glm::vec2 computeHandAzimuth(); // read the location of a hand controller and save the transform void updateJointFromController(controller::Action poseKey, ThreadSafeValueCache& matrixCache); From 370801bd85a2f753453082c7cffb78b21b5756d0 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 24 Oct 2018 16:23:05 -0700 Subject: [PATCH 5/6] removed _spine2position variable and added handling for when there is no spine2 joint. In that case the head will do the recentering rotation and the shoulders will not move with the hand azimuth --- interface/src/avatar/MyAvatar.cpp | 72 ++++++++++-------------- interface/src/avatar/MyAvatar.h | 3 +- interface/src/avatar/MySkeletonModel.cpp | 3 +- 3 files changed, 33 insertions(+), 45 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ac919d4420..e4ff88974a 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -538,33 +538,24 @@ void MyAvatar::update(float deltaTime) { // put the average hand azimuth into sensor space. // then mix it with head facing direction to determine rotation recenter - if (getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid()) { - int spine2Index = _skeletonModel->getRig().indexOfJoint("Spine2"); - if (!(spine2Index < 0)) { - // use the spine for the azimuth origin. - glm::quat spine2Rot = getAbsoluteJointRotationInObjectFrame(spine2Index); - glm::vec3 handHipAzimuthAvatarSpace = spine2Rot * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); - glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), handHipAzimuthAvatarSpace); - glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); - glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat); - glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, handHipAzimuthWorldSpace); - glm::vec2 normedHandHipAzimuthSensorSpace(0.0f, 1.0f); - if (glm::length(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)) > 0.0f) { - normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); - } + int spine2Index = _skeletonModel->getRig().indexOfJoint("Spine2"); + if (getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && !(spine2Index < 0)) { + + // use the spine for the azimuth origin. + glm::quat spine2Rot = getAbsoluteJointRotationInObjectFrame(spine2Index); + glm::vec3 handHipAzimuthAvatarSpace = spine2Rot * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); + glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), handHipAzimuthAvatarSpace); + glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); + glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat); + glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, handHipAzimuthWorldSpace); + glm::vec2 normedHandHipAzimuthSensorSpace(0.0f, 1.0f); + if (glm::length(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)) > 0.0f) { + normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH); _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); } else { - glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); - glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); - glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat); - glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, handHipAzimuthWorldSpace); - glm::vec2 normedHandHipAzimuthSensorSpace(0.0f, 1.0f); - if (glm::length(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)) > 0.0f) { - normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); - } - glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH); - _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); + // use head facing if the chest arms vector is up or down. + _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, _headControllerFacing, tau); } } else { _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, _headControllerFacing, tau); @@ -996,30 +987,27 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { } // Find the vector halfway between the hip to hand azimuth vectors -// This midpoint hand azimuth is in Avatar space -glm::vec2 MyAvatar::computeHandAzimuth() { +// This midpoint hand azimuth is in Spine2 space +glm::vec2 MyAvatar::computeHandAzimuth() const { controller::Pose leftHandPoseAvatarSpace = getLeftHandPose(); controller::Pose rightHandPoseAvatarSpace = getRightHandPose(); - - int spine2Index = _skeletonModel->getRig().indexOfJoint("Spine2"); - glm::vec3 spine2Position(0.0f,0.0f,0.0f); - glm::quat spine2Rotation(0.0f, 0.0f, 0.0f, 1.0f); - if (!(spine2Index < 0)) { - // use the spine for the azimuth origin. - spine2Position = getAbsoluteJointTranslationInObjectFrame(spine2Index); - _spine2PositionAvatarSpace = _spine2PositionAvatarSpace + ((0.05f) * (spine2Position - _spine2PositionAvatarSpace)); - spine2Rotation = getAbsoluteJointRotationInObjectFrame(spine2Index); - } - glm::vec3 rightHandOffset = rightHandPoseAvatarSpace.translation - spine2Position; - glm::vec3 leftHandOffset = leftHandPoseAvatarSpace.translation - spine2Position; - glm::vec3 rightHandSpine2Space = glm::inverse(spine2Rotation) * rightHandOffset; - glm::vec3 leftHandSpine2Space = glm::inverse(spine2Rotation) * leftHandOffset; - controller::Pose headPoseAvatarSpace = getControllerPoseInAvatarFrame(controller::Action::HEAD); const float HALFWAY = 0.50f; + const float SPINE2_POSITION_FILTER = 0.05f; + glm::vec2 latestHipToHandController = _hipToHandController; - if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid() && headPoseAvatarSpace.isValid()) { + int spine2Index = _skeletonModel->getRig().indexOfJoint("Spine2"); + if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid() && headPoseAvatarSpace.isValid() && !(spine2Index < 0)) { + + glm::vec3 spine2Position = getAbsoluteJointTranslationInObjectFrame(spine2Index); + glm::quat spine2Rotation = getAbsoluteJointRotationInObjectFrame(spine2Index); + + glm::vec3 rightHandOffset = rightHandPoseAvatarSpace.translation - spine2Position; + glm::vec3 leftHandOffset = leftHandPoseAvatarSpace.translation - spine2Position; + glm::vec3 rightHandSpine2Space = glm::inverse(spine2Rotation) * rightHandOffset; + glm::vec3 leftHandSpine2Space = glm::inverse(spine2Rotation) * leftHandOffset; + // we need the old azimuth reading to prevent flipping the facing direction 180 // in the case where the hands go from being slightly less than 180 apart to slightly more than 180 apart. glm::vec2 oldAzimuthReading = _hipToHandController; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 1be07a244e..85ad6fe7a4 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -337,7 +337,7 @@ public: void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix); // compute the hip to hand average azimuth. - glm::vec2 computeHandAzimuth(); + glm::vec2 computeHandAzimuth() const; // read the location of a hand controller and save the transform void updateJointFromController(controller::Action poseKey, ThreadSafeValueCache& matrixCache); @@ -1732,7 +1732,6 @@ private: glm::quat _averageHeadRotation { 0.0f, 0.0f, 0.0f, 1.0f }; glm::vec2 _hipToHandController { 0.0f, 1.0f }; // spine2 facing vector in xz plane (spine2 space) - glm::vec3 _spine2PositionAvatarSpace { 0.0f, 0.0f, 0.0f }; float _currentStandingHeight { 0.0f }; bool _resetMode { true }; diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 0cda71ca77..b5a495d296 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -243,6 +243,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { + const float SPINE2_ROTATION_FILTER = 0.5f; AnimPose currentSpine2Pose; AnimPose currentHeadPose; AnimPose currentHipsPose; @@ -262,7 +263,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } generateBasisVectors(up, fwd, u, v, w); AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); - currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), 0.5f); + currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER); params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; } From 7fe53d4399f8a24043b6154c7d7785bc321bf7af Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 24 Oct 2018 16:32:18 -0700 Subject: [PATCH 6/6] removed extra const float value --- interface/src/avatar/MyAvatar.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e4ff88974a..15ddb2fe87 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -993,7 +993,6 @@ glm::vec2 MyAvatar::computeHandAzimuth() const { controller::Pose rightHandPoseAvatarSpace = getRightHandPose(); controller::Pose headPoseAvatarSpace = getControllerPoseInAvatarFrame(controller::Action::HEAD); const float HALFWAY = 0.50f; - const float SPINE2_POSITION_FILTER = 0.05f; glm::vec2 latestHipToHandController = _hipToHandController;